본문 바로가기
WIKI 기술 지식 베이스

SQL Server에서 쿼리 완료 및 쿼리 오류 캡처 구성하기

원문 보기 위키 갱신

이 기능은 Extended Events (XE)를 사용해 SQL Server 인스턴스에서 쿼리 완료 이벤트와 쿼리 오류 이벤트를 수집해요. 다음에 대한 가시성을 제공해요:

  • 파라미터 값이 포함된 SQL 쿼리의 메트릭과 동작
  • 실행 중에 발생한 오류와 타임아웃

다양한 데이터베이스 시스템에서의 쿼리 파라미터 캡처에 대한 정보는 파라미터 값이 포함된 쿼리 캡처 구성하기를 참고하세요.

출처: 문서

본문

이 데이터는 다음에 유용해요:

  • 성능 분석
  • 앱 동작 디버깅
  • 예기치 않은 오류 또는 타임아웃 감사

시작하기 전에

이 가이드를 계속하기 전에 SQL Server 인스턴스에 Database Monitoring을 구성해야 해요.

지원되는 데이터베이스: SQL Server

지원되는 배포 유형: 모든 배포 유형.

지원되는 Agent 버전: 7.67.0+

설정 (Setup)

Azure가 아닌 SQL Server

  1. SQL Server 인스턴스에서 다음 Extended Events (XE) 세션을 만들어요. 이 세션은 인스턴스 내의 어떤 데이터베이스에서든 만들 수 있어요.

datadog_query_completions XE 세션은 RPC 호출, SQL 배치, 저장 프로시저에서 1초가 넘는 장기 실행 SQL 쿼리를 캡처해요.

-- Query completions: RPC, batch, and stored procedure events
IF EXISTS (
    SELECT * FROM sys.server_event_sessions WHERE name = 'datadog_query_completions'
)
    DROP EVENT SESSION datadog_query_completions ON SERVER;
GO

CREATE EVENT SESSION datadog_query_completions ON SERVER -- datadog requires this exact session name
ADD EVENT sqlserver.rpc_completed ( -- capture remote procedure call completions
    ACTION ( -- datadog requires these exact actions for rpc_completed
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.request_id
    )
    WHERE (
        sql_text <> '' AND
        duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
    )
),
ADD EVENT sqlserver.sql_batch_completed( -- capture batch completions
    ACTION ( -- datadog requires these exact actions for sql_batch_completed
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.request_id
    )
    WHERE (
        sql_text <> '' AND
        duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
    )
),
ADD EVENT sqlserver.module_end( -- capture stored procedure completions
    SET collect_statement = (1)
    ACTION ( -- datadog requires these exact actions for module_end
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.request_id
    )
    WHERE (
        sql_text <> '' AND
        duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
    )
)
ADD TARGET package0.ring_buffer -- do not change, datadog is only configured to read from ring buffer at this time
(
  SET MAX_MEMORY = 1024
)
WITH (
    MAX_MEMORY = 1024 KB, -- do not exceed 1024, values above 1 MB may result in data loss due to SQLServer internals
    TRACK_CAUSALITY = ON, -- allows datadog to correlate related events across activity ID
    EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
    MAX_DISPATCH_LATENCY = 30 SECONDS,
    MEMORY_PARTITION_MODE = PER_NODE, -- improves performance on multi-core systems (not supported on RDS)
    STARTUP_STATE = ON
);

ALTER EVENT SESSION datadog_query_completions ON SERVER STATE = START;
GO

datadog_query_errors XE 세션은 severity ≥ 11인 SQL 오류와 쿼리 타임아웃(또는 attention 이벤트라고도 함)을 캡처해서, Datadog가 쿼리 실패와 타임아웃을 보고할 수 있게 해요.

-- Errors and timeouts: SQL errors and attention events
IF EXISTS (
    SELECT * FROM sys.server_event_sessions WHERE name = 'datadog_query_errors'
)
    DROP EVENT SESSION datadog_query_errors ON SERVER;
GO
CREATE EVENT SESSION datadog_query_errors ON SERVER
ADD EVENT sqlserver.error_reported(
    ACTION( -- datadog requires these exact actions for error_reported
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.request_id
    )
    WHERE severity >= 11
),
ADD EVENT sqlserver.attention(
    ACTION( -- datadog requires these exact actions for attention
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.request_id
    )
)
ADD TARGET package0.ring_buffer -- do not change, datadog is only configured to read from ring buffer at this time
(
  SET MAX_MEMORY = 1024
)
WITH (
    MAX_MEMORY = 1024 KB, -- do not change, setting this larger than 1 MB may result in data loss due to SQLServer internals
    EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
    MAX_DISPATCH_LATENCY = 30 SECONDS,
    MEMORY_PARTITION_MODE = PER_NODE, -- improves performance on multi-core systems (not supported on RDS)
    STARTUP_STATE = ON
);

