[Перевод] Разделение задач резервного копирования и удаления устаревших копий в PostgreSQL при помощи pgBackRest

4d05506eb388fbbc655609d980ca1191.jpg

Управление резервными копиями является одним из ключевых моментов в любой стратегии администрирования баз данных. Это гарантирует, что в случае сбоя или потери данных вы можете быстро восстановить всю информацию. pgBackRest — популярное решение для резервного копирования и восстановления PostgreSQL, которое предоставляет множество функций для управления резервными копиями. Тем не менее, по умолчанию стандартная конфигурация pgBackRest часто объединяет операции резервного копирования и удаления устаревших копий в одном процессе. 

В некоторых случаях удаление устаревших резервных копий может занимать больше времени, чем создание новых. Так может произойти из-за низкой пропускной способности сети, больших размеров базы данных или любых других ограничений ресурсов. 

Чтобы избежать эту проблему, можно оптимизировать процесс управления резервными копиями, разделив операции резервного копирования и удаления устаревших копий в pgBackRest. Это позволит нам выполнять данные процедуры независимо друг от друга, что может улучшить производительность и надежность системы.

Разделение операций резервного копирования и удаления устаревших копий в pgBackRest может быть достигнуто путем настройки конфигурационного файла pgBackRest. Так мы сможем задать разные расписания для операций резервного копирования и удаления устаревших копий. Например, настроим pgBackRest так, чтобы он делал резервные копии каждый день, а устаревшие удалял раз в неделю. Это позволит нам оптимизировать использование ресурсов и избежать задержек и нарушений в работе системы.

Почему надо отделять резервное копирование и удаление устаревших копий?

Здесь речь идет о разделение двух ключевых процессов управления данными, связанных с базой данных: создание резервных копий данных (backup) и удаление устаревших резервных копий (expiry).

Разделение операций по резервному копированию и удалению в связи с окончанием срока действия дает несколько преимуществ:

  • Увеличение скорости резервного копирования: Резервное копирование можно выполнять чаще, не замедляясь из-за потенциально затратного по времени процесса удаления устаревших данных.

  • Повышенная гибкость: Можно настраивать расписание резервного копирования и очистки по истечению срока действия независимо друг от друга, в соответствии с конкретными требованиями.

  • Сокращение окна резервного копирования: Более частое выполнение резервного копирования и уменьшение частоты очистки устаревших резервных копий позволяет минимизировать воздействие на систему во время операций резервного копирования.

Этапы для разделения резервного копирования и очистки по истечению срока действия

1. Настройка конфигурации

Откройте файл pgbackrest.conf, который обычно находится в каталоге конфигурации pgBackRest. Настройте параметры, отвечающие за срок хранения резервных копий и архивов, согласующиеся с вашей стратегией резервного копирования, закомментировав хранение для резервных копий. Затем установите необходимый срок хранения для архивов, изменив соответствующий параметр.

После внесения изменений сохраните файл конфигурации. Это позволит pgBackRest использовать новые параметры хранения для будущих резервных копий и архивов. 

[global]
repo1-retention-archive-type=full

В данном примере политика хранения резервных копий настроена таким образом, чтобы сохранять резервные копии неограниченно долго, то есть резервные копии не будут автоматически удаляться на основе их возраста или других критериев хранения. Кроме того, необходимые архивы для ПОЛНЫХ (full) резервных копий постоянно сохраняются, что гарантирует, что все необходимые файлы будут доступны для восстановления полной резервной копии без каких-либо проблем.

2. Выполнение резервного копирования

Запустите команду backup, чтобы выполнить резервное копирование.

$ pgbackrest --stanza=main --config=/etc/pgbackrest/pgbackrest.conf --log-level-console=info backup --type=full
2024-01-31 09:13:01.375 P00   INFO: backup command begin 2.48: --config=/etc/pgbackrest/pgbackrest.conf --exec-id=18737-d1ca38f0 --log-level-console=info --pg1-path=/var/lib/postgresql/16/main --repo1-path=/var/lib/pgbackrest --repo1-retention-archive-type=full --stanza=main --start-fast --type=full
WARN: option 'repo1-retention-full' is not set for 'repo1-retention-full-type=count', the repository may run out of space
     HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
