Files
sql-server-samples/samples/features/in-memory-database/memory-optimized-tempdb-metadata/MemoryOptimizedTempDBMetadata-TSQL.ipynb
T
Pam Lahoud 030be3b5ec Update MemoryOptimizedTempDBMetadata-TSQL.ipynb
Re-running notebook cells with feature enabled.
2019-12-03 10:22:07 -08:00

23 KiB

Exploring Memory-Optmized TempDB Metadata

TempDB metadata contention has historically been a bottleneck to scalability for many workloads running on SQL Server. SQL Server 2019 introduces a new feature that is part of the In-Memory Database feature family, memory-optimized tempdb metadata, which effectively removes this bottleneck and unlocks a new level of scalability for tempdb-heavy workloads. In SQL Server 2019, the system tables involved in managing temp table metadata can be moved into latch-free non-durable memory-optimized tables.

To learn more about tempdb metadata contention, along with other types of tempdb contention, check out the blog article TEMPDB - Files and Trace Flags and Updates, Oh My!. Keep reading to explore the new memory-optimized tempdb metadata feature.

Configure the AdventureWorks sample database

Follow these steps to configure your environment in preparation for the demo. Alternatively, you can use the pre-configured container using the instructions in the Python companion notebook. Keep in mind that whether you use the container or your own server, you will need at least 4 cores to generate TempDB metadata contention.

  1. Ensure you have the latest version of SQL Server 2019 installed. You will need Evaluation, Enterprise, or Developer Edition in order to execute this demo.
  2. Download the AdventureWorks2017.bak sample database backup from GitHub. For your convenience, a copy of this backup has been included in the demo folder.
  3. Restore the database as AdventureWorks.

NOTE
You will need to change the paths in the following example to match your server file paths.

In [0]:
USE [master]
RESTORE DATABASE [AdventureWorks] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL15.SQL2019\MSSQL\Backup\AdventureWorks2017.bak' 
WITH  FILE = 1,  
		MOVE N'AdventureWorks2017' TO N'C:\Program Files\Microsoft SQL Server\MSSQL15.SQL2019\MSSQL\DATA\AdventureWorks.mdf',  
		MOVE N'AdventureWorks2017_log' TO N'C:\Program Files\Microsoft SQL Server\MSSQL15.SQL2019\MSSQL\DATA\AdventureWorks_log.ldf',  NOUNLOAD
GO
  1. Run the 01b-Create_EmployeeBirthdayList.sql script to create the workload procedure.
In [0]:
USE AdventureWorks
GO

CREATE OR ALTER PROCEDURE usp_EmployeeBirthdayList @month int AS
BEGIN

	IF OBJECT_ID('tempdb..#Birthdays') IS NOT NULL DROP TABLE #Birthdays;

	CREATE TABLE #Birthdays (BusinessEntityID int NOT NULL PRIMARY KEY);

	INSERT #Birthdays (BusinessEntityID)
	SELECT BusinessEntityID
	FROM HumanResources.Employee 
	WHERE MONTH(BirthDate) = @month

	SELECT p.FirstName, p.LastName, a.AddressLine1, a.AddressLine2, a.City, sp.StateProvinceCode, a.PostalCode
	FROM #Birthdays b
	INNER JOIN Person.Person p ON b.BusinessEntityID = p.BusinessEntityID
	INNER JOIN Person.BusinessEntityAddress bea ON p.BusinessEntityID = bea.BusinessEntityID
	INNER JOIN Person.Address a ON bea.AddressID = a.AddressID
	INNER JOIN Person.StateProvince sp ON a.StateProvinceID = sp.StateProvinceID
	INNER JOIN Person.AddressType at ON at.AddressTypeID = bea.AddressTypeID
	WHERE at.Name = N'Home'

END;

Run the demo scenario to generate the workload

