2025년 11월 05일

MSSQL DBCC MEMORYSTATUS 모니터링

Diagram illustrating SQL Server's DBCC MEMORYSTATUS monitoring, showing targets versus current memory usage with indicators for the buffer pool and an out-of-memory (OOM) alert.

1) DBCC MEMORYSTATUS란?

DBCC MEMORYSTATUS는 SQL Server 프로세스 내부 메모리 상태 + OS 관점의 일부 메모리 상태를 한 번에 “스냅샷”으로 출력해주는, 가장 상세한 진단 출력 중 하나입니다. 특히 다음 상황에서 강력합니다.

  • Out-of-Memory(OOM) / “메모리 부족” 계열 오류 원인 추적
  • 메모리 압박이 OS 외부 압박인지, SQL Server 내부 소비(Clerk/Cache) 문제인지 빠른 구분
  • 장애 재현이 어려운 경우 증거(스냅샷) 확보 및 시점 비교

운영 시 주의

  • DBCC MEMORYSTATUS는 진단용 출력이며, 버전/패치/빌드마다 출력 섹션/항목/형식이 바뀔 수 있습니다.
  • 상시 모니터링(Always-on Monitoring) 용도로는 부적합합니다.
    → 상시 관측은 DMV(예: sys.dm_os_memory_clerks) + PerfMon을 기본선으로 두고, 이슈 발생 시 MEMORYSTATUS로 “정밀 스냅샷”을 떠서 합쳐보는 방식이 가장 안정적입니다.

2) 실행 방법

2-1. 가장 간단한 실행

-- SSMS에서 그대로 실행
DBCC MEMORYSTATUS;

2-2. 출력 위치를 명확히 하기 (3604 / 3605)

MEMORYSTATUS 결과는 출력량이 크고, 상황에 따라 “어디로 출력되었는지”가 문제되기도 합니다. 아래 패턴을 표준으로 잡아두면 운영이 편합니다.

(1) 현재 세션(쿼리 창)으로 출력

-- 현재 세션으로 DBCC 출력 보내기
DBCC TRACEON(3604);
DBCC MEMORYSTATUS;
DBCC TRACEOFF(3604);

(2) SQL Server Error Log로 남기기(전역) — “증거 수집”에 최적

-- 에러 로그로 남기기(전역): 재현/증거 수집에 유용
DBCC TRACEON(3605, -1);
DBCC MEMORYSTATUS;
DBCC TRACEOFF(3605, -1);

Trace Flag 의미

  • 3604: DBCC 결과를 현재 세션(SSMS 결과 창)으로 출력
  • 3605: DBCC 결과를 SQL Server Error Log에 기록
  • -1: 전역(Global) 범위 적용

운영 팁

  • 장애 분석/감사/리포트 목적이면 3605 + 에러 로그 기록이 “재현 불가” 상황에서 특히 유리합니다.
  • 전역 플래그는 영향 범위를 반드시 인지하고, 캡처 후 즉시 OFF하는 습관을 권장합니다.

2-3. 자동/반복 수집이 필요할 때 (PowerShell / dbatools)

DBCC MEMORYSTATUS는 결과가 구조화되지 않아, 그대로 저장/비교하기가 까다롭습니다. 자동 수집이 필요하면 dbatools 기반이 실무 난이도가 낮습니다.

# 관리자 PowerShell
Install-Module dbatools -Scope CurrentUser

Get-DbaDbccMemoryStatus -SqlInstance "MyServer\SQL2022" |
  Export-Csv "C:\logs\memorystatus.csv" -NoTypeInformation
  • dbatools는 MEMORYSTATUS 출력을 파싱해 객체 형태로 제공하므로,
    시점별 비교/아카이빙/리포팅 자동화에 유리합니다.

권한 팁

  • 운영 환경에서는 “진단 명령”의 실행/수집 권한을 통제하는 것이 일반적입니다.
  • 상시 모니터링은 DMV/PerfMon 중심으로 구성하고, MEMORYSTATUS는 이슈 시점에만 캡처하는 전략이 안전합니다.

3) 출력 해석 핵심 4가지

MEMORYSTATUS는 정보가 매우 많습니다. 아래 4가지를 “순서대로” 집요하게 보면, 대부분의 메모리 이슈는 방향이 잡힙니다.

① 외부(OS) vs 내부(SQL) 메모리 압박 구분

(1) Process/System Counts 계열

  • System physical memory low = 1
    → OS 레벨에서 물리 메모리가 부족하다는 신호(다른 프로세스, OS 캐시/버퍼, VM Ballooning 등 포함)
  • Process physical memory low = 1
    → SQL Server 프로세스(또는 프로세스 전체) 관점에서 물리 메모리 압박 신호

