Бэкап и восстановление базы данных postgresql в докер-контейнере.
N.B.: то же самое будет происходить и без контейнера, но с ним есть пара хинтов, которые могут пригодиться.
Задача: Сделать бэкап БД постгреса и восстановить на резервном сервере. Постгрес работает в docker-контейнере.
1. Делаем бэкап на активной продакшен-среде, тестируем восстановление на случай отказа. ПОЭТОМУ: никаких pg_dump только pg_basebackup (В чем разница, какие pros и contras хорошо написано в гугле).
Ок, бэкап сделали, архив получили, перенесли на тестовый сервер.
Дальше нужно запустить в нем докер-контейнер с пустой базой, но уже с примонтированным volume в который мы потом нашу базу и конфиги положим.
Это может выглядеть например так:
services:
db:
container_name: db
ports: [5432:5432]
image: postgres:12.3
restart: unless-stopped
user: «${UID}:${GID}»
shm_size: 5g
# command: sleep 30d
env_file:
— ./.env
volumes:
— /db_data:/var/lib/postgresql/data
— /db_backup:/backup
# — ./pg_hba.conf:/var/lib/postgresql/data/pg_hba.conf
# — ./postgresql.conf:/var/lib/postgresql/data/postgresql.conf
То, что закомментировано пока оставляем закомментированным. Запускаем этот yaml
(Requirements: У вас на целевом сервере уже должен быть установлен docker и docker-compose)
$ docker-compose -f docker-compose.yml up -d
Сразу смотрим что в логе контейнера:
docker logs db
Если он пишет что база проинициализирована и готова принимать соединения — то всё ок. Если что-то про то что папка /var/lib/postgresql/data не пустая — посмотрите на хостовой машине возможно вы что-то оставили в папке-исходнике /db_data
$ docker stop db
Разархивируем бэкап базу в папку /db_data попутно удаляя оттуда backup_label (и tablespace_map)
$ docker-compose -f docker-compose.yml up -d
Смотрим лог.
У меня написал примерно следующее:
LOG: invalid primary checkpoint record
PANIC: could not locate a valid checkpoint record
$ docker stop db
Заходим в yml и раскомментируем строку command: sleep 30d
$ docker-compose -f docker-compose.yml up -d
Так как команда sleep 30d то СУБД не запустилась. Можно зайти внутрь контейнера, а можно выполнить команду снаружи:
$ docker exec -it db pg_resetwal /var/lib/postgresql/data/
The database server was not shut down cleanly.
Resetting the write-ahead log might cause data to be lost.
If you want to proceed anyway, use -f to force reset.
Ладно, уговорил:
$ docker exec -it db pg_resetwal -f /var/lib/postgresql/data/
Write-ahead log reset
Всё. Стопаем контейнер, убираем sleep 30d и раскомментируем команды подключения конфигов.
После чего апаем контейнер снова. Получим вожделленное
LOG: database system is ready to accept connections
Можно идти в pgadmin или dbeaver и подключаться к базе.