如何复制 SCH_S、SCH_M 死锁

2023-11-29

我有一个大型迁移脚本(大约 2000 行),由于某些元数据上的死锁而失败,根据我在其上捕获的一些 xEvents 数据,锁定类型为 SCH_S 和 SCH_M。该脚本非常复杂,因此我尝试使用最少的脚本重新创建相同的场景,以便我可以进一步研究它。我的场景与我在网上找到的一些场景之间的一个区别是,我的迁移脚本是在单个进程中执行的,而不是使用一个窗口进行一些架构更改并使用另一个窗口进行查询的许多在线示例。

以下脚本有点混乱,但我尝试重现该问题,但它不起作用。

SET NOEXEC OFF;
DROP FUNCTION IF EXISTS dbo.testfunc;
DROP TABLE IF EXISTS dbo.test;

-- Create some objects.
BEGIN TRANSACTION;
CREATE TABLE test
(
    testid INT
);
GO
IF @@error <> 0
   AND @@trancount > 0
    SET NOEXEC ON;
GO
CREATE FUNCTION testfunc
()
RETURNS INT
WITH SCHEMABINDING
AS
BEGIN
    RETURN
    (
        SELECT 2 * SUM(testid) FROM dbo.test
    );
END;
GO
IF @@error <> 0
   AND @@trancount > 0
    SET NOEXEC ON;
GO
IF @@error <> 0
   AND @@trancount > 0
    ROLLBACK TRANSACTION;
ELSE IF @@trancount > 0
    COMMIT TRANSACTION;

GO

-- Try to induce a SCH_S x SCH_M deadlock.
BEGIN TRANSACTION;
GO
IF @@error <> 0
   AND @@trancount > 0
    SET NOEXEC ON;
GO
ALTER FUNCTION dbo.testfunc
()
RETURNS INT
AS
BEGIN
    RETURN
    (
        SELECT 2 * SUM(testid) FROM dbo.test
    );
END;
GO
EXECUTE sp_lock
IF @@error <> 0
   AND @@trancount > 0
    ROLLBACK TRANSACTION;
GO
ALTER TABLE dbo.test ADD teststring VARCHAR(12) NULL;
GO
IF @@error <> 0
   AND @@trancount > 0
    SET NOEXEC ON;
GO
SELECT TOP (1)
       testid
FROM test;
GO
EXECUTE sp_lock
go
ALTER FUNCTION testfunc
()
RETURNS INT
WITH SCHEMABINDING
AS
BEGIN
    RETURN
    (
        SELECT TOP 1 testid FROM dbo.test ORDER BY testid DESC
    );
END;
GO
EXECUTE sp_lock
IF @@error <> 0
   AND @@trancount > 0
    SET NOEXEC ON;
GO
ALTER TABLE dbo.test ADD test_bit BIT NULL;
GO
EXECUTE sp_lock
IF @@error <> 0
   AND @@trancount > 0
    ROLLBACK TRANSACTION;
ELSE IF @@trancount > 0
    COMMIT TRANSACTION;
GO

有人可以帮助我在单个进程中重新创建这种场景吗?

这是死锁 xml 报告:

<deadlock>
 <victim-list>
  <victimProcess id="process1fbf61b8ca8" />
 </victim-list>
 <process-list>
  <process id="process1fbf61b8ca8" taskpriority="0" logused="0" waitresource="METADATA: database_id = 5 USER_TYPE(user_type_id = 264), lockPartitionId = 11" waittime="2517" ownerId="46927562" transactionname="@OptionIDs" lasttranstarted="2020-01-16T13:03:44.790" XDES="0x1fb0b790490" lockMode="Sch-S" schedulerid="12" kpid="20032" status="suspended" spid="63" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2020-01-16T13:03:44.787" lastbatchcompleted="2020-01-16T13:03:44.783" lastattention="1900-01-01T00:00:00.783" clientapp="Microsoft SQL Server Management Studio - Query" hostname="userhost" hostpid="11492" loginname="CORP\user" isolationlevel="serializable (4)" xactid="46926609" currentdb="5" lockTimeout="4294967295" clientoption1="671287392" clientoption2="390200">
   <executionStack>
    <frame procname="unknown" line="39" stmtstart="-1" sqlhandle="0x0300050048c3ee382a43d70044ab000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="adhoc" line="66" stmtstart="-1" sqlhandle="0x010005009a7e7609c0be4a35fb01000000000000000000000000000000000000000000000000000000000000">
