dbcc page解析行数据

 

dbcc page解析行数据

 

        dbcc page 用法详解:

dbcc page ( {'dbname' | dbid}, filenum, pagenum [,printopt={0|1|2|3} ])

The printopt parameter has the following meanings:

·    0 - print just the page header

·    1 - page header plus per-row hex dumps anda dump of the page slot array (unless its a page that doesn't have one, likeallocation bitmaps)

·    2 - page header plus whole page hex dump

·    3 - page header plus detailed per-rowinterpretation

 

1、构造测试数据。

先创建一个表

 

[sql] 

 

--建表 

if OBJECT_ID('t1') is not null 

 drop table t1 

go 

 

create table t1 

id int primary key, 

v varchar(20) 

 

 

insert into t1 

select 1 ,'aa' union all 

select 2 ,'bb' union all 

select 3 ,'cc' union all 

select 4 ,'dd' union all 

select 5 ,'ee' union all 

select 6 ,'ff' 


开启会话X,在里面输入下面的代码:

[sql] 

 

--执行顺序.1 

begin tran 

 

 update t1 

 set v = 'xx' 

 where id = 3 

--执行顺序.1 

 

 

--执行顺序.3 

 update t1 

 set v = 'yy' 

 where id = 6 

--执行顺序.3 

 

 

再次开启会话Y,在里面输入代码:

 

[sql] 

 

--执行顺序.2 

begin tran 

 

 update t1 

 set v = 'mm' 

 where id = 6 

 

--执行顺序.2 

 

 

--执行顺序.4 

 update t1 

 set v = 'nn' 

 where id = 3 

 

--执行顺序.4 


然后,按照先执行会话X中的执行顺序1,然后执行会话Y中的执行顺序2,执行会话X中的执行顺序3,执行会话Y中的执行顺序4,一步一步执行。

 

当执行完这4个步骤后,在会话X中,显示了死锁,且会话X的事务被回滚:

 

 

同时,能在SQL Profiler中看到监控到的死锁:

从这个图中,我们可以看到详细的死锁信息,打叉的表示被回滚的会话,把鼠标放到椭圆上,会显示导致死锁的,这个会话正在运行的sql语句。

在长方形的框中,可以看到两个会话要获取X锁,左边的会话拥有下面方框中的键锁,右边的会话拥有上面的键锁,而当左边的会话想要获取上面的键锁是,被阻塞住了,而当右边的会话想要获取下面的键锁时,也被阻塞了,于是整个图像中形成了一个循环,也就导致了死锁。

 

2、获取更详细的阻塞信息。

通过通过sys.dm_tran_locks,可以获取到更为详细的阻塞信息。

 

[sql] 

 

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 = 58 

 

 

解析resource_associated_entity_id的值:

 

[sql] 

 

--1.查询resource_associated_entity_id的意义 

select * 

from sys.tables 

where object_id = 837578022 

/* 

这个id是t1表 

 

name object_id 

t1 837578022 

*/ 

 

 

--2.查询resource_associated_entity_id的意义 

select * 

from sys.partitions p 

where p.hobt_id = 72057594041466880 

/* 

这个是表t1的一个b树 

 

partition_id object_id index_id partition_number hobt_id 

72057594041466880 837578022 1 1 72057594041466880 

*/ 


4
、通过dbcc page来解析sys.dm_tran_locks中resource_description列的值:

 

 

[sql] 

 

resource_type resource_database_id resource_description 

PAGE 10 1:188 

KEY 10 (b9b173bbe8d5) 

KEY 10 (98ec012aa510) 


为了能解析resource_description的值,需要建立一个表和一个存储过程,注意在存储过程中引用的1:188,就是上面sys.dm_tran_locks中的结果:

 

 

[sql] 

 

--3.这里创建一个表,用来存放dbcc page的结果 

if exists(select * from sys.tables where name = 'dbcc_page') 

 drop table dbcc_page 

go 

create table dbcc_page 

ParentObject varchar(500), 

Object varchar(2000), 

Field varchar(1000), 

Value nvarchar(max) 

go 

 

 

--创建一个存储过程 

if exists(select * from sys.procedures where name = 'proc_dbcc_page') 

 drop procedure proc_dbcc_page 

go 

 

create procedure proc_dbcc_page 

as 

 

DBCC page(10, --数据库id : 10 

 1, --文件id: 1 

 188, --页id: 188 

 3) with tableresults 

 

go 

 

insert into dbcc_page 

exec proc_dbcc_page 

go 


最后,我们查询一下,(b9b173bbe8d5)和(98ec012aa510),到底是哪一行数据

 

 

[sql] 

 

--查询(b9b173bbe8d5)和(98ec012aa510),到底是哪一行数据 

;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 dbcc_page 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 KeyHashValue in ('(b9b173bbe8d5)', '(98ec012aa510)') 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值