다이나믹 테이블 모니터링하기

다이나믹 테이블 모니터링하기

다이나믹 테이블의 메타데이터를 보려면 해당 테이블에 대해 MONITOR 또는 OWNERSHIP 권한이 필요해요. 이 문서에서는 리프레시 상태 확인부터 리프레시 실패 알림까지, Snowflake가 제공하는 여러 가지 모니터링 방법을 상황에 맞게 고르는 법을 알려드릴게요.

출처: Snowflake 문서

본문

다이나믹 테이블의 메타데이터를 조회하려면 해당 테이블에 MONITOR 또는 OWNERSHIP 권한이 있어야 해요.

모니터링 방법 고르기

Snowflake는 여러 모니터링 표면을 제공합니다. 상황에 맞는 방법을 고를 때 다음 표를 활용하세요.

방법 가장 적합한 상황 데이터 보존 기간 설정 노력
SHOW DYNAMIC TABLES 빠른 상태 확인, 리프레시 모드와 웨어하우스 보기 현재 스냅샷 없음
INFORMATION_SCHEMA.DYNAMIC_TABLES() 플릿(Fleet) 전반의 상태, lag 메트릭, 마지막 리프레시 결과 7일 없음
INFORMATION_SCHEMA.DYNAMIC_TABLE_REFRESH_HISTORY() 리프레시별 진단: 상태, 오류, 지속 시간, 트리거 7일 없음
DYNAMIC_TABLE_REFRESH_HISTORY 계정 사용 뷰 7일이 넘는 기간의 추세 분석 365일 없음
INFORMATION_SCHEMA.DYNAMIC_TABLE_GRAPH_HISTORY() 파이프라인 의존성 스냅샷과 토폴로지 변경 7일 없음
Event table + alerts 자동화된 장애 알림 구성 가능 중간
Pipeline spans 파이프라인 수준 추적 및 근본 원인 분석 구성 가능 중간

빠르고 임시적인 확인을 위해서는 SHOW DYNAMIC TABLES나 DYNAMIC_TABLES 테이블 함수로 시작하는 게 좋아요. 리프레시 실패에 대한 자동화된 알림이 필요하면 event table alert를 설정하고, 7일이 넘는 기간의 이력 분석이 필요하면 Account Usage 뷰를 사용하세요.

리프레시 상태 확인하기

SHOW DYNAMIC TABLES로 상태 확인하기

SHOW DYNAMIC TABLES는 리프레시 모드, 웨어하우스, 스케줄링 상태, 마지막 데이터 타임스탬프 등 다이나믹 테이블의 현재 상태를 반환해요. refresh_mode, refresh_mode_reason, warehouse 컬럼의 유일한 공급원입니다.

SHOW DYNAMIC TABLES LIKE 'dt_%' IN SCHEMA mydb.myschema;
+---------------------------+------------+---------------+-------------+------+-------+----------+------------+--------------+---------------------+--------------+---------+------+---------------------------+
| CREATED_ON                | NAME       | DATABASE_NAME | SCHEMA_NAME | ROWS | BYTES | OWNER    | TARGET_LAG | REFRESH_MODE | REFRESH_MODE_REASON | WAREHOUSE    | COMMENT | TEXT | SCHEDULING_STATE          |
|---------------------------+------------+---------------+-------------+------+-------+----------+------------+--------------+---------------------+--------------+---------+------+---------------------------|
| 2025-01-15 08:32:28 +0000 | DT_ORDERS  | MY_DB         | MY_SCHEMA   |    4 |  2048 | ORGADMIN | 10 minutes | INCREMENTAL  | NULL                | TRANSFORM_WH |         |  ... | RUNNING                   |
+---------------------------+------------+---------------+-------------+------+-------+----------+------------+--------------+---------------------+--------------+---------+------+---------------------------+

Note SHOW DYNAMIC TABLES는 스케줄링 상태 값으로 RUNNING과 SUSPENDED를 사용해요. DYNAMIC_TABLE_GRAPH_HISTORY 함수는 대신 ACTIVE와 SUSPENDED를 사용합니다. 두 라벨 모두 같은 운영 상태를 가리켜요.