CREATE FUNCTION [dbo].[tvf_GetRawPOLineDataRelatedToOption]
(
    @CommunityID INT,
    @FloorPlanID INT,
    @OptionID INT,
    @RelatedIncludedOptionIDToRemove INT
)
RETURNS @ReturnData TABLE
(
    [POTemplateID] INT NOT NULL,
    [POTemplateItemID] INT NOT NULL,
    [POTemplateItemQuantityTypeID] INT NOT NULL,
    [Quantity] DECIMAL(12, 5) NULL,
    [FloorPlanQuantityTypeID] INT NULL,
    [DynamicQuantityPercentage] INT NULL,
    [QuantityForFlooringMaterialTypeID] INT NULL,
    [HomesiteQuantityTypeID] INT NULL
)
WITH SCHEMABINDING
AS
BEGIN
    DECLARE @DependencyData dbo.DependencyDataKeyValueTable;
    DECLARE @POTemplateDependencyFilterData dbo.DependencyFilterKeyValueTable;
    DECLARE @POTemplateItemDependencyFilterData dbo.DependencyFilterKeyValueTable;
    DECLARE @POTemplateIDs dbo.IndexedIntTable;

    /*
     *  Get the default dependency data for this floor plan in this community.
     */
    INSERT INTO @DependencyData
    SELECT [Key],
           [Value]
    FROM dbo.    </frame>
   </executionStack>
   <inputbuf>
CREATE FUNCTION [dbo].[tvf_GetRawPOLineDataRelatedToOption]
(
    @CommunityID INT,
    @FloorPlanID INT,
    @OptionID INT,
    @RelatedIncludedOptionIDToRemove INT
)
RETURNS @ReturnData TABLE
(
    [POTemplateID] INT NOT NULL,
    [POTemplateItemID] INT NOT NULL,
    [POTemplateItemQuantityTypeID] INT NOT NULL,
    [Quantity] DECIMAL(12, 5) NULL,
    [FloorPlanQuantityTypeID] INT NULL,
    [DynamicQuantityPercentage] INT NULL,
    [QuantityForFlooringMaterialTypeID] INT NULL,
    [HomesiteQuantityTypeID] INT NULL
)
WITH SCHEMABINDING
AS
BEGIN
    DECLARE @DependencyData dbo.DependencyDataKeyValueTable;
    DECLARE @POTemplateDependencyFilterData dbo.DependencyFilterKeyValueTable;
    DECLARE @POTemplateItemDependencyFilterData dbo.DependencyFilterKeyValueTable;
    DECLARE @POTemplateIDs dbo.IndexedIntTable;

    /*
     *  Get the default dependency data for this floor plan in this community.
     */
    INSERT INTO @DependencyData
    SELECT [Key],
           [Value]
    FROM dbo   </inputbuf>
  </process>
 </process-list>
 <resource-list>
  <metadatalock subresource="USER_TYPE" classid="user_type_id = 264" dbid="5" lockPartition="11" id="lock1fb8a56df00" mode="Sch-M">
   <owner-list>
    <owner id="process1fbf61b8ca8" mode="Sch-M" />
    <owner id="process1fbf61b8ca8" mode="Sch-S" requestType="wait" />
   </owner-list>
   <waiter-list>
    <waiter id="process1fbf61b8ca8" mode="Sch-S" requestType="wait" />
   </waiter-list>
  </metadatalock>
 </resource-list>
</deadlock>

deadlockgraph


有人可以帮助我在单个进程中重新创建这种场景吗?

这个问题有一个简单的演示here.

BEGIN TRAN

go

CREATE TYPE dbo.OptionIDs AS TABLE( OptionID INT PRIMARY KEY )

go

DECLARE @OptionIDs dbo.OptionIDs;

go

ROLLBACK 

涉及单个进程和单个资源的死锁当然是不寻常的。

资源是metadatalock subresource="USER_TYPE" classid="user_type_id = 264"

本届会议已经召开SCH-M用户定义类型上的元数据锁定(可能是您在脚本前面创建的),这会阻止尝试获取SCH-S稍后由同一个会话锁定同一个对象。

死锁图中显示的事务名称是@OptionIDs- 这是一internal写入的系统事务tempdb创建对应表类型实例时的事务日志DECLARE @OptionIDs多于。这是与周围用户事务分开的事务,这就是会话意外无法获取SCH-S尽管已经持有锁SCH-M lock.

