我有一个 SSIS 包,它正在截断然后将整个表从 serverA 插入到 serverB,但是我试图通过在 serverB 上执行带有 NOLOCK 提示的选择来查看作业的进度,但它被“BULK INSERT”锁定由 SSIS 包执行。
我查看了“sys.dm_tran_locks”,发现“BULK INSERT”在表上持有“Sch-M”锁,我不明白为什么。
请问你能帮我解决这个问题吗?
谢谢。
我有一个 SSIS 包,它正在截断然后将整个表从 serverA 插入到 serverB,但是我试图通过在 serverB 上执行带有 NOLOCK 提示的选择来查看作业的进度,但它被“BULK INSERT”锁定由 SSIS 包执行。
我查看了“sys.dm_tran_locks”,发现“BULK INSERT”在表上持有“Sch-M”锁,我不明白为什么。
请问你能帮我解决这个问题吗?
谢谢。
Sch-M 锁表示您在目标表上至少有一个索引。
请参阅“批量导入期间的表锁定和记录”:
http://msdn.microsoft.com/en-us/library/ms177445%28v=sql.105%29.aspx
根据参考中的表格,当您批量插入时将使用 Sch-M:
此外,如果加载正确完成,截断将在批量插入开始之前完成(并且它的 Sch-M 锁消失了)。
批量更新 (BU) 锁是最优化的锁,但不要指望在批量插入期间读取表:
批量更新 (BU) 锁允许进程将数据同时批量复制到同一个表中,同时阻止未批量复制数据的其他进程访问该表。 http://msdn.microsoft.com/en-us/library/aa213039%28v=sql.80%29.aspx
使用 Remus 建议 (sys.allocation_units) 检查进度。
截断需要 SCH-M 来解除分配表分配单元。除此之外,这个锁的目的是防止并发脏读。如果在脏读扫描器在其中时截断成功地解除分配表,这些扫描器会突然发现自己正在读取不属于任何人的页面(或者更糟糕的是,被重新分配给其他某个 AU)。与任何写锁一样,2PL 协议需要保持到事务结束。随后的脏扫描仪将按其应有的方式阻挡它。
如果您没有将 TRUNCATE/BULK INSERT 包装在事务中,那么还有其他情况可能导致 BULK INSERT 本身进入 SCH-M 而不是 X(我认为在空表上批量插入的表锁定提示(没有 AU 根页)将导致此)。
太偷看 BULK INSERT 的进度,检查在sys.allocation_units
. 这将为您提供完成百分比的粗略估计。