Что первое приходит в голову, когда мы говорим про бекапы баз данных?
Ну, делать дамп раз в сутки через cron-таску и загружать его в отдельное хранилище. Есть говорить про PostgreSQL, то стандартный
pg_dump достаточен для этого. А восстанавливаемся через pg_restore.Отлично подходит для небольших инстансов, всяких селф-хостед сервисов. Например, у вас развернуты self-hosted Metabase, Infisical, Grafana. База весит немного, дамп еще меньше - рестор быстрый.
Проблем тут две:
- мы теряем до 24 часов данных, в зависимости от того, как давно был снят последний бекап
- при росте базы данных, особенно если это БД продукта, время рестора из дампа растет в прогрессии
Рестор ведь можно распараллелить - запустить в несколько потоков, почему растет время рестора?
Дамп базы под капотом - это инструкции как собрать базу заново - схема, COPY/INSERT-ы, CREATE INDEX, и тд. То есть при ресторе сначала все данные наливаются с нуля из SQL, а потом начинается создание индексов. На большой базе индексы могут создаваться долго, а главное - они жрут очень много ресурсов (проц+диск).
Плюс дампов - можно ресторить отдельные таблицы, ресторить рядом с другой БД внутри одного инстанса, сам дамп можно "прочитать".
Что делать с потерей данных, если последний дамп был давно? Надо снимать бекапы чаще :)
На прошлой неделе настраивал Point in time recovery (PITR) в PostgreSQL. Что это такое:
- раз в какое-то время снимаем полный бекап инстанса (ну например так же раз в сутки) - важно понимать, что мы бекапим не транзакционный дамп, а именно файлы БД.
- можно фулл-бекап снимать раз в неделю, а между ними бекапить "дельты" - они меньше и быстрее бекапятся.
- непрерывно и постоянно отправляем WAL-ы (write ahead log) - postgres сам запускает нужную команду, когда накапливает wal.
В чем суть?
- файловый бекап восстанавливается быстрее - потому что это просто копирование файлов
- wal-ы позволяют восстановить инстанс на ЛЮБОЕ время. Например. Сейчас 11:00. Последний фулл-бекап был в час ночи. Евстахий получил доступ на прод и навернул таблицу в 10:45. Я могу восстановить состояние кластера на 10:44. Потеря данных (не считая даунтайма на рестор) - 16 минут.
Я настраивал это с помощью софтины wal-g, которую делает Яндекс, и, кстати говоря, использует у себя в Managed Service for PostgreSQL в облаке. Сделал себе еще дашбордик с метриками и логами по бекапам, чтобы смотреть - всё ли с ними ок.