💾 Archived View for pub.phreedom.club › ~progserega_linux › glog › 2023.03.14_barman.gmi captured on 2023-03-20 at 17:45:32. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
После сбоя postgres-а или желая пооткатывать бэкапы - нужно сначала остановить передачу wal-файлов с сервера postgres в сервис barman-а, чтобы он не накатывал wal-а поверх своего бэкапа после отката. Иначе всё может смешаться в кучу и данные будут потеряны.
Т.е. может быть ситуация:
Чтобы исключить подобную ситуацию - нужно перед восстановлением бэкапа из barman-а отключить передачу wal-файлов с postgres на barman. Для этого в конфиге postgres комментируем строку:
archive_command = 'barman-wal-archive pg-cluster02.rs.int pg_cluster01 %p'
что отключит передачу wal-файлов на barman. После чего можно пробовать откатывать разные версии бэкапа на postgres, смотреть и не волноваться. После решения, что бэкап нас устраивает - нужно будет заново раскомментировать эту строку.
1. Произошёл сбой PostgreSQL сервера или мы решили откатить данные.
2. На сервере postgres (если был сбой - заново устанавливаем сервер postgres, подключаем его к barman) отключаем передачу wall-файлов, как описано в ремарке выше.
3. Останавливаем postgres
4. желательно копируем куда-нибудь директорию с данными postgres-а (если там что-то осталось)
5. Запускаем восстановление на сервере barman
6. Стартуем postgres
7. В случае необходимости проводим дополнительные действия по переводу postgres в нормальный режим работы, и запускаем репликацию на стороне barman.
останавливаем PostgreSQL на сервере базы данных
systemctl stop postgresql.service
Желательно сохранить директорию с файлами базы данных:
mv /var/lib/postgresql/13/main /var/lib/postgresql/13/main.old.bak
Команду запускаем на серере barman:
barman recover --get-wal --remote-ssh-command 'ssh postgres@pg-cluster01.rs.int' pg_cluster01 latest /var/lib/postgresql/13/main
После чего на сервере postgres просто запускаем postgres:
systemctl start postgresql.service
Проверяем, что всё корректно, что все данные присутствуют.
После этого включаем репликацию на сервере postgres - раскомментируем опцию archive_command в postgresql.conf, перезапускаем postgres:
systemctl restart postgresql.service
Репликация должна пойти, barman покажет статусом, что всё хорошо:
barman check pg_cluster01
Этот вариант сложнее, т.к. postgres будет восстанавливать своё состояние из wall-файлов, перейдёт в режим только-чтение, "сломается" репликация. И чтобы это всё заработало - потребуется большее количество действий.
останавливаем PostgreSQL на сервере базы данных
systemctl stop postgresql.service
Желательно сохранить директорию с файлами базы данных:
mv /var/lib/postgresql/13/main /var/lib/postgresql/13/main.old.bak
Восстанавливаем на конкретную дату:
barman recover --get-wal --remote-ssh-command 'ssh postgres@pg-cluster01.rs.int' --target-time "2023-03-14 11:18:00+10:00" pg_cluster01 20230314T111258 /var/lib/postgresql/13/main
Где 20230314T111258 - имя бэкапа, которое выдаёт команда `barman list-backup pg_cluster01`, либо это имя может принимать значение latest - самый последний бэкап.
После чего на сервере postgres просто запускаем postgres:
systemctl start postgresql.service
Проверяем, что всё корректно, что все данные присутствуют.
Или же может потребоваться запускать postgres в режиме восстановления:
На серере postgres запускаем восстановление (из-под пользователя postgres) - это необязательно, можно сразу просто запустить postgres как сервис, но иногда может понадобиться именно эта команда:
/usr/lib/postgresql/13/bin/postgres --single -c config_file=/etc/postgresql/13/main/postgresql.conf -D /var/lib/postgresql/13/main -P -d 5
7. после чего нажимаем ctrl+d, выходи, выходит из-под пользователя postgres и уже из-под рута запускаем postgres как сервис:
systemctl start postgresql.service
Тут же зайдя в постгрес клиентом и сделав select в нужной таблице - можно увидеть как появляются (постепенно) записи до указанного времени.
Убеждаемся, что версия оптимальная. Если не оптимальная и нужно откатывать на иную дату - то заново останавливает postgres и запускаем опять barman recover с нужными опциями (с нужным временем, на которое восстанавливаем)
Убедившись, что восстановились на нужную версию - раскомментируем опцию archive_command в postgresql.conf, перезапускаем postgres:
systemctl restart postgresql.service
Завершаем процесс восстановления на Postgres-е (все данные там в режиме "только чтение" до этого момента):
postgres=# select pg_wal_replay_resume(); pg_wal_replay_resume ---------------------- (1 row)
После этого можно писать в таблицы.
В случае, если мы восстанавливали данные на самую свежую дату (ьез указания опции --target-time), то этот раздел скорее всего вам не понадобится.
Однако если вы восстанавливали данные на какую-то конкретную дату, отличную от самой последней, то репликация может не запуститься стандартным способом, т.к. версии транзакций в barman-не для этого сервера будут свежее, чем версии транзакций на сервере postgres. Поэтому придётся синхронизировать репликацию командой:
barman receive-wal --reset pg_cluster01
Если в ответ получаем ошибку вида:
barman@pg-cluster02:/root$ barman receive-wal --reset pg_cluster01 ERROR: The receive-wal position is ahead of PostgreSQL current WAL lsn (000000070000000000000029.partial > None)
То нужно убрать файлы из streaming и повторить процесс:
mkdir /mnt/backup/barman/pg_cluster01/streaming.old/ mv /mnt/backup/barman/pg_cluster01/streaming/* /mnt/backup/barman/pg_cluster01/streaming.old/ barman receive-wal --reset pg_cluster01
Подождать пару минут, пока не запуститься в barman ещё одна оппытка репликации. И запустить проверку статуса слота:
barman check pg_cluster01
И там должно быть всё хорошо.
Так же может быть понадобится команда пересборки базы barman и, может быть, повторный сброс индексов wal:
barman rebuild-xlogdb pg_cluster01 barman receive-wal --reset pg_cluster01