메모리 최적화 tempdb 메타데이터(HkTempDB) 메모리 부족 오류

이 문서에서는 메모리 최적화 tempdb 메타데이터 기능과 관련된 메모리 부족 문제를 해결하는 해결 방법을 제공합니다.

증상

메모리 최적화 tempdb 메타데이터(HkTempDB) 기능을 사용하도록 설정하면 할당 및 SQL Server 서비스 크래시에 대한 tempdb 메모리 부족 예외를 나타내는 오류 701이 표시될 수 있습니다. 또한 In-Memory OLTP(Hekaton)의 메모리 클럭 MEMORYCLERK_XTP 이 점진적으로 또는 빠르게 증가하고 있으며 축소되지 않는 것을 볼 수 있습니다. XTP 메모리가 상한 없이 커지면 SQL Server 다음 오류 메시지가 표시됩니다.

리소스 풀 'default'의 메모리 부족으로 인해 데이터베이스 'tempdb'에 대한 페이지 할당을 허용하지 않습니다. 자세한 내용은 'http://go.microsoft.com/fwlink/?LinkId=510837'를 참조하세요.

DMVdm_os_memory_clerks 쿼리를 실행하면 메모리 클럭 MEMORYCLERK_XTP에 할당된 페이지 메모리가 높은 것을 볼 수 있습니다. 예를 들면

SELECT type, memory_node_id, pages_kb 
FROM sys.dm_os_memory_clerks
WHERE type = 'MEMORYCLERK_XTP'

결과:

type                    memory_node_id                     pages_kb
------------------------------------------------------------ -------------- --------------------
MEMORYCLERK_XTP         0                                  60104496
MEMORYCLERK_XTP         64                                 0

문제 진단

데이터를 수집하여 문제를 진단하려면 다음 단계를 수행합니다.

  1. 간단한 추적 또는 확장 이벤트(XEvent)를 수집하여 워크로드를 이해하고 tempdb 워크로드에 임시 테이블에 DDL 문이 있는 장기 실행 명시적 트랜잭션이 있는지 확인합니다.

  2. 다음 DMV의 출력을 수집하여 추가로 분석합니다.

    SELECT * FROM sys.dm_os_memory_clerks
    SELECT * FROM sys.dm_exec_requests
    SELECT * FROM sys.dm_exec_sessions
    
    -- from tempdb
    SELECT * FROM tempdb.sys.dm_xtp_system_memory_consumers 
    SELECT * FROM tempdb.sys.dm_db_xtp_memory_consumers
    
    SELECT * FROM tempdb.sys.dm_xtp_transaction_stats
    SELECT * FROM tempdb.sys.dm_xtp_gc_queue_stats
    SELECT * FROM tempdb.sys.dm_db_xtp_object_stats
    
    SELECT * FROM tempdb.sys.dm_db_xtp_transactions
    SELECT * FROM tempdb.sys.dm_tran_session_transactions
    SELECT * FROM tempdb.sys.dm_tran_database_transactions
    SELECT * FROM tempdb.sys.dm_tran_active_transactions
    

원인 및 해결

DMV를 사용하여 원인을 확인하면 문제의 다양한 시나리오가 표시될 수 있습니다. 이러한 시나리오는 다음 두 범주로 나눌 수 있습니다. 문제를 resolve 위해 각 시나리오에 해당하는 해결 방법을 사용할 수 있습니다. 문제를 완화하는 방법에 대한 자세한 내용은 메모리 최적화 tempdb 메타데이터 메모리를 검사 유지하는 완화 단계를 참조하세요.

