【问题标题】:The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this timeSQL Server 数据库引擎的实例此时无法获取 LOCK 资源
【发布时间】:2015-04-01 10:27:19
【问题描述】:

我有一个大表(7000 万条记录),它也被大量索引(5 个索引),我需要与它合并大约 100000 条记录(连续几次)。所以我做了合并,一些合并是好的,一些返回

SQL Server 数据库引擎的实例此时无法获取 LOCK 资源。当活动用户较少时重新运行您的语句。请数据库管理员检查此实例的锁和内存配置,或检查长时间运行的事务。

合并没有围绕它的事务,并且从实体框架(v 4.0)调用(作为存储过程)也没有任何事务。

using (var b = new MyEntities())
{
    b.CommandTimeout = 36000;
    b.Merge_My_Stuff();
}

服务器还有 16 Gb 的 RAM(大部分由 sql server 占用),该表中的数据为 2.5 Gb,索引为 7 Gb。 我检查了内存限制,它们是

max server memory (MB)  2147483647  2147483647  Maximum size of server memory (MB)
min server memory (MB)  0   16  Minimum size of server memory (MB)

任何建议将不胜感激。还有为什么 sql server 需要这么多锁来进行合并?

编辑 合并语句是(执行计划我稍后会添加)

merge Target_table as target
using (select * from I_Tmp) as source
on target.A_ID = source.A_ID and
   target.B_ID = source.B_ID and
   isnull(target.C_ID, 0) = isnull(source.C_ID, 0)
when not matched by target then
    insert(A_ID, B_ID, C_ID, D, E)
    values(source.A_ID, source.B_ID, source.C_ID, D, E)
when matched then
    update
    set D= source.D,
        E= source.E;

delete from I_Tmp

【问题讨论】:

  • 请添加实际的合并语句,最好是它的执行计划
  • 尝试做多个小批量,而不是一次 100K。
  • 我们来做一个实验。将WITH(TABLOCKX) 应用于该语句中涉及的所有表。错误应该消失了。这说明这个语句生成的锁的数量是问题,和我怀疑的一样。
  • technet.microsoft.com/en-us/library/ms184286(v=sql.105).aspx 浏览锁升级的场景和要求列表。有什么可以阻止它的吗?由于某种原因,查询似乎每行目标占用一个锁。 100k 锁不算什么。该错误可能来自尝试使用 70m 锁。
  • P.S.您对 IsNull() 的使用会停止使用这些列上的任何索引的优化器。

标签: sql-server


【解决方案1】:

看起来像锁定超时错误。可能与服务器内存无关,而是与其他线程争用造成的。

以下几点可能会有所帮助:

  1. 确保存在以所有合并条件(A_ID、B_ID、C_ID)作为键的索引(如果您的聚集索引将这些作为键,则更好)
  2. 显着减少批量大小

如果您无法减小批量大小,请考虑在 MERGE 语句中使用 TABLOCK/TABLOCKX 提示。由于大批量大小,SQL 无论如何都可能将您的锁升级为表锁,这会增加事务时间。直接进入表锁应该可以减少超时。

【讨论】:

    【解决方案2】:

    安装 CU15 后,我在 sql server 2016 上发生了这种情况。 Instance Properties > Advanced > Locks ...我在 MAXDOP 部分找到了新功能。 默认是 50000,我尝试设置为 0,但点击 OK 后无法应用。

    后来:我找到了解决方法:

    exec sp_configure 'show advanced options', 1;
    reconfigure;
    exec sp_configure 'Locks', 0;
    reconfigure;
    

    【讨论】:

    • 肯定是因为一些并发线程在表的范围内做某事...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多