Computer >> 컴퓨터 >  >> 프로그래밍 >> 데이터베이스

SQL Server 메모리 최적화 테이블로 인한 메모리 부족 경고 해결 방법

Microsoft SQL Server는 메모리 관리 측면에서 매우 뛰어난 성능을 자랑하지만, 때때로 메모리 부담(memory pressure) 경고가 발생하고 데이터베이스 엔진이 더 많은 메모리를 요구하면서 오류가 발생할 수 있습니다.

소개

이 글에서는 SQL Server® 2019(Enterprise Edition) 환경에서 메모리 최적화 테이블(In-Memory OLTP)로 인해 발생하는 메모리 부담 문제를 해결하는 방법을 단계별로 살펴봅니다. 소개하는 절차는 SQL Server 2014 이상 버전에도 동일하게 적용할 수 있습니다.

다음과 같은 오류 메시지가 화면에 나타나는 경우가 있습니다.

Message: MSSQL on Windows: Stolen Server Memory is too high
Source: XXXXX\MSSQLSERVER Path: Not Present Alert
description: SQL instance "MSSQLSERVER" Stolen Server Memory on computer "XXXXXXX.XXX.com" is too high.

Message: SQL Server Alert System: 'Severity 17' occurred on \\XXXXXXX
DESCRIPTION: There is insufficient system memory in resource pool 'internal' to run this query.

Message: Disallowing page allocations for database 'InMemoryDB' due to insufficient memory in the resource pool 'default'. See 'https://go.microsoft.com/fwlink/?LinkId=510837' for more information.

Message: XTP failed page allocation due to memory pressure: FAIL_PAGE_ALLOCATION 32

해결 방법

아래 단계를 순서대로 수행하여 문제를 진단하고 해결할 수 있습니다.

1단계: SQL 버퍼 풀 메모리 사용량 확인

가장 먼저 SQL 버퍼 풀(buffer pool)의 메모리 사용량을 점검합니다.

SQL Server 메모리 최적화 테이블로 인한 메모리 부족 경고 해결 방법

위 이미지에서 확인할 수 있듯이, 문제가 된 데이터베이스 InMemoryDB는 버퍼 풀의 약 0.017%만 사용하고 있었습니다.

2단계: OS 메모리 클럭(Memory Clerks) 확인

다음으로 아래 T-SQL 명령어를 실행하여 OS 메모리 클럭을 확인합니다.

select * from sys.dm_os_memory_clerks order by pages_kb desc
SQL Server 메모리 최적화 테이블로 인한 메모리 부족 경고 해결 방법

결과를 보면 주요 메모리 소비 항목들이 전체 최대 서버 메모리의 약 80%를 차지하고 있었습니다. 또한 메모리 최적화 테이블의 크기는 DB_ID_6 이름으로 확인되는 것처럼 2GB 미만으로 작았습니다. 이상적으로라면 서버에 메모리 부담이 발생하지 않아야 하는 상황입니다.

3단계: 리소스 풀 생성 및 데이터베이스 바인딩

오류 로그에 안내된 OOM(Out of Memory) 링크인 https://go.microsoft.com/fwlink/?LinkId=510837을 검토한 후, 메모리 최적화 테이블이 있는 데이터베이스를 리소스 풀(resource pool)에 바인딩해야 합니다. 이러한 바인딩은 메모리 최적화 테이블을 사용하는 데이터베이스의 모범 사례(best practice)로 권장됩니다. 리소스 관리자(Resource Governor)에서 리소스 풀을 생성하고 데이터베이스를 바인딩하는 절차는 다음과 같습니다.

모범 사례에 따르면, 하나 이상의 메모리 최적화 테이블이 SQL Server의 리소스를 독점하는 상황을 방지하고, 반대로 다른 메모리 사용자가 메모리 최적화 테이블에 필요한 메모리를 임의로 소비하는 것도 차단해야 합니다. 따라서 메모리 최적화 테이블이 있는 데이터베이스의 메모리 소비를 관리하기 위한 별도의 리소스 풀을 만드는 것이 좋습니다.

데이터베이스를 리소스 풀에 추가할 때는 다음 사항을 유의해야 합니다.

  • 하나의 데이터베이스는 하나의 리소스 풀에만 바인딩할 수 있습니다.
  • 여러 데이터베이스를 동일한 풀에 바인딩하는 것은 가능합니다.
  • SQL Server는 메모리 최적화 테이블이 없는 데이터베이스의 리소스 풀 바인딩도 허용하지만, 실질적인 효과는 없습니다.
  • 데이터베이스를 리소스 풀에 바인딩한 후에도 메모리 최적화 테이블을 새로 생성할 수 있습니다.

리소스 풀 바인딩 절차

  1. 메모리 할당 설정과 함께 리소스 풀을 생성합니다.

    USE [master]
    GO
    
    CREATE RESOURCE POOL [Admin_Pool] WITH(min_cpu_percent=0, 
       max_cpu_percent=100, 
       min_memory_percent=15, 
       max_memory_percent=15, 
       cap_cpu_percent=100, 
       AFFINITY SCHEDULER = AUTO,
       min_iops_per_volume=0,
       max_iops_per_volume=0)
    GO

    참고: 메모리 부족(OOM) 상황을 방지하려면 min_memory_percentmax_memory_percent 값을 동일하게 설정해야 합니다.

    이 사례에서는 메모리 최적화 테이블의 크기가 매우 작았기 때문에 전체 서버 메모리의 15%를 해당 리소스 풀에 할당했습니다. 여러분의 환경에 맞는 메모리 비율은 본문 하단의 참조 링크를 활용해 계산하는 것을 잊지 마세요.

  2. 리소스 풀을 확인하고 데이터베이스를 바인딩합니다.

    EXEC sp_xtp_bind_db_resource_pool 'InMemoryDB', 'Admin_Pool'  
    GO
  3. sys.databases 카탈로그 뷰에서 바인딩 결과를 확인합니다.

    SELECT d.database_id, d.name, d.resource_pool_id  
    FROM sys.databases d
    GO
    SQL Server 메모리 최적화 테이블로 인한 메모리 부족 경고 해결 방법
  4. 바인딩을 활성화하기 위해 데이터베이스를 재시작합니다.

    ALTER DATABASE DB_Name SET OFFLINE  
    GO  
    ALTER DATABASE DB_Name SET ONLINE  
    GO  

참고: Always On 가용성 그룹을 사용 중이라면 두 노드 모두에서 동일한 작업을 수행하고, 4단계(데이터베이스 재시작) 대신 보조 인스턴스로 데이터베이스 장애 조치(failover)를 진행하세요.

결론

이 사례에서는 메모리 최적화 테이블이 포함된 데이터베이스를 리소스 풀에 추가한 후, 메모리 부담 관련 모든 경고가 더 이상 발생하지 않았습니다. 몇 주간 SQL Server 오류 로그를 지속적으로 모니터링했지만 메모리 부담 흔적은 전혀 발견되지 않았습니다. 이 절차를 통해 최소한의 가동 중단 시간만으로 데이터베이스 엔진 수준의 메모리 부담 문제를 해결할 수 있었습니다.

궁금한 점이나 의견이 있다면 피드백 탭을 활용해 주세요. 언제든지 여러분과 대화를 나눌 준비가 되어 있습니다.