设为首页 收藏本站
查看: 1604|回复: 0

[经验分享] SQL Server中如何定位Row Lock锁定哪一行数据

[复制链接]

尚未签到

发表于 2017-12-13 18:06:23 | 显示全部楼层 |阅读模式
在SQL Server中有时候会使用提示(Hint)强制SQL使用行锁(Row Lock),前两天有个同事咨询了一个问题,如何定位Row Lock具体锁定了哪一行。其实这个问题只适合研究一下,实际意义并不大,因为找到、定位被锁定的行的代价开销较大,而意义却不怎么大,而且使用场景也很少。那么下面我们来探讨、研究一下这个问题吧:



在会话窗口(会话ID=65)下执行下面SQL语句,模拟SQL Server使用行锁锁定某一行记录:


USE AdventureWorks2012;GO SELECT  @@SPID; BEGIN TRAN;UPDATE  [dbo].[DatabaseLog] WITH ( ROWLOCK )SET     TSQL = N'dddd'WHERE   DatabaseLogID = 1;--ROLLBACK;



在另外一个会话窗口使用下面SQL查询,我们能看到相关锁的一些信息,如下所示,但是这些信息还不够详细,我们还需要更详细的信息:


SELECT Db_name(RSC_DBID)                AS 'DATABASE_NAME',        CASE RSC_TYPE          WHEN 1 THEN 'null'          WHEN 2 THEN 'DATABASE'          WHEN 3 THEN 'FILE'          WHEN 4 THEN 'INDEX'          WHEN 5 THEN 'TABLE'          WHEN 6 THEN 'PAGE'          WHEN 7 THEN 'KEY'          WHEN 8 THEN 'EXTEND'          WHEN 9 THEN 'RID ( ROW>         WHEN 10 THEN 'APPLICATION'        END                              AS 'REQUEST_TYPE',        CASE REQ_OWNERTYPE          WHEN 1 THEN 'TRANSACTION'          WHEN 2 THEN 'CURSOR'          WHEN 3 THEN 'SESSION'          WHEN 4 THEN 'ExSESSION'        END                              AS 'REQUEST_OWNERTYPE',        Object_name(RSC_OBJID, RSC_DBID) AS 'OBJECT_NAME',        PROCESS.HOSTNAME,        PROCESS.NT_DOMAIN,        PROCESS.NT_USERNAME,        PROCESS.PROGRAM_NAME,        SQLTEXT.TEXT FROM   sys.syslockinfo LOCK        JOIN sys.sysprocesses PROCESS          ON LOCK.REQ_SPID = PROCESS.SPID        CROSS apply sys.DM_EXEC_SQL_TEXT(PROCESS.SQL_HANDLE) SQLTEXT WHERE  PROCESS.SPID = 65


DSC0000.png



查询sys.dm_tran_locks我们可以得到更详细的信息,例如,从resource_description中我们可以得到file_id=1, 页面编号为273,这个页面的第一条记录(0)



SELECT  resource_type ,

        resource_database_id , --数据库id

        resource_description , --资源描述

        resource_associated_entity_id , --资源关联实体id

        request_mode , --请求模式

        request_type , --请求类型

        request_status ,

        request_session_id , --请求会话id

        request_owner_type

FROM    sys.dm_tran_locks

WHERE   request_session_id = 65;




DSC0001.png


准备下面脚本,为了后续我们定位到行锁锁定哪一行记录。准备好后面脚本后,我们就可以开始测试了。注意,需要开启跟踪DBCC TRACEON(3604)。否则DBCC PAGE没有任何输出信息



IF EXISTS (SELECT * FROM sys.objects WHERE type='U' AND name='DBCC_PAGE_RESULT')    DROP TABLE DBCC_PAGE_RESULT;GO CREATE TABLE DBCC_PAGE_RESULT(    [ParentObject]      NVARCHAR(200),    [Object]          NVARCHAR(2000),    [Field]          NVARCHAR(4000),    [Value]          NVARCHAR(MAX))GO CREATE PROCEDURE PRC_DBCC_PAGE( @dbid        INT, @filenum    INT, @pagenum     INT)AS  DBCC PAGE(@dbid, @filenum,  @pagenum, 3) WITH TABLERESULTS; GO DBCC TRACEON(3604)    ;WITH    t AS ( SELECT   Object ,                        Field ,                        Value ,                        CASE WHEN CHARINDEX('Column', Object) > 0                             THEN CHARINDEX('Column', Object)                             ELSE CHARINDEX('Offset', Object)                        END AS substring_len               FROM     dbo.DBCC_PAGE_RESULT dp               WHERE    Object LIKE 'Slot%Column%'                        OR Field = 'KeyHashValue'             ),        tt          AS ( SELECT   Object ,                        Field ,                        Value ,                        CAST(SUBSTRING(Object, LEN('Slot') + 1,                                       substring_len - LEN('Slot') - 1) AS INT) AS row               FROM     t             ),        ttt          AS ( SELECT   Object ,                        Field ,                        Value ,                        row ,    --第几行                          MAX(CASE WHEN Field = 'KeyHashValue' THEN Value                                 ELSE ''                            END) OVER ( PARTITION BY row ) AS KeyHashValue               FROM     tt             )    SELECT  *    FROM    ttt    WHERE   ttt.row = 0