ALTER EVENT SESSION datadog_query_errors ON SERVER STATE = START;
GO

참고: SQL Server용 Amazon RDS를 사용한다면 두 세션 구성 모두에서 MEMORY_PARTITION_MODE = PER_NODE 줄을 제거하세요. 이 옵션은 RDS 인스턴스에서 지원되지 않아요.

Datadog 에이전트 구성에서 sqlserver.d/conf.yaml의 collect_xe를 활성화하세요. 사용 가능한 모든 구성 옵션은 샘플 conf.yaml.example을 참고하세요.

  collect_xe:
    query_completions:
      enabled: true
    query_errors:
      enabled: true

파라미터 값이 포함된 쿼리 문장을 수집하려면 sqlserver.d/conf.yaml에서 collect_raw_query_statement를 활성화하세요. 파라미터 캡처에 대한 자세한 내용은 파라미터 값이 포함된 쿼리 캡처 구성하기를 참고하세요.

  collect_raw_query_statement:
    enabled: true

참고: 원시 쿼리 문장에는 민감한 정보(예: 쿼리 텍스트의 비밀번호)나 개인 식별 정보가 포함될 수 있어요. 이 옵션을 활성화하면 Datadog가 쿼리 샘플에 나타나는 원시 쿼리 문장을 수집하고 인제스트할 수 있게 돼요. 이 옵션은 기본적으로 비활성화되어 있어요.

Azure DB

  1. Azure SQL Server Database에서 다음 Extended Events (XE) 세션을 만들어요:

datadog_query_completions XE 세션은 RPC 호출, SQL 배치, 저장 프로시저에서 1초가 넘는 장기 실행 SQL 쿼리를 캡처해요.

-- Query completions: RPC, batch, and stored procedure events
IF EXISTS (
    SELECT * FROM sys.database_event_sessions WHERE name = 'datadog_query_completions'
)
    DROP EVENT SESSION datadog_query_completions ON DATABASE;
GO

CREATE EVENT SESSION datadog_query_completions ON DATABASE -- datadog requires this exact session name
ADD EVENT sqlserver.rpc_completed ( -- capture remote procedure call completions
    ACTION ( -- datadog requires these exact actions for rpc_completed
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.request_id
    )
    WHERE (
        sql_text <> '' AND
        duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
    )
),
ADD EVENT sqlserver.sql_batch_completed( -- capture batch completions
    ACTION ( -- datadog requires these exact actions for sql_batch_completed
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.request_id
    )
    WHERE (
        sql_text <> '' AND
        duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
    )
),
ADD EVENT sqlserver.module_end( -- capture stored procedure completions
    SET collect_statement = (1)
    ACTION ( -- datadog requires these exact actions for module_end
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.request_id
    )
    WHERE (
        sql_text <> '' AND
        duration > 1000000 -- in microseconds, limit to queries with duration greater than 1 second
    )
)
ADD TARGET package0.ring_buffer -- do not change, datadog is only configured to read from ring buffer at this time
(
  SET MAX_MEMORY = 1024
)
WITH (
    MAX_MEMORY = 1024 KB, -- do not exceed 1024, values above 1 MB may result in data loss due to SQLServer internals
    TRACK_CAUSALITY = ON, -- allows datadog to correlate related events across activity ID
    EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
    MAX_DISPATCH_LATENCY = 30 SECONDS,
    MEMORY_PARTITION_MODE = PER_NODE, -- improves performance on multi-core systems
    STARTUP_STATE = ON
);

ALTER EVENT SESSION datadog_query_completions ON DATABASE STATE = START;
GO

datadog_query_errors XE 세션은 severity ≥ 11인 SQL 오류와 쿼리 타임아웃(또는 attention 이벤트라고도 함)을 캡처해서, Datadog가 쿼리 실패와 타임아웃을 보고할 수 있게 해요.

-- Errors and timeouts: SQL errors and attention events
IF EXISTS (
    SELECT * FROM sys.database_event_sessions WHERE name = 'datadog_query_errors'
)
    DROP EVENT SESSION datadog_query_errors ON DATABASE;
GO
CREATE EVENT SESSION datadog_query_errors ON DATABASE
ADD EVENT sqlserver.error_reported(
    ACTION( -- datadog requires these exact actions for error_reported
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.request_id
    )
    WHERE severity >= 11
),
ADD EVENT sqlserver.attention(
    ACTION( -- datadog requires these exact actions for attention
        sqlserver.sql_text,
        sqlserver.database_name,
        sqlserver.username,
        sqlserver.client_app_name,
        sqlserver.client_hostname,
        sqlserver.session_id,
        sqlserver.request_id
    )
)
ADD TARGET package0.ring_buffer -- do not change, datadog is only configured to read from ring buffer at this time
(
  SET MAX_MEMORY = 1024
)
WITH (
    MAX_MEMORY = 1024 KB, -- do not change, setting this larger than 1 MB may result in data loss due to SQLServer internals
    EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
    MAX_DISPATCH_LATENCY = 30 SECONDS,
    MEMORY_PARTITION_MODE = PER_NODE, -- improves performance on multi-core systems
    STARTUP_STATE = ON
);

