在今天的文章里,我想向你展示下SQL Server里一个未公开的函数,还有你如何用那个函数来找出在哪页记录被存储。
今天我想向你展示的未公开函数叫做 %%lockres%% ,它与SQL Server的锁实现有关。我们都知道,SQL Server实现锁层级并在记录层,页层,表层请求锁。当在记录层锁被请求,SQL Server不在记录本身放置锁——SQL Server生成一个哈希值(hash value),这个结果哈希值最后被锁。为了计算这个哈希值,SQL Server使用未公开的 %%lockres%% 函数——你也可以自己调用。
当你在聚集表(有聚集索引定义的表)上调用这个函数, %%lockres%% 返回你聚集键列的哈希值。
1 SELECT %%lockres%%, * FROM Person.Person
通过 %%lockres%% 的返回值几乎没有意思,因为它只是个哈希值。但它可以是很方便的,因为在 sys.dm_tran_locks DMV里,你会知道 resource_description 列的哈希值。因为很容易找出在那条记录上锁被请求。
当你想在堆表上请求一个行层的锁,没有键值可以生成哈希值。在这个情况下,SQL Server在RID值上放置锁——即所谓的行标识值(Row Identifier Value)。这个值8 bytes长有如下格式: 文件号:页号:槽号(FileID:PageID:Slot) 。当你在堆表上调用 %%lockres%% 时,SQL Server会返回你这个RID值。
1 SELECT %%lockres%%, * FROM DatabaseLog
因此很容易在堆表上找到在哪个文件,哪个页,哪个槽号记录被存储——很简单,是不是?
感谢关注!