禁用超时后,SqlBulkCopy到Azure的超时

时间:2019-02-04 13:27:31

标签: c# azure .net-core azure-sql-database sqlbulkcopy

我正在尝试使用.NET Core中的SqlBulkCopy将数百万行插入到开发实例Azure SQL数据库中。

我已禁用了连接字符串超时和BulkCopyTimeout(将它们都设置为0),但是我仍在超时。

现在这不是一台高端计算机(它是一个开发环境),并且此过程非常容易使DTU最大化……但是我对DTU max应该如何工作的理解是,这是一种节流机制,而不是中止机制。有了无限的超时,我希望该过程需要一段时间,但最终会完成。相反,我看到的是过程开始...上传一堆行...然后在奇怪的时间超时:2:38,4:20 ...没有韵律或原因。

这使我认为这是某种传输错误,但是我显然收到了TimeoutException。

根据Bulk insert is not working properly in Azure SQL Server中的建议,我也尝试使批次也很小,但这似乎也无济于事。

任何人都可以解释这里发生的事情以及如何解决吗?这阻碍了一个高可视项目的开发,我不想告诉人们我可以让它在笔记本电脑的SQL Server Express上运行,而不能在Azure DB上运行。

3 个答案:

答案 0 :(得分:1)

请运行以下查询,让我们尝试查找有关Azure SQL数据库受到限制的证据。

SELECT *
FROM sys.dm_db_resource_stats
ORDER BY end_time DESC;

如果您看到avg_log_write_percent接近或等于100%,则表示正在进行限制,因此您需要扩大数据库层。非高级层不适用于I / O密集型工作负载,建议进行批处理。

在Azure SQL数据库上进行限制时,您不仅会看到响应时间很慢,而且还会开始看到尝试连接失败和超时的失败。

select * 
from sys.event_log 
where event_type <> 'connection_successful' and
start_time >= CAST(FLOOR(CAST(getdate() AS float)) AS DATETIME)
order by start_time desc

select *
from sys.database_connection_stats_ex
where start_time >= CAST(FLOOR(CAST(getdate() AS float)) AS DATETIME)
order by start_time desc

答案 1 :(得分:1)

我只是试图复制而不能。取消之前,SqlBulkCopy运行了30分钟以上。

从Azure外部针对低DTU的Azure SQL数据库尝试此操作:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static void Main(string[] args)
    {
        var constr = "Server=tcp:xxxxxx.database.windows.net,1433;Initial Catalog=xxxxxx;User ID=xxxxxx;Password=xxxxxx";


        using (var con = new SqlConnection(constr))
        {
            con.Open();

            var cmd = con.CreateCommand();
            cmd.CommandText = "create table #test(id int, data varbinary(max))";
            cmd.ExecuteNonQuery();

            var bc = new SqlBulkCopy(con);
            bc.DestinationTableName = "#test";
            bc.BulkCopyTimeout = 0;

            var dt = new DataTable();
            dt.Columns.Add("id", typeof(int));
            dt.Columns.Add("data", typeof(byte[]));
            var buf = Enumerable.Range(1, 1000 * 1000).Select(i => (byte)(i % 256)).ToArray();
            dt.BeginLoadData();
            for (int i = 0; i < 1000*1000*10; i++)
            {
                var r = dt.NewRow();
                r[0] = 1;
                r[1] = buf;
                dt.Rows.Add(r);
            }
            dt.EndLoadData();

            foreach (DataColumn col in dt.Columns)
            {
                bc.ColumnMappings.Add(col.ColumnName, col.ColumnName);
            }

            bc.NotifyAfter = 100;
            bc.SqlRowsCopied += (s, a) =>
            {
                Console.WriteLine($"{a.RowsCopied} rows copied");
            };


            Console.WriteLine($"Starting {DateTime.Now}");
            bc.WriteToServer(dt);
            Console.WriteLine($"Finished {DateTime.Now}");

        }
        Console.WriteLine("done");
    }


}

答案 2 :(得分:0)

两个答案都很好,但是看来我的问题与代码无关。有一些“毛刺出现在矩阵中”似乎正在引起我所看到的症状,经过一定时间后,我不再能够重现它们。