Настройка barman для резервирования postgres

Логика работы barman

Архитектура barman

Восстановление

Важная ремарка

После сбоя 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-сервера с сервера 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

Восстановление на конкретную дату на сервере barman из-под пользователя barman:

Этот вариант сложнее, т.к. 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)

После этого можно писать в таблицы.

Заново запускаем репликацию postgres->barman

В случае, если мы восстанавливали данные на самую свежую дату (ьез указания опции --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

Возможные ошибки

archiver errors: FAILED (duplicates: XXX)

https://groups.google.com/g/pgbarman/c/0xaSp5o6smU

Это значит, что барману кто-то прислал какие-то валы дважды. И барман сложил их в директорию `barman_store_home/errors` и теперь рапортует об этом.

Можно зайти и посмотреть дату создания этих файлов (она в том числе в имени файла содержится - в постфиксе). Желательно поразбираться кто и когда его прислал. Для решения - просто удалить эти файлы из директории `errors`.

🔙 вернуться к началу...