This lesson on Apache Iceberg & Open Table Formats — ACID on S3 is hands-on and example-driven. You will master the hierarchical architecture of Apache Iceberg and understand how open table formats bring ACID reliability, schema enforcement, and snapshot isolation to object storage like AWS S3. You will be able to trace how queries resolve down through catalogs, metadata files, manifest lists, manifest files, and raw storage files.
What You'll Be Able To Do
- Trace query resolution down through the Iceberg hierarchical metadata tree.
- Contrast traditional ETL warehouse patterns with lakehouse open table formats.
- Explain snapshot isolation mechanics during write and delete operations.
- Identify the structural roles of manifest files, manifest lists, and metadata files.
- Evaluate object store reliability trade-offs when shifting from raw data lakes to Iceberg.
Detailed Concept Walkthrough
1. Evolution From Warehouses to Open Table Formats
Data architectures evolved from rigid ETL data warehouses to schema-less object lakes, ultimately requiring open table formats to restore ACID transactional guarantees. Iceberg provides an abstraction layer over cloud object storage without locking data into proprietary engines.
- Historical Context: Traditional ETL pipelines used tools like SSIS or Talend to enforce strict schemas and ACID properties inside centralized data warehouses. As data volumes expanded to multi-modal formats, teams shifted toward ELT patterns on cloud object stores like S3.
- The Lakehouse Dilemma: Raw data lakes accept diverse file formats such as Parquet, Avro, ORC, and JSON, but they lack native transaction isolation, concurrency control, and schema enforcement. This causes unmanaged external tables to become inconsistent and difficult to maintain.
- The Table Format Solution: Open table formats act as a transactional management layer on top of lake storage. They bring database-level reliability, snapshot tracking, and atomic operations directly to object storage files.
-- Example: Creating an Iceberg managed table backed by Parquet on object storage
CREATE TABLE glue_catalog.db.customer_events (
event_id STRING,
user_id BIGINT,
event_type STRING,
event_ts TIMESTAMP
)
USING iceberg
LOCATION 's3://my-lakehouse-bucket/customer_events';
-- Schema enforcement and snapshot tracking are now enabled automatically
Key Takeaway: Open table formats provide warehouse-grade ACID consistency directly over cheap, scalable cloud object storage.
2. The Iceberg Metadata Hierarchy
Apache Iceberg organizes table state as an immutable tree of metadata spanning catalogs, metadata JSON files, manifest lists, and manifest files. This decoupled design enables atomic commits and snapshot-based time travel.
- Catalog Layer: The catalog serves as the single source of truth that atomically points to the latest valid metadata file location. It acts as the entry point for engines resolving table references.
- Metadata File Layer: Metadata JSON files maintain table schemas, partition specs, and an array of historical snapshot records (e.g., snapshot 0, snapshot 1). Each table commit produces a new immutable metadata file.
- Manifest List Layer: Each snapshot points to a manifest list file (in Avro format), which tracks an array of manifest files along with partition summary statistics for query pruning.
- Manifest File Layer: Manifest files track specific raw data files (Parquet, ORC, Avro), storing individual data file paths, partition values, and column-level metric ranges.
/* Iceberg Metadata Hierarchy Resolution:
* [ Catalog (e.g. AWS Glue, REST, Hive) ]
* │ (points to current metadata pointer)
* ▼
* [ Metadata File: v3.metadata.json ] ─── tracks snapshots (s0, s1, s2)
* │ (snapshot s2)
* ▼
* [ Manifest List: snap-2-manifest-list.avro ]
* ├── Manifest File A (manifest-a.avro) ──► [ data_1.parquet, data_2.parquet ]
* └── Manifest File B (manifest-b.avro) ──► [ data_3.orc, data_4.parquet ]
*/
Key Takeaway: Iceberg tracks state through an immutable hierarchical tree of metadata, eliminating expensive object store directory listings.
3. Snapshot Isolation and Atomic State Changes
Every write, update, or delete operation in Iceberg produces a new isolated snapshot rather than mutating existing data in place. Readers always observe a consistent table snapshot while writes occur concurrently.
- Mechanism: When new records are appended or deleted, Iceberg writes new raw data files and generates corresponding manifest files. It then writes a new manifest list and a new metadata file containing the latest snapshot ID.
- Under the Hood: An atomic catalog swap updates the table reference pointer to the newly written metadata file. If a conflict occurs during the pointer swap, the transaction aborts and retries optimistically.
- Time Travel Support: Because prior snapshots and their corresponding metadata trees remain intact on object storage, query engines can read historical table versions without restoring backups.
-- Querying historical snapshots using Iceberg time travel in Spark SQL
SELECT * FROM glue_catalog.db.customer_events
FOR SYSTEM_TIME AS OF '2023-08-01 12:00:00';
-- Alternatively query a specific snapshot ID directly
SELECT * FROM glue_catalog.db.customer_events
FOR SYSTEM_VERSION AS OF 8472910485729104857;
Key Takeaway: Snapshots provide safe concurrent writes and historical time travel by guaranteeing immutability across the metadata tree.
Topics Covered in Apache Iceberg & Open Table Formats — ACID on S3
- Origin of Apache Iceberg (0:00 - 0:45) — Iceberg was created at Netflix around 2017 to solve data lake reliability challenges and later open-sourced.
- ETL vs. ELT Paradigms (0:45 - 1:55) — Traditional data warehouses enforced strict schemas via ETL, whereas modern lakehouses favor flexible ELT patterns.
- Data Lake Inconsistencies (1:55 - 3:05) — Storing raw files directly in S3 or external tables introduces schema drift and lacks transactional durability.
- Data and Manifest Files (3:05 - 4:30) — Iceberg tracks individual raw data files using intermediate Avro manifest files containing file paths and statistics.
- Manifest Lists and Scaling (4:30 - 5:40) — Manifest lists group multiple manifest files together, reducing the metadata overhead required to manage millions of files.
- Metadata File and Snapshots (5:40 - 6:45) — Metadata JSON files store table snapshots and serve as the single source of truth for historical table versions.
- The Catalog Pointer (6:45 - 7:50) — The catalog maintains the active pointer to the latest metadata file, completing the Iceberg architecture.
Data Engineering Cheat Sheet
-
Iceberg Catalog— Stores pointer to current metadata filespark.sql.catalog.glue_catalog = org.apache.iceberg.spark.SparkCatalog -
Metadata File (*.metadata.json)— Defines schemas, partitions, and all snapshots"current-snapshot-id": 1092837465192837465 -
Manifest List (*.avro)— Maps snapshot to its manifest files"manifest_path": "s3://bucket/metadata/manifest-1.avro" -
Manifest File (*.avro)— Tracks raw data files and metrics"data_file": {"file_path": "s3://bucket/data/file-1.parquet"} -
FOR SYSTEM_VERSION AS OF— Queries table state at snapshot IDSELECT * FROM db.events FOR SYSTEM_VERSION AS OF 1092837465; -
FOR SYSTEM_TIME AS OF— Queries table state at specific timestampSELECT * FROM db.events FOR SYSTEM_TIME AS OF '2024-01-01 00:00:00';
Comparison Table
| Architecture Layer | Primary Artifact | Core Responsibility |
|---|---|---|
| Catalog | Atomic reference pointer | Tracks latest metadata JSON path |
| Metadata File | JSON schema & snapshot list | Defines table schema and history |
| Manifest List | Avro list of manifests | Tracks manifests per active snapshot |
| Manifest File | Avro file index with stats | Maps paths to data files |
| Data Layer | Parquet, ORC, or Avro files | Stores actual raw record payloads |
Common Pitfalls
- Mistake: Assuming Iceberg stores data records inside its metadata JSON files. Avoid: Treat metadata files strictly as structural indices that point to external Parquet or ORC files.
- Mistake: Relying on directory-level object storage listing to identify table contents. Avoid: Always read table state via Iceberg catalogs and manifest files rather than file system paths.
- Mistake: Treating open table formats as an ingestion ETL framework. Avoid: Use Iceberg as a storage abstraction layer managed by compute engines like Spark, Trino, or Flink.
FAQs
- Why does Apache Iceberg use multiple layers of metadata instead of one flat file? Hierarchical metadata files and manifest lists allow Iceberg to scale to billions of files without rewriting entire catalog indexes during incremental commits.
- What happens to old snapshots when a table is updated? Old snapshots remain accessible in the metadata file until an explicit snapshot expiration or vacuum job cleans up historical files.
- Can an Iceberg table combine different physical file formats? Yes, manifest files can reference Parquet, ORC, and Avro files within the same logical table structure.
- How does Iceberg achieve ACID atomicity on object storage? Iceberg stages new data and metadata files immutably, then executes a single atomic commit in the catalog pointing to the new metadata JSON.