【问题标题】:SqlBulkCopy to Azure Timing out when Timeouts are disabled禁用超时时 SqlBulkCopy 到 Azure 超时
【发布时间】:2019-02-04 13:27:30
【问题描述】:

我正在尝试使用 .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 上运行。

【问题讨论】:

  • 默认超时时间为 30 秒。不要归零。大于 30 秒。
  • 我会,最终......现在,我只是试图定位问题。当它不应该超时时,我正在为超时而挠头。
  • 我不确定设置为零是否真的会使超时无限。为什么不尝试一个非常大的超时时间,看看它是否有效。
  • #%$#^%# 我突然不能再重现这个了。这个问题自上​​周四以来就存在,现在它只是......工作。没有代码更改。叹。我想知道我们的 SAP 实例中是否有问题。
  • 这是一只黑森虫。我通过查看为您修复了它!

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


【解决方案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

【讨论】:

    【解决方案2】:

    我只是尝试复制但不能。 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");
        }
    
    
    }
    

    【讨论】:

    • 是的,大约 15 分钟前它突然开始工作,所以我也无法重现它。
    【解决方案3】:

    两个答案都很好,但似乎我的问题与代码无关。似乎有一些“矩阵故障”导致了我所看到的症状,并且在某个点之后我不再能够重现它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      • 2015-02-07
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      • 1970-01-01
      • 2017-12-07
      相关资源
      最近更新 更多