2024-01-31 09:13:02.086 P00   INFO: execute non-exclusive backup start: backup begins after the requested immediate checkpoint completes
2024-01-31 09:13:02.587 P00   INFO: backup start archive = 000000060000000100000057, lsn = 1/57000028
2024-01-31 09:13:02.587 P00   INFO: check archive for prior segment 000000060000000100000056
2024-01-31 09:13:26.215 P00   INFO: execute non-exclusive backup stop and wait for all WAL segments to archive
2024-01-31 09:13:26.422 P00   INFO: backup stop archive = 000000060000000100000057, lsn = 1/57000138
2024-01-31 09:13:26.426 P00   INFO: check archive for segment(s) 000000060000000100000057:000000060000000100000057
2024-01-31 09:13:26.542 P00   INFO: new backup label = 20240131-091301F
2024-01-31 09:13:26.598 P00   INFO: full backup size = 512.3MB, file total = 1195
2024-01-31 09:13:26.599 P00   INFO: backup command end: completed successfully (25227ms)
2024-01-31 09:13:26.599 P00   INFO: expire command begin 2.48: --config=/etc/pgbackrest/pgbackrest.conf --exec-id=18737-d1ca38f0 --log-level-console=info --repo1-path=/var/lib/pgbackrest --repo1-retention-archive-type=full --stanza=main
2024-01-31 09:13:26.608 P00   INFO: option 'repo1-retention-archive' is not set - archive logs will not be expired
2024-01-31 09:13:26.608 P00   INFO: expire command end: completed successfully (9ms)

Обратите внимание на появляющиеся предупреждения при выполнении ожидаемого резервного копирования.

3. Выполнение операции удаления устаревших резервных копий

Давайте тщательно проанализируем информацию о существующих резервных копиях и определим, сколько из них в настоящее время доступно в нашем репозитории, прежде чем приступим к операции удаления устаревших резервных копий.

$ pgbackrest info
stanza: main
   status: ok
   cipher: none
   db (current)
       wal archive min/max (16): 000000060000000100000057/00000006000000010000005F
       full backup: 20240131-091301F
           timestamp start/stop: 2024-01-31 09:13:01+00 / 2024-01-31 09:13:26+00
           wal start/stop: 000000060000000100000057 / 000000060000000100000057
           database size: 512.3MB, database backup size: 512.3MB
           repo1: backup set size: 59MB, backup size: 59MB
       full backup: 20240131-093948F
           timestamp start/stop: 2024-01-31 09:39:48+00 / 2024-01-31 09:40:12+00
           wal start/stop: 000000060000000100000059 / 000000060000000100000059
           database size: 512.3MB, database backup size: 512.3MB
           repo1: backup set size: 59MB, backup size: 59MB
       diff backup: 20240131-093948F_20240131-094022D
           timestamp start/stop: 2024-01-31 09:40:22+00 / 2024-01-31 09:40:23+00
           wal start/stop: 00000006000000010000005B / 00000006000000010000005B
           database size: 512.3MB, database backup size: 8.3KB
           repo1: backup set size: 59MB, backup size: 440B
           backup reference list: 20240131-093948F
       diff backup: 20240131-093948F_20240131-094033D
           timestamp start/stop: 2024-01-31 09:40:33+00 / 2024-01-31 09:40:35+00
           wal start/stop: 00000006000000010000005C / 00000006000000010000005D
           database size: 512.3MB, database backup size: 8.3KB
           repo1: backup set size: 59MB, backup size: 442B
           backup reference list: 20240131-093948F
       full backup: 20240131-094044F
           timestamp start/stop: 2024-01-31 09:40:44+00 / 2024-01-31 09:41:07+00
           wal start/stop: 00000006000000010000005F / 00000006000000010000005F
           database size: 512.3MB, database backup size: 512.3MB
            repo1: backup set size: 59MB, backup size: 59MB

