Function Fn_PageResCracker Internals

Published On: 2019-04-05By:

In a previous blog post, I discussed two new methods to determine exactly which page a request might be waiting for when there is contention.  One of these new methods involves a new function, fn_pagerescracker.   Naturally, I wanted to see how this function operates.  Let’s look at the Master database to investigate how it works!

The function consumes a BINARY(8) parameter and returns a table.   This parameter represents a hexadecimal value that is constructed from the database ID, page ID, and file ID.

-- Name: sys.fn_PageResCracker
-- Description:
--	Cracks the output of wait_resource page info
-- Notes:
create function [sys].[fn_PageResCracker] (@physical_locator binary (8))
returns @dumploc_table table
	[db_id]	int not null,
	[file_id]	int not null,
	[page_id]	int not null

	if @physical_locator is not null
		declare @db_id	binary (2)
		declare @file_id	binary (2)
		declare @page_id	binary (4)

		-- Page ID is the first four bytes, then 2 bytes of file ID, then 2 bytes of slot
		select @page_id = convert (binary (4), reverse (substring (@physical_locator, 1, 4)))
		select @file_id = convert (binary (2), reverse (substring (@physical_locator, 5, 2)))
		select @db_id = convert (binary (2), reverse (substring (@physical_locator, 7, 2)))

		insert into @dumploc_table values (@db_id, @file_id, @page_id)

You can see from the code that the parameter is then “diced” up with SUBSTRING commands and then converted into a small binary value.  Also, using SUBSTRING against a binary value (which is the parameter that is passed in) will return the number of bytes specified rather than the number of characters.  In this case, the Page ID is the first 4 bytes, the file ID is the following 2 bytes and finally the last 2 bytes represents the database ID.  Furthermore, when they are inserted into the table (which is returned to the calling query) it is then converted into an integer value.

Shown above, the page_resource value is 0x5001000001000600.  Now that we know how the function is going to work, we can do the math ourselves and confirm things.  Keep in mind that SQL Server utilizes big endians, so we will have to do some byte reversing.

Byte Breakdown
Page ID File ID Database ID
0x50010000 0x0100 0x0600

Page ID = 0x50010000, byte reversed is 0x00000150 (or 0x150), which when converted to an integer = 336

File ID = 0x0100, again byte reversed is 0x0001 (or 0x1), which when converted to an integer is 1.

Database ID = 0x0600, reversed once again, 0x0006 (or 0x6), which converted to an integer is 6.

We can see below that we have now confirmed that the function is working as expected!


One of things I enjoy the most is digging into the internals on how SQL Server works.  It continues to teach me new and exciting things.  It also helps to make me a better DBA in my opinion.  In this case, the value add isn’t super steep but it’s still fun tearing apart the logic.




© 2019, John Morehouse. All rights reserved.

Contact the Author | Contact DCAC


Globally Recognized Expertise

As Microsoft MVP’s and Partners as well as VMware experts, we are summoned by companies all over the world to fine-tune and problem-solve the most difficult architecture, infrastructure and network challenges.

And sometimes we’re asked to share what we did, at events like Microsoft’s PASS Summit 2015.

Awards & Certifications

Microsoft Partner       Insights Sccess Award    Technology Headlines Award    Golden Bridge Gold Award    CIO Review Top 20 Azure Solutions Providers    VMWare Partner
Microsoft Certified Master    Microsoft MVP
Share via