SQL2005中的事務與鎖定(九)-(二)- 轉載
------------------------------------------------------------------------
-- 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)
-- 關鍵字:行版本存儲二、tempdb
------------------------------------------------------------------------
16、詳述行版本存儲區二
好,下面具體來看行版數據的結構。建議大家先關註這幾個動態管理視圖(DWV)。
select * from sys.dm_tran_version_store select * from sys.dm_tran_current_transactionselect * 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中的事務與鎖定(九)-(二)- 轉載