Выполните команду expiry, чтобы удалить устаревшие резервные копии на основе настроенных политик хранения. Политики хранения определяют сколько времени резервная копия должна оставаться в репозитории перед удалением.

$ pgbackrest --stanza=main --config=/etc/pgbackrest/pgbackrest.conf --log-level-console=detail expire --repo1-retention-full=1
2024-01-31 09:43:01.502 P00   INFO: expire command begin 2.48: --config=/etc/pgbackrest/pgbackrest.conf --exec-id=19111-dc5f56ed --log-level-console=detail --repo1-path=/var/lib/pgbackrest --repo1-retention-archive-type=full --repo1-retention-full=1 --stanza=main
2024-01-31 09:43:01.504 P00   INFO: repo1: expire full backup 20240131-091301F
2024-01-31 09:43:01.504 P00   INFO: repo1: expire full backup set 20240131-093948F, 20240131-093948F_20240131-094022D, 20240131-093948F_20240131-094033D
2024-01-31 09:43:01.513 P00   INFO: repo1: remove expired backup 20240131-093948F_20240131-094033D
2024-01-31 09:43:01.513 P00   INFO: repo1: remove expired backup 20240131-093948F_20240131-094022D
2024-01-31 09:43:01.513 P00   INFO: repo1: remove expired backup 20240131-093948F
2024-01-31 09:43:01.548 P00   INFO: repo1: remove expired backup 20240131-091301F
2024-01-31 09:43:01.595 P00 DETAIL: repo1: 16-1 archive retention on backup 20240131-094044F, start = 00000006000000010000005F
2024-01-31 09:43:01.596 P00   INFO: repo1: 16-1 remove archive, start = 000000060000000100000057, stop = 00000006000000010000005E
2024-01-31 09:43:01.596 P00   INFO: expire command end: completed successfully (96ms)
postgres@ip-172-31-18-53:~$

Обратите внимание, что даже несмотря на то, что мы не предоставили никаких атрибутов для истекающих дифференциальных резервных копий при истечении срока действия полных резервных копий, программное обеспечение pgBackRest автоматически удалит последующие дифференциальные резервные копии, которые зависят от истекающего полного набора резервных копий.

Дифференциальные резервные копии (differential backups) — это тип резервного копирования, при котором сохраняются только те изменения, которые были сделаны в базе данных с момента последней полной резервной копии. Это означает, что дифференциальная резервная копия содержит все изменения, сделанные в базе данных с момента последней полной резервной копии, но не содержит саму полную резервную копию.

После того, как политика хранения была применена и истек срок действия некоторых резервных копий, важно проверить информацию о резервном копировании, чтобы узнать, какие наборы резервных копий были удалены, а какие сохранены. Это поможет администраторам баз данных контролировать использование дискового пространства, а также обеспечить наличие необходимых резервных копий для восстановления. Для проверки информации о резервном копировании можно использовать команду pgBackRest, которая позволит получить подробный отчет о всех наборах резервных копий, включая дату их создания, тип, размер и статус.

$ pgbackrest info
stanza: main
   status: ok
   cipher: none
   db (current)
       wal archive min/max (16): 00000006000000010000005F/000000060000000100000061
       full backup: 20240131-094044F
           timestamp start/stop: 2024-01-31 09:40:44+00 / 2024-01-31 09:41:07+00
           wal start/stop: 00000006000000010000005F / 00000006000000010000005F
           database size: 512.3MB, database backup size: 512.3MB
           repo1: backup set size: 59MB, backup size: 59MB
       diff backup: 20240131-094044F_20240131-094124D
           timestamp start/stop: 2024-01-31 09:41:24+00 / 2024-01-31 09:41:25+00
           wal start/stop: 000000060000000100000061 / 000000060000000100000061
           database size: 512.3MB, database backup size: 8.3KB
           repo1: backup set size: 59MB, backup size: 442B
            backup reference list: 20240131-094044F

