Вопрос не «есть ли бэкап», а «что я смогу восстановить»
Бэкап без проверенного восстановления - это надежда, а не страховка. Поэтому отталкиваются от цели: на какой момент и как быстро нужно уметь вернуться. Под разные ответы - разные инструменты.
pg_dump: логический снимок
pg_dump обходит базу одной транзакцией и выгружает её содержимое
(схему и/или данные) как SQL или в своём формате. Свойства:
- снимок строго на момент начала дампа, ни секундой позже;
- переносим между мажорными версиями и архитектурами;
- медленно восстанавливается на больших базах (это перезаливка данных и перестройка индексов);
- нельзя «докрутить» до состояния через 10 минут после дампа.
Это резервная копия уровня логики. Для «вернуть вчерашнюю базу целиком» годится; для «вернуть на 14:59, за минуту до аварии» - нет.
PITR: базовая копия + архив WAL
Point-in-time recovery собирается из двух частей:
- Базовая копия - физический слепок кластера на некоторый момент.
Снимается
pg_basebackupпрямо с работающего сервера. - Непрерывный архив WAL (см. wal) - сервер с
archive_mode = onотдаёт каждый заполненный сегмент журнала командойarchive_commandв надёжное место.
база на T0 ──┐
├──▶ восстановление: разворачиваем копию,
WAL: T0 ─────▶ T1 ─────▶ T2 ─────▶ now
проигрываем WAL до recovery_target_time
Имея копию на T0 и весь WAL после неё, можно развернуть копию и
проиграть журнал ровно до нужной точки - по времени
(recovery_target_time), по LSN или по именованной точке. Сервер
стартует с recovery.signal и restore_command, который подаёт ему
архивные сегменты, и останавливает replay на цели.
Классический сценарий «спасли от DROP»
В 15:00 кто-то выполнил DROP TABLE orders. Есть базовая копия с ночи и
архив WAL. Восстановление:
- развернуть ночную копию в отдельный каталог;
- задать
recovery_target_time = '15:00:00 минус секунда'; - дать
restore_command, чтобы сервер тянул архивные сегменты; - поднять - сервер проиграет WAL до момента перед DROP и остановится.
Таблица на месте, всё после рокового момента - откатано. Этого
pg_dump не умеет в принципе.
archive_mode требует рестарта
Частая засада: archive_mode нельзя включить на лету. Это параметр
уровня сервера, он применяется только при рестарте - в отличие от
archive_command, который перечитывается по reload. Включать архив
нужно заранее, а не в момент, когда копия уже понадобилась.
-- архив включён? применился ли (а не ждёт рестарта)?
SELECT name, setting, pending_restart
FROM pg_settings WHERE name IN ('archive_mode', 'archive_command');Что физически копируется - это форки (relfilenode-forks) и сегменты WAL; механика replay - та же, что crash recovery (checkpoint), только цель задаётся явно.