ALTER EVENT SESSION datadog_query_errors ON DATABASE STATE = START;
GO

Datadog 에이전트 구성에서 sqlserver.d/conf.yaml의 collect_xe를 활성화하세요. 사용 가능한 모든 구성 옵션은 샘플 conf.yaml.example을 참고하세요.

  collect_xe:
    query_completions:
      enabled: true
    query_errors:
      enabled: true

파라미터 값이 포함된 쿼리 문장을 수집하려면 sqlserver.d/conf.yaml에서 collect_raw_query_statement를 활성화하세요. 파라미터 캡처에 대한 자세한 내용은 파라미터 값이 포함된 쿼리 캡처 구성하기를 참고하세요.

  collect_raw_query_statement:
    enabled: true

참고: 원시 쿼리 문장과 실행 계획에는 민감한 정보(예: 쿼리 텍스트의 비밀번호)나 개인 식별 정보가 포함될 수 있어요. 이 옵션을 활성화하면 Datadog가 쿼리 샘플이나 실행 계획에 나타나는 원시 쿼리 문장과 실행 계획을 수집하고 인제스트할 수 있게 돼요. 이 옵션은 기본적으로 비활성화되어 있어요.

환경에 맞게 Extended Events 튜닝하기 (선택 사항)

Extended Events 세션을 특정 요구사항에 더 잘 맞게 사용자 정의할 수 있어요:

쿼리 지속 시간 임계값

기본 쿼리 지속 시간 임계값은 duration > 1000000(1초)이에요. 이 값을 조정해 얼마나 많은 쿼리를 캡처할지 제어할 수 있어요:

  • 더 많은 쿼리 캡처: 임계값 낮추기(예: 500ms의 경우 duration > 500000)
  • 더 적은 쿼리 캡처: 임계값 높이기(예: 5초의 경우 duration > 5000000)

경고: 임계값을 너무 낮게 설정하면 과도한 이벤트 수집으로 인해 서버 성능에 영향을 주고, 버퍼 오버플로로 인한 이벤트 손실이 발생하며, Datadog가 수집 주기당 가장 최근 1000개 이벤트만 수집하므로 데이터가 불완전해질 수 있어요.

메모리 할당

  • 기본값은 MAX_MEMORY = 1024 KB예요.
  • 1024 KB를 초과하지 마세요. 더 높은 값은 SQL Server 내부 제한으로 인해 데이터 손실을 일으킬 수 있어요.
  • 볼륨이 큰 서버에서는 최대 1024 KB로 유지하는 것이 권장돼요.
  • 트래픽이 낮은 서버에서는 512 KB 설정으로 충분할 수 있어요.

이벤트 필터링

이벤트 볼륨을 줄이려면 WHERE 절에 필터를 추가할 수 있어요. 예를 들어:

WHERE (
    sql_text <> '' AND
    duration > 1000000 AND
    -- Add custom filters here
    database_name = 'YourImportantDB' AND -- Only track specific databases
    username <> 'datadog' -- Exclude Datadog Agent queries or specific users
)

성능 고려 사항

Extended Events는 가볍게 설계되었지만 약간의 오버헤드를 도입할 수 있어요. 성능 문제를 발견하면 다음을 고려하세요:

  • 캡처되는 쿼리를 제한하도록 쿼리 지속 시간 임계값을 높이기.
  • 이벤트 볼륨을 줄이도록 더 구체적인 필터 추가하기.
  • 피크 부하 시간 동안 다음을 실행해 세션 중 하나 또는 둘 다 비활성화하기:
IF EXISTS (
    SELECT * FROM sys.server_event_sessions WHERE name = 'datadog_query_completions'
)
    DROP EVENT SESSION datadog_query_completions ON SERVER;
GO
IF EXISTS (
    SELECT * FROM sys.server_event_sessions WHERE name = 'datadog_query_errors'
)
    DROP EVENT SESSION datadog_query_errors ON SERVER;
GO

Azure 특정 고려 사항

Azure SQL Database 환경은 일반적으로 리소스가 더 제한적이에요. 성능 영향을 최소화하려면:

  • 낮은 서비스 등급을 사용한다면 더 제한적인 필터를 사용하세요.
  • 탄력적 풀(elastic pools)을 사용한다면 모든 데이터베이스에서 성능 영향을 모니터링하세요.

더 알아보기 (Learn more)