Microsoft SQL Server는 메모리 관리 측면에서 매우 지능적이지만 때때로 메모리 부족 경고 및 데이터베이스 엔진이 더 많은 메모리를 요구하여 오류가 발생합니다.
소개
이 게시물에서는 메모리 최적화 테이블(메모리 내 온라인 트랜잭션 처리(OLTP))으로 인해 SQL Server® 2019(Enterprise Edition)의 메모리 부족으로 인해 발생할 수 있는 예외적인 시나리오 중 하나를 해결하는 방법에 대해 설명합니다. 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 버퍼 풀의 메모리 사용량을 확인하는 것입니다.
앞의 이미지에서 볼 수 있듯이 문제의 데이터베이스 InMemoryDB ,버퍼 풀의 0.017%만 사용합니다.
2단계
그런 다음 다음 T-SQL 명령을 사용하여 OS Memory Clerks를 확인합니다.
select * from sys.dm_os_memory_clerks order by pages_kb desc
결과에 따르면 상위 소비자의 합계는 전체 최대 서버 메모리의 약 80%였습니다.
메모리 최적화 테이블의 크기도 2GB 미만이며, 이는 DB_ID_6 이름에 대한 이전 이미지에서 볼 수 있습니다. . 따라서 이상적으로는 서버에 메모리 부담이 없어야 합니다.
3단계
오류 로그에 언급된 메모리 부족(OOM) 링크를 검토한 후 https://go.microsoft.com/fwlink/?LinkId=510837 , 메모리 최적화 테이블이 있는 데이터베이스를 리소스 풀에 바인딩해야 합니다. 이 바인딩은 메모리 최적화 테이블이 있는 데이터베이스에 대한 모범 사례입니다. 리소스 관리자에서 리소스 풀을 만들고 데이터베이스를 바인딩하는 단계를 따릅니다.
모범 사례에서는 SQL Server가 하나 이상의 메모리 최적화 테이블에서 리소스를 소비하지 않도록 보호하고 다른 메모리 사용자가 메모리 최적화 테이블에 필요한 메모리를 소비하지 못하도록 하는 것이 좋습니다. 따라서 메모리 최적화 테이블이 있는 데이터베이스의 메모리 소비를 관리하기 위해 별도의 리소스 풀을 생성해야 합니다.
리소스 풀에 데이터베이스를 추가할 때 다음 사항에 유의하십시오.
- 하나의 리소스 풀에만 데이터베이스를 바인딩할 수 있습니다.
- 여러 데이터베이스를 동일한 풀에 바인딩할 수 있습니다.
- SQL Server를 사용하면 메모리 최적화 테이블이 없는 데이터베이스를 리소스 풀에 바인딩할 수 있지만 효과가 없습니다.
- 데이터베이스를 리소스 풀에 바인딩한 후 메모리 최적화 테이블을 생성할 수 있습니다.
리소스 풀에 바인딩하는 단계
-
메모리 할당으로 리소스 풀 생성:
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
참고 :메모리 부족 조건을 피하기 위해 min_memory_percent 값 및 max_memory_percent 동일해야 합니다.
이 경우 메모리 최적화 테이블은 리소스 풀에 할당된 총 서버 메모리의 15%로 매우 작습니다. 참조의 링크를 사용하여 환경의 메모리 비율을 계산하는 것을 잊지 마십시오.
-
리소스 풀을 확인하고 데이터베이스를 여기에 바인딩합니다.
EXEC sp_xtp_bind_db_resource_pool 'InMemoryDB', 'Admin_Pool' GO
-
sys.databases에서 바인딩 확인 :
SELECT d.database_id, d.name, d.resource_pool_id FROM sys.databases d GO
-
바인딩을 활성화하려면 데이터베이스를 다시 시작하십시오.
ALTER DATABASE DB_Name SET OFFLINE GO ALTER DATABASE DB_Name SET ONLINE GO
참고 :데이터베이스가 항상 켜져 있는 경우 두 노드에서 단계를 수행하고 4단계(데이터베이스 재시작) 대신 보조 인스턴스로 데이터베이스 장애 조치를 수행합니다.
결론
이 경우 메모리 최적화 테이블이 있는 데이터베이스를 리소스 풀에 추가한 후 메모리 부족과 관련된 모든 경고가 중지되었습니다. 이 특정 문제에 대해 몇 주 동안 SQLServer 오류 로그를 모니터링했지만 메모리 부족에 대한 흔적은 없었습니다. 이러한 단계는 최소한의 다운타임으로 데이터베이스 엔진 수준의 메모리 압력을 수정하는 데 도움이 되었습니다.
피드백 탭을 사용하여 의견을 작성하거나 질문하십시오. 저희와 대화를 시작할 수도 있습니다.