Iceberg time travel на собеседовании Data Engineer

Практика по теме статьи · без регистрации

Готовим вопросы…

Три вопроса по теме этой страницы, с объяснениями.

Почему time travel спрашивают

Time travel — одна из главных фич, ради которых команды переезжают с обычных Hive-таблиц на Apache Iceberg. Она позволяет прочитать таблицу такой, какой она была в любой момент прошлого: неделю назад, до вчерашней перезаписи, в конкретную дату для отчёта регулятору. На собесе Data Engineer это любимая тема, потому что за ней стоит понимание всей архитектуры Iceberg — метаданных, снапшотов и того, чем табличный формат отличается от «просто папки с parquet-файлами».

Типичная развилка на интервью: кандидат думает, что time travel — это про бэкапы. Это не так. Time travel работает поверх обычных данных таблицы за счёт неизменяемых снапшотов, и стоит понимать, откуда он берётся и как долго остаётся доступным.

Snapshots

Каждая операция записи в таблицу (INSERT, UPDATE, DELETE, MERGE, компакция) создаёт новый snapshot — неизменяемый (immutable) слепок состояния таблицы. Старые снапшоты не переписываются: Iceberg просто добавляет новый и переключает на него указатель текущего состояния. Именно поэтому таблицу можно «отмотать» назад — прошлые снапшоты физически лежат в метаданных.

Посмотреть историю можно через служебную таблицу метаданных:

SELECT * FROM iceberg.events.snapshots;
-- покажет snapshot_id, parent_id, operation (append/overwrite/delete),
-- committed_at и manifest-файлы каждого снапшота

Каждый снапшот ссылается на набор manifest-файлов, а те — на конкретные data-файлы. Так Iceberg точно знает, какие файлы составляли таблицу в каждый момент времени.

Запросы к прошлым версиям

Прочитать данные «как они были» можно двумя способами — по ID снапшота или по времени:

-- по ID снапшота
SELECT * FROM events VERSION AS OF 1234567;

-- по времени
SELECT * FROM events TIMESTAMP AS OF '2026-04-01 12:00:00';

Так пишут в Spark SQL. В Trino синтаксис немного другой — FOR VERSION AS OF и FOR TIMESTAMP AS OF, но смысл тот же. Движок берёт ближайший снапшот на указанный момент и читает ровно тот набор файлов, что был актуален тогда.

Branches и tags

С Iceberg 1.x появились именованные ссылки на снапшоты — почти как ветки в Git, только для данных.

Branch (ветка) — изменяемая (mutable) ссылка. Используется для dev/staging-окружений и паттерна write-audit-publish: пишете и проверяете данные в отдельной ветке, а основная (main) остаётся нетронутой, пока изменения не готовы.

ALTER TABLE events CREATE BRANCH dev_branch;
-- запись именно в ветку, main не трогаем
INSERT INTO events.branch_dev_branch VALUES (...);

Tag (тег) — неизменяемая именованная ссылка на конкретный снапшот. Удобно для аудита и регуляторных срезов: зафиксировали состояние на нужную дату и храните его заданный срок.

ALTER TABLE events CREATE TAG audit_2026_05_07
  AS OF VERSION 1234567
  RETAIN 365 DAYS;

Разница простая: ветка «двигается» с новыми записями, тег навсегда указывает на один снапшот.

Готовишься к собесу Data Engineer?
Spark, Airflow, ClickHouse, SQL для DE — вопросы с разборами в браузере
Тренировать DE в браузере

Применения

  • Аудит и compliance. «Покажите записи по состоянию на 1 апреля для регулятора» — фиксируете тег на нужную дату и отдаёте воспроизводимый срез.
  • Воспроизводимость ML. Обучаете модель на конкретной версии датасета, чтобы эксперимент можно было повторить байт-в-байт даже после того, как таблицу перезаписали.
  • Отладка. Сравниваете текущее состояние с прошлым, чтобы понять, что именно изменилось после проблемной загрузки.
  • Откат (rollback). Если джоба залила битые данные, таблицу возвращают на здоровый снапшот одной командой:
CALL iceberg.system.rollback_to_snapshot('events', 1234567);

Откат тоже создаёт новый снапшот, а не удаляет историю, — то есть его самого при желании можно откатить обратно.

Частые ошибки

  • Считать time travel бэкапом. Он не защищает от удаления файлов или потери хранилища — это функция версионирования поверх тех же данных, а не резервная копия в отдельном месте.
  • Забыть про expire snapshots. Старые снапшоты живут не вечно: процедура expire_snapshots и настройки retention удаляют устаревшие снапшоты и их файлы. После этого отмотать таблицу к удалённому снапшоту уже нельзя. На собесе часто спрашивают: «Почему time travel на месяц назад вернул ошибку?» — ответ обычно в истёкшем retention.
  • Путать branch и tag. Ветка изменяемая и двигается с записями, тег неизменяемый. Записать в тег «свежие» данные не получится.
  • Ожидать time travel в любом движке. Синтаксис зависит от движка (Spark, Trino, Flink), а часть систем поверх Iceberg поддерживает чтение снапшотов ограниченно.

Связанные темы

FAQ

Чем time travel отличается от бэкапа?

Time travel — это версионирование поверх текущих данных таблицы: старые снапшоты ссылаются на те же самые data-файлы в хранилище. Бэкап — независимая копия в отдельном месте, которая переживёт удаление или сбой основного хранилища. Time travel не заменяет бэкап: если файлы физически удалены (например, процедурой expire), отмотать таблицу к ним уже нельзя.

Как долго доступны старые снапшоты?

Пока они не истекли по retention. Процедура expire_snapshots и настройки вроде максимального возраста снапшота удаляют старые снапшоты и неиспользуемые файлы, освобождая место. Если нужен долгоживущий срез (например, для аудита) — вешают на него тег с явным сроком хранения через RETAIN N DAYS.

В чём разница между branch и tag?

Branch — изменяемая ветка, которая двигается вперёд с каждой новой записью; используется для dev/staging и паттерна write-audit-publish. Tag — неизменяемая метка на конкретном снапшоте; используется для аудита и фиксации состояния на дату. Ветка — «живой» указатель, тег — «замороженный».

Как откатить таблицу на прошлое состояние?

Процедурой rollback_to_snapshot (или set_current_snapshot) — указываете таблицу и ID здорового снапшота. Откат не стирает историю, а создаёт новый снапшот, указывающий на прошлое состояние, поэтому операция обратима. Найти нужный ID можно в служебной таблице snapshots.

Это официальная информация?

Нет. Статья основана на документации Apache Iceberg. Конкретный синтаксис и поведение зависят от движка (Spark, Trino, Flink) и версии Iceberg — сверяйтесь с документацией вашего окружения.


Тренируйте Data Engineering — откройте тренажёр с 1500+ вопросами для собесов.