XTP 메모리 사용량의 점진적 증가

  • 시나리오 1

    DMV tempdb.sys.dm_xtp_system_memory_consumers 또는 tempdb.sys.dm_db_xtp_memory_consumers 할당된 바이트와 사용된 바이트 간에 큰 차이가 표시됩니다.

    해결 방법: 문제를 resolve 위해 2019 CU13, SQL Server SQL Server 2022 CU1 또는 할당되었지만 사용되지 않는 바이트를 해제하는 새 프로시저 sys.sp_xtp_force_gc 가 있는 이후 버전에서 다음 명령을 실행할 수 있습니다.

    참고

    SQL Server 2022 CU1부터 저장 프로시저를 한 번만 실행해야 합니다.

    /* Yes, 2 times for both*/
    EXEC sys.sp_xtp_force_gc 'tempdb'
    GO
    EXEC sys.sp_xtp_force_gc 'tempdb'
    GO
    EXEC sys.sp_xtp_force_gc
    GO
    EXEC sys.sp_xtp_force_gc
    
  • 시나리오 2

    DMV tempdb.sys.dm_xtp_system_memory_consumers 는 메모리 소비자 유형 VARHEAP 및 에 할당되고 사용되는 바이트에 대해 높은 값을 표시합니다 LOOKASIDE.

    해결 방법: 트랜잭션을 짧게 유지하여 임시 테이블 및 애플리케이션 쪽에서 resolve DDL 문과 관련된 장기 실행 명시적 트랜잭션을 확인합니다.

    참고

    테스트 환경에서 이 문제를 재현하려면 임시 테이블의 DDL(데이터 정의 언어) 문을 사용하여 명시적 트랜잭션 을 만들고 다른 작업이 발생할 때 오랫동안 열어 둘 수 있습니다.

  • 시나리오 3

    DMV tempdb.sys.dm_db_xtp_memory_consumers 는 , 및 가 인 큰 개체(LOB) 할당자 또는 테이블 힙Object_IDXTP_Object_ID에서 할당되고 Index_ID 사용되는 바이트에 대한 높은 값을 표시합니다NULL.

    해결 방법: 문제14535149 SQL Server 2019 CU16을 적용합니다.

  • 시나리오 4

    지속적으로 증가하는 "VARHEAP\Storage 내부 힙" XTP 데이터베이스 메모리 소비자는 메모리 부족 오류 41805로 이어집니다.

    해결 방법: SQL Server17 CU25 이상 버전에서 이미 식별되고 해결된 14087445 문제는 2019년 SQL Server 이식될 예정입니다.

XTP 메모리 사용량이 급격히 증가하거나 급격히 증가

  • 시나리오 5

    DMV tempdb.sys.dm_db_xtp_memory_consumers 는 가 아닌 NULL테이블 힙 Object_ID 에서 할당되거나 사용되는 바이트에 대한 높은 값을 표시합니다. 이 문제의 가장 일반적인 원인은 임시 테이블에 DDL 문을 사용하여 명시적으로 열려 있는 장기 실행 트랜잭션입니다. 예를 들면

    BEGIN TRAN
        CREATE TABLE #T(sn int)
        …
        …
    COMMIT
    

    임시 테이블에 DDL 문을 사용하여 명시적으로 열린 트랜잭션은 메타데이터를 사용하여 tempdb 후속 트랜잭션에 대해 테이블 힙 및 lookaside 힙을 해제할 수 없습니다.

    해결 방법: 트랜잭션을 짧게 유지하여 임시 테이블 및 애플리케이션 쪽에서 resolve DDL 문과 관련된 장기 실행 명시적 트랜잭션을 확인합니다.

메모리 최적화 tempdb 메타데이터 메모리를 검사 유지하는 완화 단계

  1. 임시 테이블에서 DDL 문을 사용하는 장기 실행 트랜잭션을 방지하거나 resolve 일반적인 지침은 트랜잭션을 짧게 유지하는 것입니다.

  2. tempdb가 많은 워크로드가 있는 상태에서 충분한 메모리가 작동할 수 있도록 최대 서버 메모리 를 늘입니다.

  3. 주기적으로 실행 sys.sp_xtp_force_gc 합니다.

  4. 메모리 부족 상태로부터 서버를 보호하기 위해 tempdb를 Resource Governor 리소스 풀에 바인딩할 수 있습니다. 예를 들어 를 사용하여 MAX_MEMORY_PERCENT = 30리소스 풀을 만듭니다. 그런 다음, 다음 ALTER SERVER CONFIGURATION 명령을 사용하여 리소스 풀을 메모리 최적화 tempdb 메타데이터에 바인딩합니다.

    ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON (RESOURCE_POOL = '<PoolName>');
    

    메모리 최적화 tempdb 메타데이터를 이미 사용하도록 설정한 경우에도 이 변경 사항을 적용하려면 다시 시작해야 합니다. 자세한 내용은 다음 항목을 참조하세요.

    경고

    풀에 HktempDB를 바인딩한 후 풀이 최대 설정에 도달할 수 있으며, 를 사용하는 tempdb 모든 쿼리는 메모리 부족 오류로 인해 실패할 수 있습니다. 예를 들면

    리소스 풀 'HkTempDB'의 메모리 부족으로 인해 데이터베이스 'tempdb'에 대한 페이지 할당을 허용하지 않습니다. 자세한 내용은 'http://go.microsoft.com/fwlink/?LinkId=510837'를 참조하세요. 메모리 압력으로 인한 XTP 페이지 할당 실패: FAIL_PAGE_ALLOCATION 8

    특정 상황에서 메모리 부족 오류가 발생하면 SQL Server 서비스가 중지될 수 있습니다. 이런 일이 발생할 가능성을 줄이려면 메모리 풀의 MAX_MEMORY_PERCENT 값을 높은 값으로 설정합니다.

  5. 메모리 최적화 tempdb 메타데이터 기능은 모든 워크로드를 지원하지 않습니다. 예를 들어 오랜 시간 동안 실행되는 임시 테이블에서 DDL 문과 함께 명시적 트랜잭션을 사용하면 설명된 시나리오로 이어질 수 있습니다. 워크로드에 이러한 트랜잭션이 있고 해당 기간을 제어할 수 없는 경우 이 기능이 사용자 환경에 적합하지 않을 수 있습니다. 를 사용하기 HkTempDB전에 광범위하게 테스트해야 합니다.