这是 Aaron Bertrand 的博客here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何复制 SCH_S、SCH_M 死锁 的相关文章

  • SQL Server 2008 R2 的 Try_Convert

    我正在使用 SQL Server 2008 R2 并且有一个VARCHAR我想要转换为的列DECIMAL 28 10 using CONVERT 但其中许多行的格式错误 因此无法将它们解析为数字 在这种情况下 我只想通过将结果设置为 0 或
  • Visual Studio SSDT Data Compare如何比较单个数据库中的两个表

    尝试在 SSDT 中做一些简单的数据比较 但事实证明有点困难 在一个数据库中 我有两个要比较的表 这些表具有相同的架构 只是表名不同 我只是想看看这个工具是否能给我一个很好的方法来比较两者的数据 I e tblOutput tblOutpu
  • Id 或 [TableName]Id 作为主键/实体标识符

    是否首选使用 Id 作为主键的列名或 TableName Id 作为命名约定 表 账户主键 ID 相对 表 账户主键 AccountId 在我见过的实现中 它似乎分为 50 50 左右 每种方法的优点和缺点是什么 跟进 在我的数据库中使用一
  • Sql Server:如何在 WHERE 子句中使用 MAX 等聚合函数

    我想获得该记录的最大值 请帮我 SELECT rest field1 FROM mastertable AS m INNER JOIN SELECT t1 field1 field1 t2 field2 FROM table1 AS T1
  • 如何授予所有表的 REFERENCES 权限

    我必须授予REFERENCES登录权限说sql login 我可以给予资助REFERENCES对单个表的权限 例如 GRANT REFERENCES ON Mytable TO sql login 有什么办法可以授予REFERENCES允许
  • 如何跟踪用户在 X 天内每天访问该网站?

    Stack Overflow 上有一个新徽章 这 woot https stackoverflow com badges 71 woot enthusiast 徽章将授予连续 30 天内每天访问该网站的用户 如何实现这样的功能 如何以最简单
  • 获取家庭成员

    假设以下家庭 其构建架构是 create table PersonConn child int parent int insert into PersonConn values 1 2 insert into PersonConn valu
  • SQL Server 用分隔符分割字符串

    我有一个输入字符串 100 2 3 101 2 1 103 2 3 我想解析它并将其添加到具有 3 列的表中 因此它应该是 f x col1 col2 col3 100 2 3 类似的其他数据以逗号分隔作为记录和 作为列 Thanks ni
  • 在 SQL Server 中处理日期

    我正在开发一个 ASP NET 网站 我从网页获取日期 然后根据用户输入我想从 SQL Server 数据库获取结果 使用存储过程 问题是我只能从用户界面获取这种格式的日期2016 10 08这是字符串类型 但在数据库中 我有一个类型为da
  • SQL 删除表并重新创建并保留数据

    在我们最初的设计中 我们搞砸了表中的外键约束 现在表已充满数据 我们无法在不删除表中所有记录的情况下更改它 我能想到的唯一解决方案是创建一个备份表并将所有记录放在那里 然后删除所有记录 更改表并开始将它们添加回来 还有其他 更好 的想法吗
  • 列中差异的数量

    我想检索一列每行中有多少个字母的差异 例如 如果您有一个值 test 而另一行有一个值 testing 则 test 和 testing 之间的差异为 4 个字母 该列的数据值为 4 I have reflected about it an
  • 了解 SSMS 2008 中关系的更新和删除规则

    当我们定义外键约束时 我对 SQL Server 2008 Management Studio 中的更新和删除规则的含义感到困惑 我也没有找到相关的帮助文档 例如F1帮助 这是屏幕快照 如果有人能描述它们的含义并推荐一些相关文档来阅读 我将
  • Spark.read 在 Databricks 中给出 KrbException

    我正在尝试从 databricks 笔记本连接到 SQL 数据库 以下是我的代码 jdbcDF spark read format com microsoft sqlserver jdbc spark option url jdbc sql
  • 探查器模板可以迁移到较新版本的 SQL Profiler 吗?

    是否可以将 Profiler 模板迁移到较新版本的 SQL Server 就我而言 我想将 SQL 2008 模板带到 2012 年 我尝试过 1 直接文件复制和 2 导出 导入 在这两种情况下 旧模板都会运行 但无法修改 修改后会出现以下
  • 重命名重复行

    这是我的问题的一个简化示例 我有一个表 其中有一个包含重复条目的 名称 列 ID Name 1 AAA 2 AAA 3 AAA 4 BBB 5 CCC 6 CCC 7 DDD 8 DDD 9 DDD 10 DDD 进行 GROUP BY 操
  • 单独的逗号分隔值并存储在sql server的表中

    我有一个存储过程 它将逗号分隔的值作为输入 我需要将其分开并需要将其作为单独的行存储在表中 令 SP 的输入为 Rule ID ListType ID Values 1 2 319 400 521 8465 2013 我需要将它存储在一个名
  • “RDBMS”附近的语法不正确。当我尝试创建外部数据源时,有人遇到同样的问题吗?

    我使用的是sql server 2017 CREATE EXTERNAL DATA SOURCE MyElasticDBQueryDataSrc WITH TYPE RDBMS LOCATION
  • 如何在NiFi中映射流文件中的列数据?

    我有 csv 文件 其结构如下 Alfreds Centro Ernst Island Bacchus Germany Mexico Austria UK Canada 01 02 03 04 05 现在我必须将这些数据移入数据库 如下所示
  • 可以获取SQL Server中当前执行的存储过程的行号吗?

    几年前 我在 Sybase Delphi 环境中工作 使用 BDE 连接到数据库服务器 我们有一个 Delphi 小应用程序 给定当前正在执行的存储过程的名称 它可以告诉您当前正在执行该存储过程的哪一行 这对于调试似乎挂起的存储过程非常有用
  • 一列作为主键或两个外键作为主键

    我有以下数据库设计 An E Report有一个QAP其中有一些Requirements A QAP和它的Requirements 可以用于多个E Report Every Requirement每份电子报告中都会有 是 否 确认 我已经添

随机推荐