Use the included ostress.exe tool to generate a multi-threaded load against your server. You will need a minimum of 4 cores to generate the contention. When configuring the ostress command, generally a 1:4 ratio of cores to concurrent threads works best to simulate the scenario and demonstrate the improvement. For example, this demo was tested with 4 cores and 16 concurrent threads. If you have 8 cores, start with 32 concurrent threads. You will also need to configure the number of iterations to allow the scenario to run long enough to observe the server. For 4 cores and 16 threads, 120 iterations should take around 30 seconds without Memory-Optimized TempDB Metadata enabled, 20 seconds with it enabled. Use the -r parameter to increase this number if you would like the script to run longer. Switch to the Python notebook to run the command, or you can open a Command Prompt window and execute the following command:

ostress.exe -Slocalhost,1455 -Usa -PP@ssw0rd! -dAdventureWorks -Q"EXEC dbo.usp_EmployeeBirthdayList 4" -mstress -quiet -n20 -r120 | FINDSTR "QEXEC Starting Creating elapsed"

Monitor your workload for page contention

You can use the following script to view all the sessions that are waiting for page-related wait types and get information about the objects that the pages belong to.

In [11]:
USE master
GO

SELECT 
er.session_id, er.wait_type, er.wait_resource, 
OBJECT_NAME(page_info.[object_id],page_info.database_id) as [object_name],
er.blocking_session_id,er.command, 
    SUBSTRING(st.text, (er.statement_start_offset/2)+1,   
        ((CASE er.statement_end_offset  
          WHEN -1 THEN DATALENGTH(st.text)  
         ELSE er.statement_end_offset  
         END - er.statement_start_offset)/2) + 1) AS statement_text,
page_info.database_id,page_info.[file_id], page_info.page_id, page_info.[object_id], 
page_info.index_id, page_info.page_type_desc
FROM sys.dm_exec_requests AS er
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS st 
CROSS APPLY sys.fn_PageResCracker (er.page_resource) AS r  
CROSS APPLY sys.dm_db_page_info(r.[db_id], r.[file_id], r.page_id, 'DETAILED') AS page_info
WHERE er.wait_type like '%page%'
GO
Out [11]:
Commands completed successfully.
(3 rows affected)
Total execution time: 00:00:00.267
session_idwait_typewait_resourceobject_nameblocking_session_idcommandstatement_textdatabase_idfile_idpage_idobject_idindex_idpage_type_desc
70PAGELATCH_EX2:1:118sysschobjs71EXECUTEEXEC dbo.usp_EmployeeBirthdayList 421118342INDEX_PAGE
78PAGELATCH_EX2:1:118sysschobjs71EXECUTEEXEC dbo.usp_EmployeeBirthdayList 421118342INDEX_PAGE
79PAGELATCH_EX2:1:118sysschobjs72CREATE TABLECREATE TABLE #Birthdays (BusinessEntityID int NOT NULL PRIMARY KEY)21118342INDEX_PAGE

Enable and Disable Memory-Optimized TempDB Metadata

The following script will enable Memory-Optimized TempDB Metadata. Note that this change requires a server restart to take effect.

In [2]:
ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA=ON;
GO
Commands completed successfully.
Total execution time: 00:00:00.141

Once the command is complete, restart the SQL Server service, then run the following command to verify that Memory-Optimized TempDB Metadata has been enabled.

In [4]:
SELECT SERVERPROPERTY('IsTempDBMetadataMemoryOptimized') AS IsTempDBMetadataMemoryOptimized; 
GO
Out [4]:
(1 row affected)
Total execution time: 00:00:00.132
IsTempDBMetadataMemoryOptimized
1

The system stored procedure sp_configure can also be used. If the config_value does not equal the run_value, it means that the configuration has been changed, but the server must be restarted in order for it to take effect.

In [5]:
EXEC sp_configure 'show advanced options', 1
RECONFIGURE

EXEC sp_configure 'tempdb metadata memory-optimized'
Out [5]:
Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.
Total execution time: 00:00:00.180
nameminimummaximumconfig_valuerun_value
tempdb metadata memory-optimized0111

Simlarly, you can use the following script to disable Memory-Optimized TempDB Metadata. This also requires a server restart.

In [16]:
ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA=OFF;
GO
Commands completed successfully.
Total execution time: 00:00:00.037