1. 程式人生 > >SQL2005中的事務與鎖定(九)-(二)- 轉載

SQL2005中的事務與鎖定(九)-(二)- 轉載

ise clas iso state primary sql actions 內容 移除

------------------------------------------------------------------------
-- Author : HappyFlyStone
-- Date : 2010-01-18 22:00
-- Version: Microsoft SQL Server 2005 - 9.00.2047.00 (Intel X86)
-- Apr 14 2006 01:12:25
-- Copyright (c) 1988-2005 Microsoft Corporation
-- Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)

-- 轉載請註明出處,更多請關註:http://blog.csdn.net/happyflystone
-- 關鍵字:行版本存儲二、tempdb
------------------------------------------------------------------------

16、詳述行版本存儲區二

好,下面具體來看行版數據的結構。建議大家先關註這幾個動態管理視圖(DWV)。

select * from sys.dm_tran_version_store
select * from sys.dm_tran_current_transaction
select * from sys.dm_tran_transactions_snapshot go

sys.dm_tran_version_store 返回一個可顯示版本存儲區中所有版本記錄的虛擬表。其中有幾個字段要了解一下:

列名 說明
transaction_sequence_num 生成該記錄版本的事務的序列號
version_sequence_num 版本記錄序列號。此值在生成事務的版本中是唯一的。
status 指示有版本控制的記錄是否已拆分為兩個記錄。如果此值為 0,則記錄存儲在一頁中。如果此值為 1,則記錄拆分為兩個記錄,且存儲在兩個不同頁上。
min_length_in_bytes 記錄的最小長度(字節)。
record_image_first_part 版本記錄的第一部分的二進制圖像。
record_image_second_part 版本記錄的第二部分的二進制圖像。

dm_tran_current_transaction顯示當前會話中的事務狀態信息。

首先我們來看一下當前庫快照狀態:

select name,snapshot_isolation_state_desc,is_read_committed_snapshot_on
from sys.databases
where name = dblock
/*
name               snapshot_isolation_state_desc           is_read_committed_snapshot_on
------------- -------------------------------   -----------------------------
dblock              OFF                                                          1
(1 行受影響)
*/

好吧,我下面準備部分數據並用前面但要查看頁面信息的命令先看看頁面內容:

drop table ta
 
create table ta(id int,col char(10))
insert into ta select 1,aaaaaaaaaa
insert into ta select 1,bbbbbbbbbb
dbcc ind(dblock,ta,-1) --73
dbcc traceon(3604)
dbcc page(dblock,1,89,1)
00000000:   50001200 01000000 63636363 63636363 †P.......cccccccc         
00000010:   63200200 fcc80000 00010000 00120000 †c ..............         
00000020:   000000†††††††††††††††††††††††††††††††...                      
 
Slot 1, Offset 0x83, Length 35, DumpStyle BYTE
 
Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VERSIONING_INFO
 
Memory Dump @0x433BC083
 
00000000:   50001200 01000000 63636363 63636363 †P.......cccccccc         
00000010:   63200200 fcc80000 00010001 00120000 †c ..............         
00000020:   000000†††††††††††††††††††††††††††††††...          
---------------------------------------------------------------
Slot 0, Offset 0x60, Length 35, DumpStyle BYTE
 
Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VERSIONING_INFO
 
Memory Dump @0x444CC060
 
00000000:   50001200 01000000 64646464 64646464 †P.......dddddddd         
00000010:   64640200 fcd00000 00010000 00130000 †dd..............         
00000020:   000000†††††††††††††††††††††††††††††††...                      
 
Slot 1, Offset 0x83, Length 35, DumpStyle BYTE
 
Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VERSIONING_INFO
 
Memory Dump @0x444CC083
 
00000000:   50001200 01000000 64646464 64646464 †P.......dddddddd         
00000010:   64640200 fcd00000 00010001 00130000 †dd..............         
00000020:   000000†††††††††††††††††††††††††††††††...                      
            

