代码之家  ›  专栏  ›  技术社区  ›  Jeremy Holovacs

禁用超时时SqlBulkCopy到azure的超时

  •  2
  • Jeremy Holovacs  · 技术社区  · 5 年前

    我正在尝试在.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 ,我也尝试过将批处理得非常小,但这似乎也没有任何作用。

    有人能解释一下这里发生了什么事,怎么解决吗?这阻碍了high-vis项目的开发,我不想告诉人们我可以让它在我笔记本电脑的sql server express上运行,但不能在azure数据库上运行。

    2 回复  |  直到 5 年前
        1
  •  1
  •   Alberto Morillo    5 年前

    请运行以下查询,让我们尝试查找有关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
    
        2
  •  1
  •   David Browne - Microsoft    5 年前

    我只是想重新编程,但没成功。在取消之前,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");
        }
    
    
    }
    
        3
  •  0
  •   Jeremy Holovacs    5 年前

    这两个答案都很好,但似乎我的问题不是代码相关的。有一些“毛病在基质”似乎是造成的症状,我看到的,并在某一点上,我已不再能够重现它们。