추가 정보

이 섹션에서는 메모리 최적화 tempdb 메타데이터와 관련된 일부 메모리 구성 요소에 대해 자세히 설명합니다.

Lookaside 메모리 할당자

In-Memory OLTP의 Lookaside는 빠른 트랜잭션 처리를 달성하는 데 도움이 되는 스레드 로컬 메모리 할당자입니다. 각 스레드 개체에는 lookaside 메모리 할당자 컬렉션이 포함되어 있습니다. 각 스레드와 연결된 각 lookaside에는 할당할 수 있는 메모리 양에 대한 미리 정의된 상한이 있습니다. 제한에 도달하면 스레드는 분산된 공유 메모리 풀(VARHEAP)에서 메모리를 할당합니다. DMV sys.dm_xtp_system_memory_consumers 는 각 lookaside 형식() 및 공유 메모리 풀(memory_consumer_type_desc = 'LOOKASIDE'memory_consumer_type_desc = 'VARHEAP'memory_consumer_desc = 'Lookaside heap')에 대한 데이터를 집계합니다.

시스템 수준 소비자: tempdb.sys.dm_xtp_system_memory_consumers

약 25가지의 lookaside 메모리 소비자 유형이 상한입니다. 스레드가 이러한 조회에서 더 많은 메모리를 필요로 하는 경우 메모리가 로 분산되어 lookaside 힙에 만족합니다. 사용된 바이트에 대한 높은 값은 임시 개체를 사용하는 일정한 워크 tempdb 로드 및/또는 장기 실행 개방형 트랜잭션을 나타내는 지표일 수 있습니다.

-- system memory consumers @ instance  
SELECT memory_consumer_type_desc, memory_consumer_desc, allocated_bytes, used_bytes
FROM sys.dm_xtp_system_memory_consumers 
memory_consumer_type_desc     memory_consumer_desc                   allocated_bytes      used_bytes
------------------------- ------------------------------------------ -------------------- --------------------
VARHEAP                       Lookaside heap                             0                    0
PGPOOL                        256K page pool                             0                    0
PGPOOL                        4K page pool                               0                    0
VARHEAP                       System heap                                458752               448000
LOOKASIDE                     Transaction list element                   0                    0
LOOKASIDE                     Delta tracker cursor                       0                    0
LOOKASIDE                     Transaction delta tracker                  0                    0
LOOKASIDE                     Creation Statement Id Map Entry            0                    0
LOOKASIDE                     Creation Statement Id Map                  0                    0
LOOKASIDE                     Log IO proxy                               0                    0
LOOKASIDE                     Log IO completion                          0                    0
LOOKASIDE                     Sequence object insert row                 0                    0
LOOKASIDE                     Sequence object map entry                  0                    0
LOOKASIDE                     Sequence object values map                 0                    0
LOOKASIDE                     Redo transaction map entry                 0                    0
LOOKASIDE                     Transaction recent rows                    0                    0
LOOKASIDE                     Heap cursor                                0                    0
LOOKASIDE                     Range cursor                               0                    0
LOOKASIDE                     Hash cursor                                0                    0
LOOKASIDE                     Transaction dependent ring buffer          0                    0
LOOKASIDE                     Transaction save-point set entry           0                    0
LOOKASIDE                     Transaction FK validation sets             0                    0
LOOKASIDE                     Transaction partially-inserted rows set    0                    0
LOOKASIDE                     Transaction constraint set                 0                    0
LOOKASIDE                     Transaction save-point set                 0                    0
LOOKASIDE                     Transaction write set                      0                    0
LOOKASIDE                     Transaction scan set                       0                    0
LOOKASIDE                     Transaction read set                       0                    0
LOOKASIDE                     Transaction                                0                    0

데이터베이스 수준 소비자: tempdb.sys.dm_db_xtp_memory_consumers

  • LOB 할당자는 시스템 테이블 LOB/행 끄기 데이터에 사용됩니다.

  • 테이블 힙은 시스템 테이블 행에 사용됩니다.

사용된 바이트에 대한 높은 값은 임시 개체를 사용하는 일정한 워크 tempdb 로드 및/또는 장기 실행 개방형 트랜잭션을 나타내는 지표일 수 있습니다.