(2) Memory Manager 계열

  • Target Committed ↔ Current Committed 비교가 핵심입니다.
  • Current ≪ Target : 아직 여유 / 더 사용할 여지가 있음
  • Current ≈ Target : 목표에 근접 / 내부 압박 가능성 증가

(3) Locked Pages 관련(환경에 따라)

  • Locked Pages Allocated가 크다면, LPIM(Lock Pages in Memory) 적용 여부/효과도 함께 고려합니다.
    (단, LPIM은 “무조건 좋다”가 아니라 운영 정책/메모리 압박 형태에 따라 판단이 달라집니다.)
A gauge illustrating the difference between Target Committed and Current Committed memory in SQL Server, with indicators for plenty of headroom, near target, and pressure.

② NUMA별 메모리 노드 분포 확인

NUMA 환경이라면 MEMORYSTATUS에서 Memory node Id = n 섹션을 확인합니다.

  • 노드별 Current/Target Committed가 비정상적으로 쏠리는지
  • 특정 노드에서만 압박 신호가 나타나는지

운영에서는 보통 다음 순서로 봅니다.
1) …Total (전체 합계)로 큰 그림 확인
2) 노드별 분포로 “쏠림/편차” 점검


③ Buffer Pool(데이터/인덱스 캐시) 상태

버퍼풀은 OLTP 성능과 직결되는 핵심입니다. 아래 포인트만 먼저 봐도 충분합니다.

  • Database(캐시 크기)
  • Dirty(더티 페이지)
  • In IO(I/O 진행 중)
  • Page Life Expectancy(PLE)(버퍼 재사용 압박의 대표 신호)
  • Target(버퍼풀 목표)

해석 힌트

  • Dirty ↑ + In IO ↑
    → 체크포인트/쓰기 지연/스토리지 병목 의심
  • PLE 급락
    → 버퍼 재활용 급증(대량 스캔, 읽기 폭증, 내부 메모리 압박 가능)

PLE는 “절대값”보다 “평소 베이스라인 대비 급락/지속”을 더 중요하게 보세요.


④ Memory Clerk / CacheStore 상위 소비자 파악

MEMORYSTATUS에서 다음 계열의 Pages Allocated(또는 유사 지표) 상위가 누구인지 먼저 봅니다.

  • MEMORYCLERK_*
  • CACHESTORE_*
  • USERSTORE_*
  • OBJECTSTORE_*

이때 가장 중요한 질문은 하나입니다.

“누가 메모리를 먹고 있는가?”

그리고 반드시 DMV로 교차검증합니다(정렬/집계가 훨씬 쉬움).

-- 상위 메모리 소비자(Clerk) TOP 10
SELECT TOP (10)
       type,
       SUM(pages_kb) AS pages_kb
FROM sys.dm_os_memory_clerks
GROUP BY type
ORDER BY SUM(pages_kb) DESC;
A bar chart showing the top memory consumers labeled as Clerk, CacheStore, UserStore, and ObjectStore, with corresponding percentage values indicating their memory usage and an arrow highlighting the 80/20 line.

4) 문제 유형별 빠른 체크리스트(실무용)

A. 외부(OS) 압박이 의심될 때

징후

  • System physical memory low = 1
  • OS에서 Available Memory 급락, 다른 프로세스 메모리 급증

즉시 조치 방향

  • DB 서버에서 함께 돌아가는 불필요 서비스/에이전트/백신 실시간 스캔 정책 점검
  • VM 환경이면 Ballooning/Overcommit/Host 압박 여부 점검
  • 장기적으로 RAM 증설 또는 워크로드 분리(ETL/배치 분리) 검토

B. 내부(SQL) 압박이 의심될 때

징후

  • Current Committed ≈ Target Committed
  • 특정 Clerk/CacheStore가 비정상적으로 상위 고착

즉시 조치 방향

  • 상위 소비자(Clerk/Cache)를 “원인 후보”로 두고 추가 진단
  • 컴파일 폭주/플랜 캐시 비대, 대량 정렬/해시(Memory Grant) 폭증 여부 점검
  • 필요한 경우 “쿼리/인덱스/통계/파라미터 스니핑/메모리 그랜트” 관점으로 튜닝 전개

C. 버퍼풀 급락/PLE 저하가 뚜렷할 때

징후

  • PLE ↓, In IO ↑, Dirty ↑ (조합으로 나타나는 경우가 많음)

즉시 조치 방향

  • 대량 스캔 유발 쿼리(리포트/배치) 유입 여부 확인
  • 데이터/로그 I/O 지연 확인(스토리지 성능, 파일 배치, 체크포인트 패턴)
  • OLTP 시스템이면 “핫 데이터” 접근 쿼리의 인덱스/커버링/필터드 인덱스 검토

D. 증거 확보가 최우선인 상황(재현 불가/간헐적 OOM)