DYNAMIC_TABLES 함수로 플릿 상태 확인하기

DYNAMIC_TABLES 함수는 계정 안 모든 다이나믹 테이블의 lag 메트릭과 마지막 리프레시 결과를 반환해요. 신선도(freshness) 목표를 달성하지 못하는 테이블을 찾는 데 유용합니다.

SELECT
  name,
  database_name,
  schema_name,
  scheduling_state,
  last_completed_refresh_state,
  target_lag_sec,
  time_within_target_lag_ratio,
  maximum_lag_sec
FROM TABLE(INFORMATION_SCHEMA.DYNAMIC_TABLES())
ORDER BY name;
+--------------------+---------------+-------------+--------------------+-------------------------------+----------------+-------------------------------+-----------------+
| NAME               | DATABASE_NAME | SCHEMA_NAME | SCHEDULING_STATE   | LAST_COMPLETED_REFRESH_STATE  | TARGET_LAG_SEC | TIME_WITHIN_TARGET_LAG_RATIO  | MAXIMUM_LAG_SEC |
|--------------------+---------------+-------------+--------------------+-------------------------------+----------------+-------------------------------+-----------------|
| DT_ORDERS_DAILY    | MY_DB         | MY_SCHEMA   | {"state":"RUNNING"}| SUCCEEDED                     |           1800 |                         0.999 |             125 |
| DT_ORDERS          | MY_DB         | MY_SCHEMA   | {"state":"RUNNING"}| SUCCEEDED                     |            600 |                         0.998 |              42 |
+--------------------+---------------+-------------+--------------------+-------------------------------+----------------+-------------------------------+-----------------+

time_within_target_lag_ratio가 0.90보다 낮으면, 그 다이나믹 테이블이 대부분의 시간 동안 신선도 목표를 지키지 못하고 있다는 뜻이에요. 리프레시 히스토리를 조사하고 target lag나 웨어하우스 크기 조정을 고려해 보세요.

리프레시별 히스토리 보기

DYNAMIC_TABLE_REFRESH_HISTORY 함수는 리프레시마다 한 행씩, 결과, 오류 세부 정보, 지속 시간, 트리거를 반환해요. 특정 실패를 조사하거나 리프레시 추세를 추적할 때 사용합니다.

SELECT
  name,
  state,
  state_code,
  state_message,
  refresh_action,
  refresh_trigger,
  data_timestamp,
  refresh_start_time,
  refresh_end_time,
  DATEDIFF('second', refresh_start_time, refresh_end_time) AS duration_sec
FROM TABLE(INFORMATION_SCHEMA.DYNAMIC_TABLE_REFRESH_HISTORY(NAME_PREFIX => 'MY_DB.MY_SCHEMA'))
ORDER BY data_timestamp DESC
LIMIT 10;
+--------------------+-----------------+------------------------------+----------------------------------------------------------------+-----------------+-----------------+---------------------+-------------------------+-------------------------+--------------+
| NAME               | STATE           | STATE_CODE                   | STATE_MESSAGE                                                  | REFRESH_ACTION  | REFRESH_TRIGGER | DATA_TIMESTAMP      | REFRESH_START_TIME      | REFRESH_END_TIME        | DURATION_SEC |
|--------------------+-----------------+------------------------------+----------------------------------------------------------------+-----------------+-----------------+---------------------+-------------------------+-------------------------+--------------|
| DT_ORDERS          | SUCCEEDED       |                              |                                                                | INCREMENTAL     | SCHEDULED       | 2025-04-12 09:01:30 | 2025-04-12 09:01:30     | 2025-04-12 09:01:36     |            6 |
| DT_ORDERS_DAILY    | SUCCEEDED       |                              |                                                                | INCREMENTAL     | SCHEDULED       | 2025-04-12 09:01:36 | 2025-04-12 09:01:36     | 2025-04-12 09:01:48     |           12 |
| DT_ORDERS          | FAILED          | 100038                       | Numeric value 'Good' is not recognized.                        | INCREMENTAL     | SCHEDULED       | 2025-04-12 09:00:00 | 2025-04-12 09:00:00     | 2025-04-12 09:00:05     |            5 |
| DT_ORDERS_DAILY    | UPSTREAM_FAILED | UPSTREAM_FAILURE             | Skipped refreshing because an input dynamic table failed.      | NO_DATA         | SCHEDULED       | 2025-04-12 09:00:00 | 2025-04-12 09:00:05     | 2025-04-12 09:00:05     |            0 |
+--------------------+-----------------+------------------------------+----------------------------------------------------------------+-----------------+-----------------+---------------------+-------------------------+-------------------------+--------------+

