zoukankan      html  css  js  c++  java
  • SQL2005中的事务与锁定(九)-(2)- 转载

    ------------------------------------------------------------------------
    -- 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没有可用空间时,清理线程就会提前调用。在极端的情况下如果磁盘已经满,版本就无法生成,查询即失败,这是使用版本控制的一个注意事项。

  • 相关阅读:
    Redis使用小结
    MongoDB中的变更通知
    发布一个从迅雷下载字幕的小工具
    在Windows下通过netsh命令实现端口映射
    .net core在Linux ARM板上运行
    通过WinAPI播放PCM声音
    spring中scope作用域(转)
    Spring <context:annotation-config/> 解说(转)
    Jenkins+Maven+SVN快速搭建持续集成环境(转)
    maven中跳过单元测试(转)
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/10348569.html
Copyright © 2011-2022 走看看