권장 패턴

  • 사건 발생 직후(또는 발생 중) 3605로 에러 로그에 MEMORYSTATUS 캡처
  • 동일 시점에 아래 “보조 스냅샷 DMV”도 함께 저장(표준 런북화 권장)

5) MEMORYSTATUS와 함께 보면 좋은 “보조 스냅샷 DMV”

MEMORYSTATUS는 “전체 그림”에 강하고, DMV는 “정렬/집계/자동화”에 강합니다. 아래는 실무에서 같이 묶어두면 좋은 최소 세트입니다.

5-1. OS/프로세스 메모리 상태(요약)

-- OS 메모리 요약
SELECT *
FROM sys.dm_os_sys_memory;

-- SQL Server 프로세스 메모리 요약
SELECT *
FROM sys.dm_os_process_memory;

5-2. 메모리 그랜트(정렬/해시 등) 폭증 여부

SELECT TOP (20)
       session_id,
       requested_memory_kb,
       granted_memory_kb,
       used_memory_kb,
       max_used_memory_kb,
       wait_time_ms,
       grant_time
FROM sys.dm_exec_query_memory_grants
ORDER BY requested_memory_kb DESC;

5-3. 버퍼풀 분포(데이터베이스별 캐시 점유)

SELECT TOP (20)
       DB_NAME(database_id) AS database_name,
       COUNT(*) * 8 / 1024 AS buffer_pool_mb
FROM sys.dm_os_buffer_descriptors
GROUP BY database_id
ORDER BY buffer_pool_mb DESC;

팁

  • MEMORYSTATUS로 “이상 징후”를 잡고
  • DMV로 “상위 소비자/상위 쿼리/상위 DB”를 좁혀가는 흐름이 가장 빠릅니다.

6) FAQ

Q1. 운영 서버에서 실행해도 되나요?

A. 일반적으로 스냅샷 출력이라 큰 부하는 드뭅니다. 다만 출력량이 크고, 상황에 따라 결과 수집(특히 로그 기록)이 부담이 될 수 있으니 필요 시점에만 실행하는 것을 권장합니다.

Q2. DMV랑 뭐가 다른가요?

A. DMV는 지속 관측/자동화에 강하고, MEMORYSTATUS는 한 번에 전체 구조를 스냅샷으로 확인하는 데 강합니다. 두 방법을 합쳐서 교차검증하면 가장 확실합니다.

Q3. OOM 나면 자동으로 남나요?

A. 일부 메모리 관련 오류는 SQL Server Error Log에 MEMORYSTATUS 출력이 함께 기록되는 경우가 있습니다. 재현이 어려운 장애는 3605로 로그 캡처를 표준화해 두면 분석 속도가 크게 올라갑니다.


7) 결론 & 실전 팁

  • 가장 먼저: 외부(OS) 압박인지 내부(SQL) 압박인지부터 구분하세요.
  • 핵심만 빠르게: Target vs Current, Buffer Pool·PLE, Top Clerk/Cache 3줄로 방향이 잡힙니다.
  • 증거 수집: 재현이 어렵다면 DBCC TRACEON(3605, -1)로 에러 로그 캡처를 남겨 시점 비교 기반을 만드세요.
  • 상시 관측선: DMV/PerfMon을 기본으로, 이슈 시점에 MEMORYSTATUS로 정밀 스냅샷을 떠서 합쳐보는 운영이 가장 안전합니다.

참고 쿼리/스크립트 모음

-- 1) MEMORYSTATUS 스냅샷
DBCC MEMORYSTATUS;

-- 2) 현재 세션으로 결과 출력
DBCC TRACEON(3604);
DBCC MEMORYSTATUS;
DBCC TRACEOFF(3604);

-- 3) 에러 로그로 남기기(전역) - 재현/증거 수집
DBCC TRACEON(3605, -1);
DBCC MEMORYSTATUS;
DBCC TRACEOFF(3605, -1);

-- 4) 상위 메모리 소비자(Clerk) TOP 10
SELECT TOP (10) type, SUM(pages_kb) AS pages_kb
FROM sys.dm_os_memory_clerks
GROUP BY type
ORDER BY SUM(pages_kb) DESC;

-- 5) OS/프로세스 메모리 요약(보조 스냅샷)
SELECT * FROM sys.dm_os_sys_memory;
SELECT * FROM sys.dm_os_process_memory;

-- 6) 메모리 그랜트(정렬/해시) 확인
SELECT TOP (20)
       session_id,
       requested_memory_kb,
       granted_memory_kb,
       used_memory_kb,
       max_used_memory_kb,
       wait_time_ms,
       grant_time
FROM sys.dm_exec_query_memory_grants
ORDER BY requested_memory_kb DESC;