Как и ожидалось, была сохранена одна полная резервная копия в соответствии с атрибутами, указанными в команде expiry. Кроме того, также были сохранены соответствующие дифференциальные резервные копии для данного набора полных резервных копий, что позволяет выполнить восстановление до любого момента времени (PITR — Point-in-Time Recovery).

4. Расписание резервных копий и удаления устаревших

Создайте отдельные cron-задания или планировщики задач для резервного копирования и удаления устаревших резервных копий в соответствии с предпочитаемой частотой. Это означает, что необходимо настроить автоматическое выполнение операций резервного копирования и удаления устаревших резервных копий в определенное время и в соответствии с определенным графиком.

В зависимости от ваших требований к безопасности и объему данных, вы можете настроить различную частоту выполнения резервного копирования и удаления устаревших резервных копий. Например, вы можете выполнять резервное копирование ежедневно в определенное время, а удаление устаревших резервных копий — еженедельно.

При создании cron-заданий или планируемых задач необходимо учесть, чтобы они не пересекались по времени выполнения, чтобы избежать конфликтов и нагрузки на систему. Кроме того, рекомендуется регулярно проверять результаты работы cron-заданий и планируемых задач, чтобы убедиться в их корректной работе и своевременно устранять возникающие ошибки.

# Example backup cron job (run diff backups on weekdays)
0 3 * * 1-5 pgbackrest --stanza=main --config=/etc/pgbackrest/pgbackrest.conf backup --type=diff

# Example backup cron job (run full backups on Saturday)
0 3 * * 6 pgbackrest --stanza=main --config=/etc/pgbackrest/pgbackrest.conf backup --type=full

# Example expiry cron job (run less frequently, e.g., on Sunday)
0 4 * * 0 pgbackrest --stanza=main --config=/etc/pgbackrest/pgbackrest.conf expire --repo1-retention-full=1

В этом примере дифференциальное резервное копирование выполняется по будням в 3 часа утра, полное — по субботам, а операции удаления устаревших копий — еженедельно по воскресеньям в 4 часа утра. Обратите внимание, что команда expiry имеет параметр —repo1-retention-full=1, что позволит нам сохранить хотя бы одну полную резервную копию. pgBackRest автоматически управляет удалением последующих дифференциальных резервных копий, а также удалением каждого набора полных резервных копий.

Заключение

Такой подход обеспечивает быстрое и оперативное выполнение операций резервного копирования, даже если база данных растет. Я наблюдал подобную проблему у одного из наших клиентов, который хранил резервные копии в облаке, и операции удаления устаревших данных занимали в три-четыре раза больше времени, чем резервное копирование, что мешало выполнению множества задач. Для ее решения мы использовали опцию пакетной обработки файлов (file bundle) pgBackRest, которая позволяет собирать или объединять несколько файлов в один компактный пакет для удобства хранения, передачи или использования. Она помогла сократить время, затрачиваемое на резервное копирование. Тем не менее, операции удаления всё равно занимали много времени.

Отделение операций резервного копирования и удаления устаревших данных с помощью pgBackRest — это не просто настройка конфигурации, это стратегический шаг к более устойчивому и адаптивному подходу к управлению базами данных.

Percona Distribution for PostgreSQL предоставляет лучшие и наиболее важные корпоративные компоненты от сообщества разработчиков программного обеспечения с открытым исходным кодом в одном дистрибутиве. Все эти компоненты тщательно протестированы и спроектированы для совместной работы. Это позволяет использовать PostgreSQL в продакшене и критически важных средах. Кроме того, предоставляется простой способ деплоя и оркестрации надежной PostgreSQL в Kubernetes.

В завершение приглашаем всех желающих на открытый урок «PostgreSQL High-Availability при помощи Patroni». В ходе вебинара мы рассмотрим создание отказоустойчивого кластера PostgreSQL с использованием такого инструмента как Patroni. Patroni — это Python-приложение для создания высокодоступных PostgreSQL кластеров на основе потоковой репликации. Записывайтесь по ссылке.

© Habrahabr.ru