Сразу оговорюсь - dump это крайне надёжный и очень гибкий способ создания резервных копий!
Но, есть нюансы...
Рекомендуемая в том числе и мной схема организации резервного копирования:
▫️Мастер
▫️Реплика для отказоустойчивости
▫️Реплика для резервных копий
Соответственно резервные копии, например с помощью утилиты pg_dump (а в PostgreSQL есть ещё и другие способы сделать backup) рекомендуется делать с "Реплики для резервного копирования".
Так как dump это длительная транзакция, а длительные транзакции для PostgreSQL это плохой сценарий для мастера приводящий к блокировке работы autovacuum (процесс автоочистки "мёртвых" строк).
Помимо этого dump это ещё и достаточно большая нагрузка на диски, что так же не зачем мастеру, его работа пользователей обслуживать, а не ит-шные хотелки 😁
Итак, осознавая зачем и почему мы прилежно делаем dump-ы с реплики и считаем что всё хорошо. В целом оно так и есть при одном условии:
❗️Если реплика не отстаёт от мастера
Давайте на цифрах:
▫️Время на мастере - 12:00:00
▫️Время на которое реплика уже "проиграла" в себя данные - 11:59:59.389
▫️Время старта dump с реплики - 12:00:00
✅В этом случае всё прекрасно, делаем dump, и при восстановлении данные в базе будут на 11:59:59.389. так как dump консистентен на начало транзакции.
Теперь другой сценарий:
▫️Время на мастере - 13:00:00
▫️Время на которое реплика уже "проиграла" в себя данные - 11:59:59.389
▫️Время старта dump с реплики - 13:00:00
❗️В этом случае при восстановлении данные в базе будут на 11:59:59.389 и это неожиданно! Ведь мы то думали что они будут на момент старта dump-а 13:00:00!
Как такое произошло?
Всё дело в отставании реплики, оно на момент старта dump-а составило чуть более 1 часа.
Откуда может взяться отставание?
Дело в том, что в отличии от мастера, реплика однопоточная и ничего не знает о версиях, номерах транзакций и т.д., очень нужных вещей для мастера и совершенно бесполезных для реплики.
И если на реплики идёт транзакция, то "проигрывание" данные в базу останавливается (начинается накопление WAL - журнала предзаписи), "проигрывание" продолжится как только транзакция будет завершена. И так до следующей транзакции.
И как ни странно, этой первой транзакцией может легко оказаться наш первый dump, который просто длился более 1 часа
Второй вариант отставания - это чисто "железное" отставание, когда не справляется сеть между мастером и репликой. В этом случае на реплику просто не поступили ещё WAL-ы с мастера и ей нечего записать в базу.
Как получить отставание реплики от мастера?
Для этого есть специальное представление
pg_stat_replicationselect replay_lag from pg_stat_replication
Вернёт нам отставание реплики от мастера. например 00:00:00.003122
Но отставание как мы выше поняли может быть 2х типов (на самом деле больше, но это уже экзотика), получить отставание, которое обосновано не транзакциями на реплике, а сетью можно тем же представлением:
select wtite_lag from pg_stat_replication
❗️Что с этим со всем делать?
1. Следить за отставанием реплик
2. Иметь более одной реплики от мастера
3. Использовать другие средства резервного копирования (pg_basebackup, probackup и ещё штук 10 вариантов открытого ПО)
4. При крайней необходимости сделать dump с мастера, он всегда будет содержать данные на момент начала dump-а