如下截图所示,就可以找到行锁(Row Lock)锁定了row=0这行记录(注意,这里的行记录是从0开始的,而不是1),也就是DatabaseLogID=1的记录。如果1:273:2, 那么查询条件中row=2  这个表示这个页面的第几行记录。

                                                                                                                                                                                                                                                      



DSC0002.png



但是,有时候你锁定了一行,查询sys.dm_tran_locks时,你会发现resource_type为RID类型的记录有好几条,如下所示:


USE AdventureWorks2012;GO SELECT  @@SPID; BEGIN TRAN;UPDATE  [dbo].[DatabaseLog] WITH ( ROWLOCK )SET     TSQL = N'dddd'WHERE   DatabaseLogID = 21;--ROLLBACK;


DSC0003.png



其实真正是数据页的只有resource_description=1:273:4 这行记录, 也就是说这行记录位于Page Number=273下的第5条记录


DSC0004.png



其它一些页面,例如 1,295;  1,279等都不是数据页,如下截图所示:m_type的值表示这个是数据页、索引页、IAM页等等。具体参考


m_type

·         This is the page type. The values you’re likely to see are:

o   1 – data page. This holds data records in a heap or clustered index leaf-level.

o   2 – index page. This holds index records in the upper levels of a clustered index and all levels of non-clustered indexes.

o   3 – text mix page. A text page that holds small chunks of LOB values plus internal parts of text tree. These can be shared between LOB values in the same partition of an index or heap.

o   4 – text tree page. A text page that holds large chunks of LOB values from a single column value.

o   7 – sort page. A page that stores intermediate results during a sort operation.

o   8 – GAM page. Holds global allocation information about extents in a GAM interval (every data file is split into 4GB chunks – the number of extents that can be represented in a bitmap on a single database page). Basically whether an extent is allocated or not. GAM = Global Allocation Map. The first one is page 2 in each file. More on these in this post.

o   9 – SGAM page. Holds global allocation information about extents in a GAM interval. Basically whether an extent is available for allocating mixed-pages. SGAM = Shared GAM. the first one is page 3 in each file. More on these in this post.

o   10 – IAM page. Holds allocation information about which extents within a GAM interval are allocated to an allocation unit (portion of a table or index). IAM = Index Allocation Map. More on these in this post.

o   11 – PFS page. Holds allocation and free space information about pages within a PFS interval (every data file is also split into approx 64MB chunks – the number of pages that can be represented in a byte-map on a single database page. PFS = Page Free Space. The first one is page 1 in each file. More on these in this post.

o   13 – boot page. Holds information about the database. There’s only one of these in the database. It’s page 9 in file 1.

o   15 – file header page. Holds information about the file. There’s one per file and it’s page 0 in the file.

o   16 – diff map page. Holds information about which extents in a GAM interval have changed since the last full or differential backup. The first one is page 6 in each file.

o   17 – ML map page. Holds information about which extents in a GAM interval have changed while in bulk-logged mode since the last backup. This is what allows you to switch to bulk-logged mode for bulk-loads and index rebuilds without worrying about breaking a backup chain. The first one is page 7 in each file.

o   18 – a page that’s be deallocated by DBCC CHECKDB during a repair operation.

o   19 – the temporary page that ALTER INDEX … REORGANIZE (or DBCC INDEXDEFRAG) uses when working on an index.

o   20 – a page pre-allocated as part of a bulk load operation, which will eventually be formatted as a ‘real’ page.



DSC0005.png


DSC0006.png






参考资料:


http://blog.csdn.net/sqlserverdiscovery/article/details/13291629

https://www.sqlskills.com/blogs/paul/inside-the-storage-engine-anatomy-of-a-page/

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-423748-1-1.html 上篇帖子: sql server 2008安装的时候选NT AUTHORITY\NEWORK SERVICE 还是选 NT AUTHORITY\SYSTEM ? 下篇帖子: 微软 SQL Server 版本号
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表