Задача
Нужно было снимать копии нескольких баз PostgreSQL без доступа к серверу по SSH и без ручного pg_dump. Полная копия большой базы дорогая, поэтому между полными нужны маленькие копии только с изменениями.
Решение
Сделал веб-приложение на Django. Каждая копия сохраняет отпечаток всех строк базы, а следующая сравнивает с ним текущее состояние и пишет только разницу: новые, изменённые и удалённые строки. Разница ложится в один SQL-файл, который применяется обычным psql поверх восстановленной полной копии. Перед запуском приложение проверяет подключение и объясняет ошибку понятными словами.
Решённые задачи
- Сделал полные копии через pg_dump и инкрементальные и дифференциальные поверх них
- Ловлю все изменения, включая удалённые строки, без колонок updated_at
- Проверил восстановление целиком тестами на настоящем PostgreSQL
- Вынес копирование в фоновый воркер, сайт не ждёт дампа
- Дал выбор хранилища: диск сервера или S3
- Не храню пароли баз: в очереди они зашифрованы и стираются после копии
- Разделил доступ: каждый пользователь видит только свои копии
Результат
Копия базы снимается из браузера в пару кликов, а между полными копиями хранятся только изменения. Код открыт на GitHub, сервис разворачивается одной командой docker compose up.
Технологии
PythonDjangoPostgreSQLS3Docker