실패한 리프레시만 걸러내려면 ERROR_ONLY => TRUE를 넘기면 돼요.

SELECT
  name,
  state,
  state_code,
  state_message,
  data_timestamp
FROM TABLE(INFORMATION_SCHEMA.DYNAMIC_TABLE_REFRESH_HISTORY(NAME_PREFIX => 'MY_DB.MY_SCHEMA', ERROR_ONLY => TRUE))
ORDER BY data_timestamp DESC;
+--------------------+-----------------+------------------------------+----------------------------------------------------------------+---------------------+
| NAME               | STATE           | STATE_CODE                   | STATE_MESSAGE                                                  | DATA_TIMESTAMP      |
|--------------------+-----------------+------------------------------+----------------------------------------------------------------+---------------------|
| DT_ORDERS          | FAILED          | 100038                       | Numeric value 'Good' is not recognized.                        | 2025-04-12 09:00:00 |
| DT_ORDERS_DAILY    | UPSTREAM_FAILED | UPSTREAM_FAILURE             | Skipped refreshing because an input dynamic table failed.      | 2025-04-12 09:00:00 |
+--------------------+-----------------+------------------------------+----------------------------------------------------------------+---------------------+

Important DYNAMIC_TABLE_REFRESH_HISTORY 테이블 함수는 데이터를 7일간 보관해요. 7일이 지난 실패를 조사하거나 추세 분석이 필요하면 365일간 보관하는 DYNAMIC_TABLE_REFRESH_HISTORY Account Usage 뷰를 조회하세요.

DYNAMIC_TABLE_GRAPH_HISTORY로 파이프라인 상태 모니터링하기

DYNAMIC_TABLE_GRAPH_HISTORY 함수는 상위 입력(upstream inputs), 스케줄링 상태, target lag을 포함한 다이나믹 테이블의 의존성 그래프를 반환해요. 파이프라인 토폴로지를 이해하고 시간에 따른 구성 변경을 감지하는 데 씁니다.

SELECT
  name,
  scheduling_state,
  target_lag_sec,
  target_lag_type,
  inputs,
  valid_from,
  valid_to
FROM TABLE(INFORMATION_SCHEMA.DYNAMIC_TABLE_GRAPH_HISTORY(NAME => 'MY_DB.MY_SCHEMA.DT_ORDERS_DAILY'))
ORDER BY valid_from DESC;
+--------------------+------------------+----------------+-----------------+-------------------------------+-------------------------+-------------------------+
| NAME               | SCHEDULING_STATE | TARGET_LAG_SEC | TARGET_LAG_TYPE | INPUTS                        | VALID_FROM              | VALID_TO                |
|--------------------+------------------+----------------+-----------------+-------------------------------+-------------------------+-------------------------|
| DT_ORDERS_DAILY    | ACTIVE           |           1800 | USER_DEFINED    | ["MY_DB.MY_SCHEMA.DT_ORDERS"] | 2025-04-10 08:00:00     | NULL                    |
+--------------------+------------------+----------------+-----------------+-------------------------------+-------------------------+-------------------------+

각 행은 다이나믹 테이블 속성의 스냅샷을 나타내요. 속성(예: target lag)을 변경하면 업데이트된 valid_from 타임스탬프를 가진 새 행이 생기고, 이전 행에는 valid_to 값이 채워집니다.

파이프라인의 전체 의존성 트리를 보려면 주어진 테이블을 inputs 배열에 포함하는 모든 다이나믹 테이블을 조회하세요.

SELECT
  name,
  inputs,
  scheduling_state,
  target_lag_sec
FROM TABLE(INFORMATION_SCHEMA.DYNAMIC_TABLE_GRAPH_HISTORY())
WHERE name = 'MY_DB.MY_SCHEMA.DT_ORDERS_DAILY'
  OR ARRAY_CONTAINS('MY_DB.MY_SCHEMA.DT_ORDERS_DAILY'::VARIANT, inputs);
+----------------------------------+-------------------------------+------------------+----------------+
| NAME                             | INPUTS                        | SCHEDULING_STATE | TARGET_LAG_SEC |
|----------------------------------+-------------------------------+------------------+----------------|
| MY_DB.MY_SCHEMA.DT_ORDERS_DAILY  | ["MY_DB.MY_SCHEMA.DT_ORDERS"] | ACTIVE           |           1800 |
+----------------------------------+-------------------------------+------------------+----------------+

Snowsight에서 파이프라인 그래프 보기

Snowsight에서 lineage 그래프는 상위/하위 의존성을 시각화해 줘요.

  1. Snowsight에 로그인하세요.
  2. Transformation » Dynamic tables를 선택하세요.
  3. 다이나믹 테이블을 선택하세요. Graph 뷰가 기본 표시됩니다.
  4. 그래프에서 다이나믹 테이블을 선택하면 Details(세부 정보) 창에서 lag 메트릭과 구성을 볼 수 있어요.

리프레시가 UPSTREAM_FAILED 상태로 실패했다면, 그래프가 실패를 일으킨 상위 다이나믹 테이블을 강조 표시해 줍니다.

ACCESS_HISTORY의 다이나믹 테이블

다이나믹 테이블 리프레시 작업은 ACCESS_HISTORY 뷰에 기록됩니다.

  • 리프레시 읽기: 리프레시 중 읽히는 베이스 테이블이 base_objects_accessed 필드에 나타나요.
  • 리프레시 쓰기: 리프레시 중인 다이나믹 테이블은 object_modified_by_ddl에 dynamicTableAction = 'REFRESH'인 DDL ALTER 작업으로 나타나요.
  • 사용자 조회: 다이나믹 테이블에 대한 SELECT 쿼리는 표준 테이블 액세스로 기록돼요.

Event table로 알림 설정하기

다이나믹 테이블이 리프레시되면 Snowflake가 활성 event table에 refresh.status 이벤트를 기록할 수 있어요. event table을 모니터링하고 리프레시 실패 시 알림을 보내는 alert를 만들 수 있습니다.

Note 다이나믹 테이블용 로깅 이벤트는 비용이 발생해요. 텔레메트리 데이터 수집 비용을 참고하세요.

이벤트 심각도 레벨 설정하기

이벤트가 캡처되려면 먼저 LOG_EVENT_LEVEL 파라미터를 설정해야 해요. 설정하지 않으면 어떤 이벤트도 기록되지 않습니다.

이벤트는 다음 레벨로 캡처됩니다.

  • <C>ERROR</C>: 리프레시 실패 이벤트만.
  • <C>WARN</C>: 리프레시 실패 및 상위(upstream) 실패 이벤트.
  • <C>INFO</C>: 성공을 포함한 모든 리프레시 이벤트.

계정, 데이터베이스, 스키마, 또는 특정 다이나믹 테이블에 레벨을 설정할 수 있어요. 예를 들어 <C>ALTER DYNAMIC TABLE dt_orders SET LOG_EVENT_LEVEL = WARN</C>를 실행하면 특정 테이블의 WARN/ERROR 이벤트를 캡처하고, <C>ALTER DATABASE mydb SET LOG_EVENT_LEVEL = INFO</C>는 데이터베이스 안 모든 지원 객체의 모든 이벤트를 캡처합니다.

Important LOG_EVENT_LEVEL을 데이터베이스, 스키마, 계정 수준에 설정하면 다이나믹 테이블뿐 아니라 이벤트 로깅을 지원하는 모든 객체 유형(다이나믹 테이블, 저장 프로시저, UDF, 태스크)에 영향을 줘요.

Event table 조회하기

심각도 레벨을 설정한 뒤 event table을 조회해 리프레시 이벤트를 확인하세요. <C>resource_attributes:"snow.executable.type" = 'DYNAMIC_TABLE'</C>로 필터링해 다이나믹 테이블 이벤트만 분리할 수 있어요.

SELECT
  timestamp,
  resource_attributes:"snow.executable.name"::VARCHAR AS dt_name,
  resource_attributes:"snow.query.id"::VARCHAR AS query_id,
  record:"severity_text"::VARCHAR AS severity,
  value:state::VARCHAR AS state,
  value:message::VARCHAR AS error_message
FROM my_event_table
WHERE
  resource_attributes:"snow.executable.type" = 'DYNAMIC_TABLE'
  AND resource_attributes:"snow.database.name" = 'MY_DB'
  AND record:"name" = 'refresh.status'
  AND value:state = 'FAILED'
ORDER BY timestamp DESC;
+-------------------------+------------+--------------------------------------+----------+--------+---------------------------------------------------------------------------------+
| TIMESTAMP               | DT_NAME    | QUERY_ID                             | SEVERITY | STATE  | ERROR_MESSAGE                                                                   |
|-------------------------+------------+--------------------------------------+----------+--------+---------------------------------------------------------------------------------|
| 2025-02-17 21:40:45.444 | DT_ORDERS  | 01ba7614-0107-e56c-0000-a995024f304a | ERROR    | FAILED | SQL compilation error:                                                          |
|                         |            |                                      |          |        | Object 'MY_DB.MY_SCHEMA.RAW_ORDERS' does not exist or not authorized.           |
+-------------------------+------------+--------------------------------------+----------+--------+---------------------------------------------------------------------------------+

상위(upstream) 실패를 조회하려면 필터를 value:state = 'UPSTREAM_FAILURE'로 바꾸세요. (event table은 UPSTREAM_FAILURE를, DYNAMIC_TABLE_REFRESH_HISTORY 함수는 UPSTREAM_FAILED를 사용해요.)

리프레시 실패 alert 만들기

새 데이터에 대한 alert(new data)는 조건에 일치하는 새 행이 event table에 삽입될 때 트리거돼요. 다음 예시는 mydb에 있는 다이나믹 테이블이 리프레시에 실패하면 Slack 알림을 보냅니다.

Note 새 데이터 alert를 만들려면 event table을 조회할 수 있는 권한이 필요한 역할을 써야 해요.

다이나믹 테이블 리프레시 실패 시 실행되는 alert를 만들려면 Snowflake alerts 기능과 event table에 대한 조건 쿼리를 사용하세요. <C>resource_attributes:"snow.executable.type" = 'DYNAMIC_TABLE'</C>과 <C>record:"severity_text" = 'ERROR'</C>로 필터링해 실패를 감지한 뒤(Slack 통합 등으로) 알림을 보냅니다. alert 생성 문법, 스케줄링 옵션, 알림 통합 설정은 알림 설정하기를 참고하세요.

Note event table의 timestamp 컬럼은 UTC 값을 저장해요. 새 데이터 alert 대신 타임스탬프 필터를 가진 스케줄된 alert를 쓴다면, 현재 타임스탬프를 UTC로 변환하세요:

timestamp > DATEADD('minute', -5, CONVERT_TIMEZONE('UTC', CURRENT_TIMESTAMP()))

Event table 컬럼 레퍼런스

다이나믹 테이블이 리프레시되면 다음 값을 가진 행이 event table에 삽입됩니다.

주요 컬럼
컬럼 데이터 타입 설명
timestamp TIMESTAMP_NTZ 이벤트가 생성된 UTC 타임스탬프.
observed_timestamp TIMESTAMP_NTZ 현재는 timestamp와 동일.
resource_attributes OBJECT 다이나믹 테이블을 식별하는 속성. resource_attributes의 키-값 쌍 참고.
record_type STRING 다이나믹 테이블 리프레시의 경우 EVENT.
record OBJECT 리프레시 상태에 대한 세부 정보. record의 키-값 쌍 참고.
value VARIANT 리프레시 상태와, 실패 시 오류 메시지. value의 키-값 쌍 참고.
resource_attributes의 키-값 쌍
속성 타입 설명 예시
snow.database.name VARCHAR 다이나믹 테이블이 있는 데이터베이스. MY_DB
snow.schema.name VARCHAR 다이나믹 테이블이 있는 스키마. MY_SCHEMA
snow.executable.name VARCHAR 다이나믹 테이블 이름. DT_ORDERS
snow.executable.type VARCHAR 객체 유형. 이 이벤트에서는 항상 DYNAMIC_TABLE. DYNAMIC_TABLE
snow.query.id VARCHAR 리프레시의 쿼리 ID. 01ba7614-0107-e56c-0000-a995024f304a
snow.warehouse.name VARCHAR 리프레시에 사용된 웨어하우스. TRANSFORM_WH
snow.owner.name VARCHAR 다이나믹 테이블에 OWNERSHIP이 있는 역할. DATA_ADMIN
snow.owner.type VARCHAR 객체를 소유한 역할의 유형. 예: ROLE. Snowflake Native App이 객체를 소유하면 값은 APPLICATION. 삭제된 객체는 소유자 역할이 없으므로 Snowflake는 NULL을 반환. ROLE
snow.database.id INTEGER 데이터베이스의 내부 ID. 12345
snow.schema.id INTEGER 스키마의 내부 ID. 12345
snow.executable.id INTEGER 다이나믹 테이블의 내부 ID. 12345
snow.owner.id INTEGER 소유자 역할의 내부 ID. 12345
snow.warehouse.id INTEGER 웨어하우스의 내부 ID. 12345
record의 키-값 쌍
키 타입 설명 예시
name VARCHAR 이벤트 이름. 다이나믹 테이블 리프레시에서는 항상 refresh.status. refresh.status
severity_text VARCHAR INFO(리프레시 성공), ERROR(리프레시 실패), WARN(상위 다이나믹 테이블 실패). ERROR
value의 키-값 쌍
키 타입 설명 예시
state VARCHAR SUCCEEDED, FAILED, 또는 UPSTREAM_FAILURE. FAILED
message VARCHAR state가 FAILED일 때의 오류 메시지. 그 외에는 NULL. SQL compilation error: Object does not exist.

Span으로 파이프라인 추적하기

이벤트 외에도 Snowflake는 다이나믹 테이블 리프레시에 대한 pipeline span을 기록할 수 있어요. 이벤트는 개별 리프레시 결과를 기록하지만, span은 파이프라인 수준의 컨텍스트(상관 trace ID, skip 이유, 의존성 토폴로지)를 추가해 줍니다. span은 이벤트가 발행되지 않는 상태도 캡처하는데, 예를 들어 상위 skip이나 스케줄러 부하 분산으로 인한 SKIPPED 리프레시가 그렇습니다.

Note 다이나믹 테이블용 span 기록은 비용이 발생해요. 텔레메트리 데이터 수집 비용을 참고하세요.

Pipeline spans 활성화하기

스키마 또는 데이터베이스 레벨에서 TRACE_LEVEL 파라미터를 <C>ALWAYS</C>로 설정하세요. 예: <C>ALTER SCHEMA mydb.myschema SET TRACE_LEVEL = 'ALWAYS'</C>.

Span 데이터 조회하기

record_type = 'SPAN'이고 record:"name" = 'table_refresh'인 행으로 필터링하세요.

SELECT
  resource_attributes:"snow.executable.name"::STRING AS dt_name,
  record_attributes:"snow.dynamic_table.state"::STRING AS state,
  record_attributes:"snow.dynamic_table.state_reason"::STRING AS state_reason,
  record_attributes:"snow.dynamic_table.data_timestamp"::STRING AS data_timestamp,
  trace:"trace_id"::STRING AS trace_id,
  trace:"span_id"::STRING AS span_id,
  record:"status":"code"::STRING AS status_code
FROM my_event_table
WHERE record_type = 'SPAN'
  AND record:"name" = 'table_refresh'
ORDER BY start_timestamp ASC;
+------------+-----------+-----------------+-------------------------+-----------------------------------+----------+-------------------+
| DT_NAME    | STATE     | STATE_REASON    | DATA_TIMESTAMP          | TRACE_ID                          | SPAN_ID  | STATUS_CODE       |
|------------+-----------+-----------------+-------------------------+-----------------------------------+----------+-------------------|
| DT_ORDERS  | SUCCEEDED | NULL            | 2026-02-13T10:00:00.000 | abc123def456abc123def456abc12345  | f1e2d3c4 | STATUS_CODE_OK    |
| DT_CUSTOMERS | SUCCEEDED | NULL            | 2026-02-13T10:00:00.000 | abc123def456abc123def456abc12345  | b5a6c7d8 | STATUS_CODE_OK    |
| DT_ENRICHED | FAILED    | QUERY_FAILURE   | 2026-02-13T10:00:00.000 | abc123def456abc123def456abc12345  | a1b2c3d4 | STATUS_CODE_ERROR |
| DT_SUMMARY | SKIPPED   | UPSTREAM_FAILURE| 2026-02-13T10:00:00.000 | abc123def456abc123def456abc12345  | c9d0e1f2 | STATUS_CODE_ERROR |
+------------+-----------+-----------------+-------------------------+-----------------------------------+----------+-------------------+
Span 속성(record_attributes)
속성 타입 설명
snow.dynamic_table.state STRING SUCCEEDED, FAILED, 또는 SKIPPED.
snow.dynamic_table.state_reason STRING 리프레시가 skip되거나 실패한 이유. 성공 시 NULL. 값: QUERY_FAILURE, UPSTREAM_FAILURE, UPSTREAM_SKIP, NOT_EFFECTIVE_TICK_TO_REFRESH.
snow.dynamic_table.data_timestamp STRING 리프레시가 평가된 transactional 타임스탬프. 이 타임스탬프 이전에 베이스 테이블에 도착한 모든 데이터가 다이나믹 테이블에 포함됩니다.

파이프라인 전반의 span 상관시키기

리프레시 사이클에 여러 다이나믹 테이블이 포함되면 모든 span이 동일한 trace:"trace_id"를 공유해요. 각 span은 또한 각 상위 의존성의 span_id를 나열하는 record:"links" 배열을 포함합니다.

단일 리프레시 사이클의 모든 span을 가져오려면 span 조회 출력의 trace:"trace_id" 값을 사용하세요.

SELECT
  trace:"span_id"::STRING AS span_id,
  resource_attributes:"snow.executable.name"::STRING AS dt_name,
  record_attributes:"snow.dynamic_table.state"::STRING AS state,
  record_attributes:"snow.dynamic_table.state_reason"::STRING AS state_reason,
  start_timestamp,
  timestamp AS end_timestamp,
  DATEDIFF('second', start_timestamp, timestamp) AS duration_sec,
  record:"links" AS upstream_links
FROM my_event_table
WHERE record_type = 'SPAN'
  AND record:"name" = 'table_refresh'
  AND trace:"trace_id" = 'abc123def456abc123def456abc12345'
ORDER BY start_timestamp ASC;
+----------+---------+-----------+-----------------+-------------------------+-------------------------+--------------+---------------------------------------------+
| SPAN_ID  | DT_NAME | STATE     | STATE_REASON    | START_TIMESTAMP         | END_TIMESTAMP           | DURATION_SEC | UPSTREAM_LINKS                              |
|----------+---------+-----------+-----------------+-------------------------+-------------------------+--------------+---------------------------------------------|
| f1e2d3c4 | DT_ORDERS    | SUCCEEDED | NULL            | 2026-02-13 10:01:00.000 | 2026-02-13 10:01:30.000 |           30 | []                                          |
| b5a6c7d8 | DT_CUSTOMERS | SUCCEEDED | NULL            | 2026-02-13 10:01:31.000 | 2026-02-13 10:02:00.000 |           29 | [{"span_id": "f1e2d3c4", ...}]              |
| a1b2c3d4 | DT_ENRICHED  | FAILED    | QUERY_FAILURE   | 2026-02-13 10:02:01.000 | 2026-02-13 10:02:20.000 |           19 | [{"span_id": "b5a6c7d8", ...}]              |
| c9d0e1f2 | DT_SUMMARY   | SKIPPED   | UPSTREAM_FAILURE| 2026-02-13 10:02:20.000 | 2026-02-13 10:02:20.000 |            0 | [{"span_id": "a1b2c3d4", ...}]              |
+----------+---------+-----------+-----------------+-------------------------+-------------------------+--------------+---------------------------------------------+

이 예시에서 DT_ORDERS와 DT_CUSTOMERS는 성공했고, DT_ENRICHED는 쿼리 오류로 실패했으며, DT_SUMMARY는 상위 의존성이 실패해서 자동으로 skip됐어요. UPSTREAM_LINKS 컬럼은 각 다이나믹 테이블의 직접 의존성을 span_id로 보여줍니다.

실패의 근본 원인 추적하기

하위(downstream) 다이나믹 테이블이 skip되거나 실패하면, span 링크를 통해 상위 의존성을 추적해 근본 원인을 찾아보세요.

WITH
  pipeline AS (
    SELECT
      trace:"span_id"::STRING AS span_id,
      resource_attributes:"snow.executable.name"::STRING AS dt_name,
      record_attributes:"snow.dynamic_table.state"::STRING AS state,
      record_attributes:"snow.dynamic_table.state_reason"::STRING AS state_reason,
      resource_attributes:"snow.query.id"::STRING AS query_id,
      record:"links" AS upstream_links
    FROM my_event_table
    WHERE record_type = 'SPAN'
      AND record:"name" = 'table_refresh'
      AND record_attributes:"snow.dynamic_table.data_timestamp" = '2026-02-13T10:00:00.000'
  ),
  target_links AS (
    SELECT f.value:"span_id"::STRING AS upstream_span_id
    FROM pipeline, LATERAL FLATTEN(input => upstream_links) f
    WHERE dt_name = 'DT_SUMMARY'
  )
SELECT
  p.dt_name AS upstream_dt,
  p.state AS upstream_state,
  p.state_reason AS upstream_reason,
  p.query_id AS upstream_query_id
FROM target_links tl
JOIN pipeline p ON tl.upstream_span_id = p.span_id;
+-------------+----------------+-----------------+--------------------------------------+
| UPSTREAM_DT | UPSTREAM_STATE | UPSTREAM_REASON | UPSTREAM_QUERY_ID                    |
|-------------+----------------+-----------------+--------------------------------------|
| DT_ENRICHED | FAILED         | QUERY_FAILURE   | 01ba7614-0107-e56c-0000-a995024f304a |
+-------------+----------------+-----------------+--------------------------------------+

query_id를 사용해 GET_QUERY_OPERATOR_STATS 또는 query history로 실패한 쿼리를 더 조사할 수 있어요.

다이나믹 테이블 파이프라인 span은 OpenTelemetry 데이터 모델을 따릅니다. event table에서 OpenTelemetry 호환 도구로 내보내 시각화할 수 있어요.

Snowsight에서 다이나믹 테이블 모니터링하기

목록 확인 및 검사하기

  1. Snowsight에 로그인하세요.
  2. Catalog » Explorer를 선택하세요.
  3. 데이터베이스와 스키마를 선택한 다음 Dynamic Tables 탭을 선택하세요.
  4. 다이나믹 테이블을 선택해 세부 정보를 확인하세요.
  • Table Details: 스케줄링 상태, 마지막 리프레시 상태, 현재·목표 lag, 리프레시 모드, 태그, 권한.
  • Columns: 컬럼 이름과 타입.
  • Data Preview: 최대 100행의 데이터.
  • Graph: 이 다이나믹 테이블의 파이프라인 의존성 그래프.
  • Refresh History: 리프레시별 상태, 지속 시간, lag 메트릭, 변경된 행 수.

리프레시 히스토리 보기

  1. Snowsight에 로그인하세요.
  2. Transformation » Dynamic tables를 선택하세요.
  3. 모든 다이나믹 테이블의 스케줄링 상태와 마지막 리프레시 상태를 확인하세요. 데이터베이스나 스키마로 필터링해 결과를 좁힐 수 있어요.
  4. 다이나믹 테이블을 선택하고 Refresh History 탭으로 이동해 상태, 지속 시간, lag을 포함한 리프레시별 세부 정보를 확인하세요.

더 알아보기 (Learn more)