至少上面顯示的行信息不用我介紹了吧,直接用我上面介紹的,因為當前沒有產生版本信息,我們用兩個select來驗證:

select * from sys.dm_tran_version_store
select * from sys.dm_tran_current_transaction

兩個SQL沒有返回任何信息,下面更新記錄生成版本信息。

update ta
set col = ddddddddd where id = 1
select * from sys.dm_tran_version_store
select * from sys.dm_tran_current_transaction
 
transaction_sequence_num version_sequence_num database_id rowset_id            status min_length_in_bytes record_length_first_part_in_bytes record_image_first_part                                                                                                                                                                                                                                            record_length_second_part_in_bytes record_image_second_part
---------------------------------------------------------------------
29     1  8      72057594038714368    0      18     35 0x5000120001000000616161616161616161610200FC0000000000000000100000000000        0        NULL


(1 行受影響)
 



transaction_id       transaction_sequence_num transaction_is_snapshot first_snapshot_sequence_num last_transaction_sequence_num first_useful_sequence_num
-------------------- --------- -------- -----  -------------------   
4872     18           0             NULL            29                21
 
(1 行受影響)

如果這時我們再查看原來的TA裏的slot0信息:

Slot 0, Offset 0x60, Length 35, DumpStyle BYTE
 
Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VERSIONING_INFO
 
Memory Dump @0x445EC060
 
00000000:   50001200 01000000 64646464 64646464 †P.......dddddddd         
00000010:   64200200 fcc00000 00010001 001d0000 †d ..............         
00000020:   000000†††††††††††††††††††††††††††††††...    

前面26個字節不用解釋了吧,那這(c00000 00010001 001d0000 000000)14個字節是什麽意思呢?大家是記得前面介紹過XSN啦,這就是14個字節指針信息,用於跟蹤行版本信息的。sys.dm_tran_current_transaction 表返回的first_useful_sequence_num列就是是大XSN行版本。XSN的如下:

第一部分 8bytes 第二部分 6bytes
c00000 00010001 00 1d0000 000000
在tempdb中的文件號、頁面號、slot號 記錄版本的事務的序列號
exec sp_us_FPSinfo 0xc000000001000100
FILE_NUM:PAGE_ID:SLOT_ID
----------------------------
1 : 192 : 1
1d è 29
每一個事務都會分配一個獨立並不斷增加的XSN值

驗證一下在tempdb中的內容 (註意紅色部分):

dbcc page(‘tempdb‘,1,192,1)
 
Slot 1, Offset 0xc8, Length 104, DumpStyle BYTE
Record Type = INDEX_RECORD           Record Attributes =  VARIABLE_COLUMNS
Memory Dump @0x441FC0C8
 
00000000:   26010068 0000851f 44f77f1b 01140000 †&..h....D.......     
00000010:   00000000 00010000 00000000 0008001f †................     
00000020:   44000005 a000000c 00000000 0112001f †D...............     
00000030:   441c5b1b 0180861f 441c0800 00000000 †D.[.....D.......     
00000040:   00000000 00500012 00010000 00616161 †.....P.......aaa     
00000050:   61616161 61616102 00fc0000 00000000 †aaaaaaa.........     
00000060:   00001000 00000000 †††††††††††††††††††........

17、版本區大小的管理
首先版本區的大小是SQLSERVER自行管理的,它有一個清理線程在活動,確保版本保留的時效。對於SI模式來說版本保留到事務結束,對於RCSI模式來說在Select結束線程就會移除版本數據。
清理線程活動周期以分鐘計,但是有一個例外,那就是如果周期未到而tempdb沒有可用空間時,清理線程就會提前調用。在極端的情況下如果磁盤已經滿,版本就無法生成,查詢即失敗,這是使用版本控制的一個註意事項。

SQL2005中的事務與鎖定(九)-(二)- 轉載