Apache Iceberg 메타데이터 테이블: 내부 조회
Source: Dev.to
이 글은 15부작 Apache Iceberg 마스터클래스의 11번째 파트입니다. 10부에서는 유지보수 작업에 대해 다루었습니다. 이번 글에서는 표준 SQL을 사용해 Iceberg 테이블 내부를 검사할 수 있는 메타데이터 테이블에 대해 소개합니다.
Iceberg은 내부 메타데이터를 쿼리 가능한 가상 테이블 형태로 노출합니다. 이를 활용해 테이블 상태를 점검하고, 성능 문제를 디버깅하며, 변경 이력을 감사하고, 모니터링 대시보드를 구축할 수 있습니다. 별도의 도구가 필요 없으며, SQL만 있으면 됩니다.
목차
- 테이블 포맷이란 무엇이며 왜 필요했는가?
- 현재 테이블 포맷들의 메타데이터 구조
- 성능과 Apache Iceberg의 메타데이터
- 파티션 진화에 대한 기술적 깊이 파고들기
- 숨겨진 파티셔닝에 대한 기술적 깊이 파고들기
- Apache Iceberg 테이블에 쓰기
- 레이크하우스 카탈로그란?
- 임베디드 카탈로그: S3 테이블 및 MinIO AI 스토어
- Iceberg 테이블 스토리지가 시간이 지남에 따라 어떻게 악화되는가
- Apache Iceberg 테이블 유지보수
- Apache Iceberg 메타데이터 테이블
- Python 및 MPP 엔진과 함께 Iceberg 사용하기
- 스트리밍 데이터를 Apache Iceberg 테이블에 넣기
- Dremio Cloud를 활용한 Iceberg 실습
- Apache Iceberg로 마이그레이션하기
메타데이터 테이블 소개
- $snapshots 테이블: 테이블 히스토리의 모든 스냅샷을 나열합니다. 각 행은 커밋된 트랜잭션을 의미합니다.
-- Dremio syntax
SELECT * FROM TABLE(table_snapshot('analytics.orders'))
-- Spark syntax
SELECT * FROM analytics.orders.snapshots
주요 컬럼: snapshot_id, committed_at, operation(append, overwrite, delete), summary(추가/삭제된 파일 수).
- $history 테이블: 각 시점에 어떤 스냅샷이 현재였는지를 보여줍니다.
SELECT * FROM TABLE(table_history('analytics.orders'))
- $files 테이블: 현재 스냅샷에 포함된 모든 데이터 파일과 상세 통계를 나열합니다.
SELECT file_path, file_size_in_bytes, record_count, partition
FROM TABLE(table_files('analytics.orders'))
이 테이블은 파일 크기를 점검하고 작은 파일 문제를 식별하는 기본 진단 도구입니다.
- $manifests 테이블: 현재 스냅샷에 대한 매니페스트 파일을 나열합니다.
SELECT path, length, added_data_files_count, existing_data_files_count
FROM TABLE(table_manifests('analytics.orders'))
- $partitions 테이블: 파티션별 통계(레코드 수, 파일 수, 크기)를 제공합니다.
SELECT partition, record_count, file_count
FROM TABLE(table_partitions('analytics.orders'))
파일 평균 크기 확인 예시
SELECT
AVG(file_size_in_bytes) / 1048576 AS avg_file_mb,
MIN(file_size_in_bytes) / 1048576 AS min_file_mb,
COUNT(*) AS total_files
FROM TABLE(table_files('analytics.orders'))
- 평균 파일 크기가 64 MB 이하로 떨어지면 컴팩션을 스케줄링합니다.
파티션당 파일 수 확인 예시
SELECT partition, COUNT(*) AS files, SUM(record_count) AS rows
FROM TABLE(table_files('analytics.orders'))
GROUP BY partition
ORDER BY files DESC
LIMIT 20
파일 수가 수백 개에 달하는 파티션은 컴팩션 후보입니다. 이 쿼리를 일일 건강 체크에 활용하고 결과를 모니터링 시스템에 파이프라인하세요.
정렬 효과 확인 (파일 테이블의 컬럼 통계)
SELECT
file_path,
lower_bounds['customer_id'] AS min_customer_id,
upper_bounds['customer_id'] AS max_customer_id
FROM TABLE(table_files('analytics.orders'))
파일 간 최소/최대 범위가 크게 겹친다면 정렬이 약화된 것이며, 파트 10에서 다룬 정렬 기반 컴팩션을 수행하면 효과가 회복됩니다.
쓰기 빈도 추적
SELECT
DATE_TRUNC('hour', committed_at) AS hour,
COUNT(*) AS commits,
SUM(CAST(summary['added-data-files'] AS INT)) AS files_added
FROM TABLE(table_snapshot('analytics.orders'))
WHERE committed_at > CURRENT_TIMESTAMP - INTERVAL '24' HOUR
GROUP BY DATE_TRUNC('hour', committed_at)
ORDER BY hour
시간당 수백 건의 커밋이 발생한다면 스트리밍 워크로드이며, 적극적인 컴팩션이 필요합니다.
최근 10개 커밋 보기
SELECT committed_at, operation, summary
FROM TABLE(table_snapshot('analytics.orders'))
ORDER BY committed_at DESC
LIMIT 10
각 커밋에서 추가·삭제된 파일 수를 확인할 수 있습니다.
타임 트래블 (시간 여행) 쿼리
메타데이터 테이블을 이용해 특정 시점의 스냅샷 ID를 찾은 뒤, 해당 스냅샷으로 테이블을 조회합니다.
-- 2월 15일 기준 테이블 조회
SELECT * FROM analytics.orders
AT SNAPSHOT '1234567890123456789'
-- 혹은 타임스탬프 기준
SELECT * FROM analytics.orders
AT TIMESTAMP '2024-02-15 00:00:00'
타임 트래블은 다음 상황에 유용합니다.
- 디버깅: “어제 파이프라인이 실행되기 전 테이블은 어땠을까?”
- 감사: “분기 말 기준 계정 잔액은 얼마였는가?”
- 재현 가능한 분석: “지난 달 데이터로 보고서를 다시 실행한다.”
증분 처리
두 스냅샷을 비교해 새로 추가된 파일만 골라 처리하면 전체 테이블을 다시 스캔할 필요가 없습니다.
-- 마지막 스냅샷에 추가된 파일 찾기
SELECT file_path, record_count
FROM TABLE(table_files('analytics.orders'))
WHERE file_path NOT IN (
SELECT file_path FROM TABLE(table_files('analytics.orders'))
AT SNAPSHOT '1234567890'
)
이 패턴은 Iceberg 테이블에서 CDC(Change Data Capture)의 기본이 됩니다. 마지막 처리 이후 변경된 데이터만 읽어오면 됩니다.
롤백
잘못된 쓰기로 테이블이 손상됐을 경우, 스냅샷 리스트를 이용해 이전 정상 스냅샷으로 되돌릴 수 있습니다.
-- 마지막 정상 스냅샷 찾기
SELECT snapshot_id, committed_at, operation
FROM TABLE(table_snapshot('analytics.orders'))
ORDER BY committed_at DESC
-- Spark에서 롤백 실행
CALL system.rollback_to_snapshot('analytics.orders', 1234567890)
롤백은 데이터를 삭제하지 않습니다. 현재 스냅샷 포인터를 이전 스냅샷으로 이동시켜 테이블을 그 시점의 상태로 보이게 할 뿐이며, 롤백된 파일은 복구를 위해 스토리지에 그대로 남아 있습니다.
Dremio와 메타데이터 테이블
Dremio는 TABLE() 함수 구문을 통해 모든 Iceberg 메타데이터 테이블을 지원하며, SQL 및 시맨틱 레이어 모두에서 타임 트래블을 제공합니다.
메타데이터 기반 모니터링 잡 예시
-- 테이블 건강 요약
SELECT
(SELECT COUNT(*) FROM TABLE(table_snapshot('analytics.orders'))) AS snapshots,
(SELECT COUNT(*) FROM TABLE(table_files('analytics.orders'))) AS files,
(SELECT AVG(file_size_in_bytes)/1048576 FROM TABLE(table_files('analytics.orders'))) AS avg_mb,
(SELECT COUNT(*) FROM TABLE(table_manifests('analytics.orders'))) AS manifests
스냅샷 수가 1,000을 초과하거나 평균 파일 크기가 64 MB 이하, 매니페스트 수가 500을 초과하면 알림을 설정합니다.
엔진별 문법 차이
기본 데이터는 동일하지만, 메타데이터 테이블을 호출하는 SQL 문법은 엔진마다 다릅니다. 어떤 엔진을 사용하든, 이 메타데이터 테이블은 Iceberg 테이블 건강을 이해하고 유지보수하는 핵심 진단 도구입니다.
자동화된 유지보수 의사결정
예를 들어, 스케줄러가 컴팩션이 필요한지를 먼저 판단하고 실행하도록 할 수 있습니다.
-- 평균 파일 크기가 임계값 이하일 때만 컴팩션 수행
SELECT CASE
WHEN AVG(file_size_in_bytes) / 1048576 < 64 THEN 'COMPACT_NEEDED'
ELSE 'HEALTHY'
END AS table_status
FROM TABLE(table_files('analytics.orders'))
이미 정돈된 테이블에 불필요한 컴팩션을 실행하지 않아 컴퓨팅 비용을 절감하고, 데이터 재작성도 방지합니다.
프로덕션 환경 적용
Airflow, Dagster, Prefect 등 오케스트레이션 도구에 이 체크들을 통합하세요. 모든 테이블에 대해 일일 메타데이터 스캔을 수행하고, 건강 지표를 수집한 뒤, 필요할 때만 유지보수 작업을 트리거합니다. 이렇게 하면 수백 개 테이블을 수동 관리 없이도 확장할 수 있습니다. Open Catalog로 관리되는 테이블에 대해서는 Dremio의 자동 최적화 기능이 전체 워크플로를 자동화합니다.
다음 파트: Part 12에서는 Python 및 MPP 쿼리 엔진에서 Iceberg을 사용하는 방법을 다룹니다.
참고 자료
- Architecting the Apache Iceberg Lakehouse – Alex Merced (Manning)
- Lakehouses with Apache Iceberg: Agentic Hands-on – Alex Merced
- Constructing Context: Semantics, Agents, and Embeddings –