AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 274690
Accepted
Arun Gopinath
Arun Gopinath
Asked: 2020-09-01 01:48:20 +0800 CST2020-09-01 01:48:20 +0800 CST 2020-09-01 01:48:20 +0800 CST

lock_acquired 扩展事件中的锁升级和计数差异

  • 772

我试图理解为什么在某些情况下锁定计数sys.dm_tran_locks和扩展事件存在差异。sqlserver.lock_acquired这是我的复制脚本,我StackOverflow2013在 SQL Server 2019 RTM 上使用数据库,兼容级别 150。

/* Initial Setup */
IF OBJECT_ID('dbo.HighQuestionScores', 'U') IS NOT NULL 
DROP TABLE dbo.HighQuestionScores; 

CREATE TABLE dbo.HighQuestionScores 
(
    Id INT PRIMARY KEY CLUSTERED,
    DisplayName NVARCHAR(40) NOT NULL,
    Reputation BIGINT NOT NULL,
    Score BIGINT
)

INSERT dbo.HighQuestionScores  
        (Id, DisplayName, Reputation, Score)
SELECT u.Id, 
       u.DisplayName,
       u.Reputation, 
       NULL
FROM dbo.Users AS u;

CREATE INDEX ix_HighQuestionScores_Reputation ON dbo.HighQuestionScores  (Reputation);

接下来,我使用大量假行数更新表统计信息

/* Chaotic Evil. */
UPDATE STATISTICS dbo.HighQuestionScores WITH ROWCOUNT = 99999999999999;
DBCC FREEPROCCACHE WITH NO_INFOMSGS;

然后我打开一个事务并更新Score声誉,比如说56

BEGIN TRAN;
UPDATE dbo.HighQuestionScores  
SET Score = 1
WHERE Reputation = 56 /* 8066 records */
AND 1 = (SELECT 1);
/* Source: https://www.erikdarlingdata.com/sql-server/helpers-views-and-functions-i-use-in-presentations/ Thanks, Erik */
SELECT *
FROM dbo.WhatsUpLocks(@@SPID) AS wul 
WHERE wul.locked_object = N'HighQuestionScores'
ROLLBACK;

我得到了一堆页面锁(尽管有一个关于声誉的索引)。我猜糟糕的估计确实在那里的优化器上做了一个数字。

page_locks

我还仔细检查了使用sp_whoisactive,它也返回了相同的信息。

<Object name="HighQuestionScores" schema_name="dbo">
  <Locks>
    <Lock resource_type="OBJECT" request_mode="IX" request_status="GRANT" request_count="1" />
    <Lock resource_type="PAGE" page_type="*" index_name="PK__HighQues__3214EC072EE1ADBA" request_mode="X" request_status="GRANT" request_count="6159" />
  </Locks>
</Object>

同时,我还有一个sqlserver.lock_acquired单独的扩展活动。当我查看分组数据时,我看到8066页锁而不是初始6159

扩展事件锁定计数

我绝对看不到锁升级(使用sqlserver.lock_escalation事件验证),所以我想我的问题是为什么扩展事件显示与更高数量的锁计数存在差异?

sql-server locking
  • 1 1 个回答
  • 347 Views

1 个回答

  • Voted
  1. Best Answer
    Josh Darnell
    2020-09-01T03:44:30+08:002020-09-01T03:44:30+08:00

    XE 报告每次更新行时获取页锁(受更新影响的 8066 行中的每一行都有一个事件)。但是,这些行仅存储在 6159 个唯一页面上,这解释了差异。

    我在这台机器上没有 StackOverflow2013,但使用 SO2010 获得了类似的体验:

    • 更新了 1368 行(并且触发了许多 XEvent)
    • 958页锁

    如果您按以下方式排序,则可以在 XE 输出中看到相同的页面被重复锁定resource_0:

    SSMS 中 XE 输出的屏幕截图

    使用DBCC PAGE:

    DBCC TRACEON (3604); -- needed for the next one to work
    GO
    
    DBCC PAGE (StackOverflow2010, 1, 180020, 3);
    GO
    

    我可以看到页面 180020 上有 163 条记录(m_slotCnt = 163):

    Page @0x000002C278C62000
    
    m_pageId = (1:180020)               m_headerVersion = 1                 m_type = 1
    m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x0
    m_objId (AllocUnitId.idObj) = 174   m_indexId (AllocUnitId.idInd) = 256 
    Metadata: AllocUnitId = 72057594049331200                                
    Metadata: PartitionId = 72057594044350464                                Metadata: IndexId = 1
    Metadata: ObjectId = 1525580473     m_prevPage = (1:180019)             m_nextPage = (1:180021)
    pminlen = 24                        m_slotCnt = 163                     m_freeCnt = 31
    m_freeData = 7835                   m_reservedCnt = 0                   m_lsn = (203:19986:617)
    m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
    m_tornBits = 1894114769             DB Frag ID = 1                
    

    其中 3 个符合更新条件(我将输出粘贴到 notepad++ 并搜索“Reputation = 56”):

    显示 3 个数学的屏幕截图

    这是第一场比赛,例如:

    Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
    Record Size = 39                    
    Memory Dump @0x000000EDB2B7821D
    
    0000000000000000:   30001800 86540000 38000000 00000000 6041c2e4  0...T..8.......`AÂä
    0000000000000014:   c3020000 04000801 00270045 00720069 006300    Ã........'.E.r.i.c.
    
    Slot 9 Column 1 Offset 0x4 Length 4 Length (physical) 4
    
    Id = 21638                          
    
    Slot 9 Column 2 Offset 0x1f Length 8 Length (physical) 8
    
    DisplayName = Eric                  
    
    Slot 9 Column 3 Offset 0x8 Length 8 Length (physical) 8
    
    Reputation = 56                     
    
    Slot 9 Column 4 Offset 0x0 Length 0 Length (physical) 0
    
    Score = [NULL]                      
    
    Slot 9 Offset 0x0 Length 0 Length (physical) 0
    
    KeyHashValue = (e1caffa60313)       
    Slot 10 Offset 0x244 Length 43
    

    我相信这种行为是由于执行计划的流水线性质,以及这种特定 XE 的实现方式。

    • 6

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve