SQL Server中TempDB管理(version store的逻辑结构)


资料来自:

https://blogs.msdn.com/b/sqlserverstorageengine/archive/tags/tempdb/

https://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/12/31/managing-tempdb-in-sql-server-tempdb-basics-version-store-logical-structure.aspx

前面几篇博文已经初步介绍了版本存储区,现在我们来了解一下它的逻辑结构,看看它究竟是如何储存不同结构的表格和索引行的。其实我们只要看一下DMV
sys.dm_tran_version_store
这个DMV就够了 .

这个DVM视图显示了版本存储区全部逻辑结构。有两点值得注意。第一,版本存储区也和数据页面索引页面一样由8k大小的页组成。这些页存在缓冲池中,可以在TempDB面临内存压力时被写入磁盘。第二,版本存储区存储的是完整的二进制文件,就像在数据页存储的一样。这种二进制文件分为前后两个部分,然后在SQL
Server内部会对其进行组合。这使得行版本存储独立于它所属的对象的架构,即一个储存区的页可以存储来自不同表不同索引的行,甚至可能来自同一实例下的不同数据库。换句话说,版本存储区是一个SQL
Server实例下公用的。和数据页和索引页一样,在内存紧张的时候版本存储页也会从缓冲池中被清除。

如果查看名为sys.dm_tran_version_store的DMV会发现,我们会发现版本行有很多原始数据或索引页面所没有的的新属性,如database-id,行长度等。您可能会问,行版本同样受到SQL
Server最大行长度8060的限制,那么它是如何存储原始数据行(最大行长度也是8060)并增长新属性的呢。答案是,数据行在版本存储页实际上被分成了2行,只是在DMV视图中表现成一大行。

下面是一个版本存储的例子。事务57已经更新了三个不同的行,同时事务58只更新1行内容。请注意,如果一个事务中多次更新同一行,只会创建一个行版本,因为对其他事务来说,它从一开始就持有了X锁。

transaction_sequence_num
version_sequence_num database_id

------------------------
-------------------- -----------

57                      1                    9          

57                      2                    9          

57                      3                    9          

58                      1                    9          

 

rowset_id            status min_length_in_bytes

--------------------
------ -------------------

72057594038321152    0     
12                 

72057594038321152    0     
12                

72057594038321152    0     
12                

72057594038386688    0     
16                

 

record_length_first_part_in_bytes

---------------------------------

29                              

29                              

29                              

33                              

 

record_image_first_part                                            

--------------------------------------------------------------------

0x50000C0073000000010000000200FCB000000001000000270000000000       

0x50000C0073000000020000000200FCB000000001000100270000000000       

0x50000C0073000000030000000200FCB000000001000200270000000000       

0x500010000100000002000000030000000300F800000000000000002E0000000000

 

record_length_second_part_in_bytes    record_image_second_part

----------------------------------
----------------------

0                                  NULL

0                                  NULL

0                                  NULL

0                                  NULL