24.3. Continue Archiving and Point-in-Time Recovery (PITR)#

24.3. Continue Archiving and Point-in-Time Recovery (PITR)

24.3. Continue Archiving and Point-in-Time Recovery (PITR) #

В любое время Tantor BE поддерживает журнал с предварительной записью (WAL) в подкаталоге pg_wal/ каталога данных кластера. Журнал записывает каждое изменение, внесенное в файлы данных базы данных. Этот журнал существует в основном для обеспечения безопасности при сбое: если система выйдет из строя, база данных может быть восстановлена до согласованного состояния путем повторного воспроизведения записей журнала, сделанных с момента последней контрольной точки. Однако наличие журнала позволяет использовать третью стратегию резервного копирования баз данных: можно объединить резервное копирование на уровне файловой системы с резервным копированием файлов журнала предзаписи. Если требуется восстановление, мы восстанавливаем резервную копию файловой системы, а затем повторно воспроизводим записи из резервных копий файлов журнала предзаписи, чтобы привести систему в актуальное состояние. Этот подход сложнее в управлении, чем любой из предыдущих подходов, но он имеет некоторые значительные преимущества:

  • Нам не нужна идеально согласованная резервная копия файловой системы в качестве отправной точки. Любая внутренняя несогласованность в резервной копии будет исправлена с помощью воспроизведения журнала (это не существенно отличается от того, что происходит во время восстановления после сбоя). Поэтому нам не нужна возможность создания снимка файловой системы, просто tar или аналогичный инструмент архивирования.

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

  • Необходимо воспроизводить записи WAL не до конца. Можно остановить воспроизведение в любой момент и иметь согласованную снимок базы данных такой, какой она была в этот момент. Таким образом, эта техника поддерживает восстановление до точки во времени: возможно восстановить базу данных в состояние, которое она имела в любое время после создания базовой резервной копии.

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

Примечание

pg_dump и pg_dumpall не создают резервные копии на уровне файловой системы и не могут использоваться в качестве части непрерывного архивного решения. Такие дампы являются логическими и не содержат достаточно информации для использования при воспроизведении WAL.

Как и в случае с обычной техникой резервного копирования файловой системы, этот метод может поддерживать только восстановление всего кластера баз данных, а не его подмножества. Кроме того, для него требуется много архивного хранилища: базовая резервная копия может быть громоздкой, и активная система будет генерировать много мегабайтов трафика WAL, которые должны быть архивированы. Тем не менее, это предпочтительный метод резервного копирования во многих ситуациях, где требуется высокая надежность.

Чтобы успешно восстановиться с использованием непрерывной архивации (также называемой "онлайн-резервным копированием" многими поставщиками баз данных), вам необходима непрерывная последовательность архивных файлов журнала предзаписи, которая простирается назад, по крайней мере, до времени начала вашего резервного копирования. Поэтому, чтобы начать, вам следует настроить и протестировать процедуру архивации файлов журнала предзаписи перед тем, как сделать первое базовое резервное копирование. Следовательно, мы сначала обсудим механику архивации файлов журнала предзаписи.

24.3.1. Настройка архивирования WAL #

В абстрактном смысле, работающая система Tantor BE производит бесконечную последовательность записей WAL. Система физически разделяет эту последовательность на файлы WAL сегментов, которые обычно имеют размер 16 МБ (хотя размер сегмента может быть изменен во время initdb). Сегменты файлов получают числовые имена, отражающие их позицию в абстрактной последовательности WAL. Когда не используется архивирование WAL, система обычно создает только несколько сегментных файлов, а затем переиспользует их, переименовывая файлы сегментов, которые больше не нужны, в более высокие номера сегментов. Предполагается, что сегментные файлы, содержимое которых предшествует последней контрольной точке, больше не представляют интереса и могут быть переиспользованы.

При архивировании данных WAL нам необходимо захватывать содержимое каждого сегментного файла после его заполнения и сохранять эти данные где-то, прежде чем сегментный файл будет повторно использован. В зависимости от приложения и доступного оборудования может быть множество различных способов "сохранения данных где-то": можно скопировать сегментные файлы в каталог, смонтированный по NFS на другой машине, записать их на магнитную ленту (обеспечивая способ идентификации исходного имени каждого файла), объединить их вместе и записать на CD или что-то еще полностью отличное. Чтобы предоставить администратору базы данных гибкость, Tantor BEне делает никаких предположений о том, как будет выполняться архивирование. Вместо этого Tantor BEпозволяет администратору указать команду оболочки или библиотеку архива, которая будет выполнена для копирования завершенного сегментного файла в нужное место. Это может быть такой простой командой оболочки, как cp, или она может вызывать сложную функцию на языке C - все зависит от вас.

Для включения архивирования WAL установите параметр конфигурации wal_level в значение replica или выше, параметр archive_mode в значение on, укажите команду оболочки для использования в параметре конфигурации archive_command или укажите библиотеку для использования в параметре конфигурации archive_library. На практике эти настройки всегда будут размещены в файле postgresql.conf.

В archive_command переменная, %p, заменяется на путь к файлу для архивации, а %f - только на имя файла. (Путь относительно текущего рабочего каталога, т.е. каталога данных кластера). Используйте %%, если вам нужно вставить фактический символ % в команду. Самая простая полезная команда может выглядеть так:

archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'  # Unix
archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"'  # Windows

который скопирует архивные сегменты WAL в каталог /mnt/server/archivedir. (Это пример, а не рекомендация, и может не работать на всех платформах). После замены параметров %p и %f, фактическая выполняемая команда может выглядеть так:

test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065

Для каждого нового файла, который нужно архивировать, будет сгенерирована аналогичная команда.

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

Важно, чтобы команда архивации возвращала нулевой статус выхода только в случае успеха. Получив нулевой результат, Tantor BE будет считать, что файл успешно архивирован, и удалит или переработает его. Однако ненулевой статус сообщает Tantor BE, что файл не был архивирован; он будет периодически пытаться снова, пока не добьется успеха.

Еще один способ архивирования - использовать пользовательский модуль архивации в качестве archive_library. Поскольку такие модули написаны на C, создание собственного модуля может потребовать значительно больше усилий, чем написание команды оболочки. Однако модули архивации могут быть более производительными, чем архивирование через оболочку, и они будут иметь доступ к многим полезным ресурсам сервера. Дополнительную информацию о модулях архивации см. в разделе Глава 48.

Когда команда архивации завершается сигналом (кроме SIGTERM, который используется при завершении работы сервера) или ошибкой оболочки с кодом возврата больше 125 (например, команда не найдена), или если функция архивации выдает ERROR или FATAL, процесс архиватора прерывается и перезапускается постмастер. В таких случаях сбой не отображается в pg_stat_archiver.

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

В редких случаях, Tantor BE может попытаться повторно архивировать файл WAL, который был ранее архивирован. Например, если система аварийно завершает работу до того, как сервер сделает надежную запись об успешном архивировании, сервер попытается архивировать файл снова после перезапуска (при условии, что архивирование все еще включено). Когда команда архивирования или библиотека сталкивается с уже существующим файлом, она должна вернуть нулевой статус или true, соответственно, если файл WAL имеет идентичное содержимое с уже существующим архивом и уже существующий архив полностью сохранен на носителе. Если уже существующий файл содержит другое содержимое, чем файл WAL, который архивируется, команда архивирования или библиотека должны вернуть ненулевой статус или false, соответственно.

Приведенная выше команда для Unix избегает перезаписи существующего архива путем включения отдельного шага test. На некоторых платформах Unix, cp имеет опции, такие как -i, которые могут быть использованы для достижения того же результата менее многословно, но не следует полагаться на них, не проверив, что возвращается правильный статус выхода. (В частности, GNU cp вернет статус ноль, когда используется -i и целевой файл уже существует, что является не желаемым поведением.)

При проектировании системы архивирования учтите, что произойдет, если команда архивации или библиотека несколько раз не смогут выполниться из-за требования вмешательства оператора или из-за нехватки места в архиве. Например, это может произойти, если вы записываете на ленту без автоматического сменного устройства; когда лента заполняется, невозможно производить дальнейшую архивацию до тех пор, пока лента не будет заменена. Вы должны обеспечить адекватное сообщение об ошибке или запросе оператору, чтобы ситуация могла быть разрешена достаточно быстро. Каталог pg_wal/ будет продолжать заполняться файлами сегментов WAL до тех пор, пока ситуация не будет разрешена. (Если файловая система, содержащая каталог pg_wal/, заполнится, Tantor BE выполнит аварийное выключение. Никакие подтвержденные транзакции не будут потеряны, но база данных останется офлайн до освобождения некоторого пространства).

Скорость выполнения команды архивации или библиотеки не имеет значения, пока она может справиться с средней скоростью генерации данных WAL вашим сервером. Нормальная работа продолжается даже в случае небольшой задержки процесса архивации. Если архивация существенно отстает, это увеличит объем данных, которые могут быть потеряны в случае катастрофы. Это также означает, что каталог pg_wal/ будет содержать большое количество сегментных файлов, которые еще не были архивированы, что в конечном итоге может превысить доступное дисковое пространство. Рекомендуется отслеживать процесс архивации, чтобы убедиться, что он работает так, как вы планировали.

При написании команды архивации или библиотеки следует предполагать, что имена файлов для архивации могут быть длиной до 64 символов и могут содержать любую комбинацию букв ASCII, цифр и точек. Необходимо сохранить оригинальное относительное расположение файла (%p) не требуется, но необходимо сохранить имя файла (%f).

Обратите внимание, что хотя архивирование WAL позволит восстановить все изменения, внесенные в данные в вашей базе данных Tantor BE, оно не восстановит изменения, внесенные в файлы конфигурации (то есть postgresql.conf, pg_hba.conf и pg_ident.conf), поскольку они редактируются вручную, а не через SQL-операции. Возможно, вам захочется сохранить файлы конфигурации в месте, которое будет резервироваться вашими обычными процедурами резервного копирования файловой системы. См. Раздел 18.2 для получения информации о том, как переместить файлы конфигурации.

Команда архивации или функция вызываются только для завершенных сегментов WAL. Следовательно, если ваш сервер генерирует только небольшой трафик WAL (или имеет периоды простоя, когда это происходит), между завершением транзакции и ее безопасной записью в архивное хранилище может быть длительная задержка. Чтобы ограничить возраст неархивированных данных, вы можете установить archive_timeout, чтобы заставить сервер переключаться на новый файл сегмента WAL хотя бы столько раз. Обратите внимание, что архивированные файлы, которые архивируются раньше из-за принудительного переключения, все равно имеют ту же длину, что и полностью заполненные файлы. Поэтому не рекомендуется устанавливать очень короткий archive_timeout - это приведет к раздутию вашего архивного хранилища. Обычно разумными являются значения archive_timeout в минуту или около того.

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

Когда wal_level установлен в minimal, некоторые SQL-команды оптимизируются для избежания записи в WAL, как описано в Раздел 14.4.7. Если архивирование или потоковая репликация были включены во время выполнения одного из этих операторов, в WAL не будет достаточно информации для восстановления из архива. (Восстановление после сбоя не затрагивается). Поэтому wal_level может быть изменен только при запуске сервера. Однако archive_command и archive_library могут быть изменены с помощью перезагрузки файла конфигурации. Если вы архивируете через оболочку и хотите временно остановить архивирование, один из способов сделать это - установить archive_command в пустую строку (''). Это приведет к накоплению WAL-файлов в каталоге pg_wal/ до тех пор, пока не будет установлена рабочая archive_command.

24.3.2. Создание базовой резервной копии #

Самый простой способ выполнить базовое резервное копирование - использовать инструмент pg_basebackup. Он может создавать базовое резервное копирование как обычные файлы, так и в виде tar-архива. Если требуется больше гибкости, чем может предоставить pg_basebackup, можно также создать базовое резервное копирование с использованием низкоуровневого API (см. Раздел 24.3.3).

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

Для использования резервной копии необходимо сохранить все файлы сегментов WAL, сгенерированные во время и после резервного копирования файловой системы. Чтобы помочь вам в этом, процесс создания базовой резервной копии создает файл истории резервной копии, который немедленно сохраняется в области архива WAL. Этот файл назван по имени первого файла сегмента WAL, который вам нужен для резервного копирования файловой системы. Например, если начальный файл журнала предзаписи имеет имя 0000000100001234000055CD, то файл истории резервной копии будет назван примерно так: 0000000100001234000055CD.007C9330.backup. (Вторая часть имени файла означает точное положение внутри файла журнала предзаписи и обычно может быть проигнорирована). После того, как вы безопасно заархивировали резервную копию файловой системы и файлы сегментов WAL, использованные во время резервного копирования (как указано в файле истории резервной копии), все архивированные сегменты WAL с числовыми именами, меньшими, больше не нужны для восстановления резервной копии файловой системы и могут быть удалены. Однако рекомендуется сохранить несколько наборов резервных копий, чтобы быть абсолютно уверенным в возможности восстановления данных.

Файл истории резервных копий - это всего лишь небольшой текстовый файл. Он содержит строку метки, которую вы указали для pg_basebackup, а также начальное и конечное время и WAL-сегменты резервной копии. Если вы использовали метку для идентификации связанного файла дампа, то архивный файл истории достаточно, чтобы узнать, какой файл дампа восстановить.

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

24.3.3. Создание базовой резервной копии с использованием низкоуровневого API #

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

Возможно одновременное выполнение нескольких резервных копий (как тех, которые запущены с использованием этого API резервного копирования, так и тех, которые запущены с использованием pg_basebackup).

  1. Убедитесь, что архивирование WAL включено и работает.

  2. Подключитесь к серверу (не важно к какой базе данных) в качестве пользователя с правами на выполнение функции pg_backup_start (суперпользователь или пользователь, которому было предоставлено право EXECUTE на эту функцию) и выполните команду:

    SELECT pg_backup_start(label => 'label', fast => false);
    

    где label - это любая строка, которую нужно использовать для уникальной идентификации этой операции резервного копирования. Соединение, вызывающее pg_backup_start, должно быть поддержано до конца резервного копирования, иначе резервное копирование будет автоматически прервано.

    Все резервные копии в режиме онлайн всегда запускаются в начале контрольной точки. По умолчанию, pg_backup_start будет ожидать завершения следующей регулярно запланированной контрольной точки, что может занять длительное время (см. параметры конфигурации checkpoint_timeout и checkpoint_completion_target). Это обычно предпочтительно, так как это минимизирует влияние на работающую систему. Если нужно начать резервное копирование как можно скорее, передайте true в качестве второго параметра в pg_backup_start и он запросит немедленную контрольную точку, которая завершится как можно быстрее, используя максимально возможное количество I/O.

  3. Выполните резервное копирование, используя любое удобное средство резервного копирования файловой системы, такое как tar или cpio (не pg_dump или pg_dumpall). Необходимо и не желательно останавливать нормальную работу базы данных во время выполнения этой операции. См. Раздел 24.3.3.1 для учета некоторых моментов при выполнении этого резервного копирования.

  4. В том же соединении, что и ранее, выполните команду:

    SELECT * FROM pg_backup_stop(wait_for_archive => true);
    

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

    Функция pg_backup_stop вернет одну строку с тремя значениями. Второе из этих полей должно быть записано в файл с именем backup_label в корневом каталоге резервной копии. Третье поле должно быть записано в файл с именем tablespace_map, если поле не пустое. Эти файлы являются важными для работы резервной копии и должны быть записаны байт в байт без изменений, что может потребовать открытия файла в двоичном режиме.

  5. После архивации активных файлов сегментов WAL во время резервного копирования вы закончили. Файл, идентифицированный первым возвращаемым значением функции pg_backup_stop, является последним сегментом, который требуется для формирования полного набора файлов резервной копии. На основном сервере, если archive_mode включен и параметр wait_for_archive установлен в true, функция pg_backup_stop не возвращает управление до тех пор, пока последний сегмент не будет заархивирован. На резервном сервере archive_mode должен быть всегда, чтобы функция pg_backup_stop ожидала. Архивация этих файлов происходит автоматически, так как вы уже настроили archive_command или archive_library. В большинстве случаев это происходит быстро, но рекомендуется следить за системой архивации, чтобы убедиться, что нет задержек. Если процесс архивации отстает из-за сбоев в команде архивации или библиотеке, он будет продолжать повторять попытки до тех пор, пока архивация не будет успешной и резервное копирование не будет завершено. Если нужно установить ограничение времени выполнения функции pg_backup_stop, установите соответствующее значение pg_backup_stop, но имейте в виду, что если pg_backup_stop завершается из-за этого, ваше резервное копирование может быть недействительным.

    Если процесс резервного копирования отслеживает и гарантирует, что все файлы сегментов WAL, необходимые для резервной копии, успешно архивированы, то параметр wait_for_archive (который по умолчанию установлен в true) может быть установлен в false, чтобы функция pg_backup_stop вернула управление сразу после записи записи о завершении резервного копирования в WAL. По умолчанию функция pg_backup_stop будет ожидать, пока все WAL-файлы не будут архивированы, что может занять некоторое время. Этот параметр должен использоваться с осторожностью: если архивация WAL не отслеживается правильно, то резервная копия может не содержать все файлы WAL и, следовательно, будет неполной и не сможет быть восстановлена.

24.3.3.1. Резервное копирование каталога данных #

Некоторые инструменты резервного копирования файловой системы выдают предупреждения или ошибки, если файлы, которые они пытаются скопировать, изменяются во время копирования. При создании базовой резервной копии активной базы данных такая ситуация является нормальной и не является ошибкой. Однако необходимо убедиться, что вы можете отличить такие жалобы от реальных ошибок. Например, некоторые версии приложения rsync возвращают отдельный код завершения для исчезнувших исходных файлов, и вы можете написать скрипт-драйвер, чтобы принять этот код завершения как случай без ошибок. Кроме того, некоторые версии GNU tar возвращают код ошибки, неотличимый откритической ошибки, если файл был обрезан во время копирования tar. К счастью, версии GNU tar 1.16 и более поздние завершаются с кодом 1, если файл был изменен во время резервного копирования, и с кодом 2 для других ошибок. С версии GNU tar 1.23 и более поздних вы можете использовать опции предупреждения --warning=no-file-changed --warning=no-file-removed, чтобы скрыть связанные предупреждающие сообщения.

Убедитесь, что ваша резервная копия включает все файлы в каталоге кластера базы данных (например, /usr/local/pgsql/data). Если вы используете табличные пространства, которые не находятся внутри этого каталога, будьте внимательны и включите их в резервную копию (и убедитесь, что ваша резервная копия архивирует символические ссылки как ссылки, иначе восстановление повредит ваши табличные пространства).

Вы должны, однако, исключить из резервной копии файлы в подкаталоге pg_wal/ кластера. Это небольшое изменение стоит сделать, потому что оно снижает риск ошибок при восстановлении. Это легко организовать, если pg_wal/ является символической ссылкой, указывающей на место вне каталога кластера, что является стандартной настройкой для повышения производительности. Также можно исключить postmaster.pid и postmaster.opts, которые содержат информацию о работающем postmaster, а не о postmaster, который в конечном итоге будет использовать эту резервную копию. (Эти файлы могут запутать pg_ctl).

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

Содержимое каталогов pg_dynshmem/, pg_notify/, pg_serial/, pg_snapshots/, pg_stat_tmp/ и pg_subtrans/ (но не сами каталоги) можно опустить из резервной копии, так как они будут инициализированы при запуске постмастера.

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

pg_internal.init файлы могут быть не указаны из резервной копии, если найден файл с таким именем. Эти файлы содержат данные кеша отношений, которые всегда перестраиваются при восстановлении.

Файл метки резервной копии включает строку метки, которую вы указали для pg_backup_start, а также время запуска pg_backup_start и имя начального WAL-файла. В случае путаницы можно просмотреть содержимое файла резервной копии и точно определить, из какой сессии резервного копирования был получен файл дампа. Файл карты табличных пространств включает имена символических ссылок, так как они существуют в каталоге pg_tblspc/, и полный путь каждой символической ссылки. Эти файлы не просто для вашей информации; их наличие и содержимое критически важны для правильной работы процесса восстановления системы.

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

24.3.4. Восстановление с использованием непрерывной резервной копии архива #

Хорошо, случилось самое худшее и вам нужно восстановиться из резервной копии. Вот процедура:

  1. Остановите сервер, если он работает.

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

  3. Удалите все существующие файлы и подкаталоги в каталоге данных кластера и в корневых каталогах всех используемых вами табличных пространств.

  4. Восстановите файлы базы данных из резервной копии файловой системы. Убедитесь, что они восстановлены с правильными правами доступа (пользователь системы баз данных, а не root!) и с правильными разрешениями. Если вы используете табличные пространства, убедитесь, что символические ссылки в pg_tblspc/ были правильно восстановлены.

  5. Удалите все файлы, находящиеся в pg_wal/. Они были получены из резервной копии файловой системы и, скорее всего, устарели, а не актуальны. Если вы вообще не архивировали pg_wal/, то пересоздайте его с правильными разрешениями, тщательно убедившись, что вы восстановили его как символическую ссылку, если ранее она была настроена таким образом.

  6. Если у вас есть неархивированные файлы сегментов WAL, которые вы сохранили на шаге 2, скопируйте их в pg_wal/. (Лучше скопировать их, а не перемещать, чтобы у вас остались исходные файлы, если возникнет проблема и вам придется начать сначала).

  7. Установите настройки восстановления в файле postgresql.conf (см. Раздел 18.5.5) и создайте файл recovery.signal в каталоге данных кластера. Возможно, вам также потребуется временно изменить файл pg_hba.conf, чтобы предотвратить подключение обычных пользователей, пока вы не убедитесь в успешном восстановлении.

  8. Запустите сервер. Сервер перейдет в режим восстановления и продолжит чтение необходимых архивных файлов журнала предзаписи. Если восстановление будет прервано из-за внешней ошибки, сервер может быть просто перезапущен, и он продолжит восстановление. По завершении процесса восстановления сервер удалит recovery.signal (чтобы предотвратить случайное повторное вход в режим восстановления позже) и затем начнет нормальные операции с базой данных.

  9. Проверьте содержимое базы данных, чтобы убедиться, что вы восстановились в желаемое состояние. Если нет, вернитесь к шагу 1. Если все в порядке, разрешите вашим пользователям подключаться, восстановив pg_hba.conf в нормальное состояние.

Ключевой частью всего этого является настройка конфигурации восстановления, которая описывает, как вы хотите восстановить и до какого момента должно выполняться восстановление. Единственное, что вы абсолютно должны указать, это restore_command, который сообщает Tantor BE, как извлекать архивированные сегменты WAL файлов. Как и archive_command, это строка команд оболочки. Она может содержать %f, который заменяется именем нужного WAL файла, и %p, который заменяется именем пути для копирования WAL файла. (Имя пути относительно текущего рабочего каталога, т.е. каталога данных кластера.) Напишите %%, если вам нужно вставить фактический символ % в команду. Самая простая полезная команда выглядит примерно так:

restore_command = 'cp /mnt/server/archivedir/%f %p'

который скопирует ранее архивированные сегменты WAL из каталога /mnt/server/archivedir. Конечно, вы можете использовать что-то гораздо более сложное, возможно, даже оболочку, которая запросит оператору подключить соответствующую ленту.

Важно, чтобы команда возвращала ненулевой код завершения в случае ошибки. Команда будет вызываться для файлов, которые отсутствуют в архиве; она должна возвращать ненулевой код при запросе таких файлов. Это не является ошибочным состоянием. Исключение составляет случай, когда команда была прервана сигналом (кроме SIGTERM, который используется при остановке сервера базы данных) или ошибкой оболочки (например, команда не найдена), в этом случае восстановление будет прервано и сервер не запустится.

Не все запрашиваемые файлы будут файлами сегментов WAL; также следует ожидать запросов на файлы с суффиксом .history. Также имейте в виду, что базовое имя пути %p будет отличаться от %f; не ожидайте их взаимозаменяемости.

WAL сегменты, которые не могут быть найдены в архиве, будут искаться в pg_wal/; это позволяет использовать недавно неархивированные сегменты. Однако, сегменты, доступные из архива, будут использоваться в приоритете перед файлами в pg_wal/.

Обычно восстановление будет происходить через все доступные сегменты WAL, восстанавливая базу данных до текущей точки во времени (или как можно ближе к ней, учитывая доступные сегменты WAL). Поэтому нормальное восстановление закончится сообщением "файл не найден", точный текст сообщения об ошибке зависит от вашего выбора команды восстановления restore_command. Также можно увидеть сообщение об ошибке в начале восстановления для файла с именем, например, 00000001.history. Это также нормально и не указывает на проблему в простых ситуациях восстановления; см. подробнее раздел "Резервные копии и временные линии Раздел 24.3.5".

Если нужно восстановиться до какой-либо предыдущей точки во времени (скажем, прямо перед тем, как младший DBA удалил вашу основную транзакционную таблицу), просто укажите требуемую точку остановки. Вы можете указать точку остановки, известную как цель восстановления, либо по дате/времени, либо по имени точки восстановления, либо по завершению определенной транзакции. На момент написания этого документа только опции по дате/времени и по имени точки восстановления являются действительно полезными, поскольку нет инструментов, которые помогли бы вам точно определить, какой идентификатор транзакции использовать.

Примечание

Точка остановки должна быть после времени окончания базового резервного копирования, то есть времени окончания pg_backup_stop. Вы не можете использовать базовое резервное копирование для восстановления до времени, когда это резервное копирование было в процессе. (Чтобы восстановиться до такого времени, необходимо вернуться к предыдущему базовому резервному копированию и продолжить с него).

Если восстановление обнаруживает поврежденные данные WAL, процесс восстановления останавливается в этой точке, и сервер не запускается. В таком случае процесс восстановления может быть повторно запущен с самого начала, указав цель восстановления до точки повреждения, чтобы восстановление могло завершиться нормально. Если восстановление не удалось по внешней причине, такой как сбой системы или недоступность архива WAL, то восстановление может быть просто перезапущено, и оно начнется почти с того места, где оно завершилось. Перезапуск восстановления работает похожим образом на создание контрольной точки в нормальной работе: сервер периодически записывает все свое состояние на диск, а затем обновляет файл pg_control, чтобы указать, что уже обработанные данные WAL не нужно сканировать снова.

24.3.5. Графики времени #

Возможность восстановления базы данных до предыдущего момента времени создает некоторые сложности, сравнимые с научно-фантастическими историями о путешествиях во времени и параллельных вселенных. Например, в исходной истории базы данных предположим, что вы удалили критическую таблицу в 17:15 вечера во вторник, но не осознали свою ошибку до полудня в среду. Не смущаясь, вы берете резервную копию, восстанавливаете до момента времени 17:14 вечера во вторник и продолжаете работу. В этой истории вселенной базы данных вы никогда не удалили таблицу. Но предположим, что позже вы понимаете, что это была не такая уж хорошая идея, и вы хотели бы вернуться к какому-то моменту среды утром в исходной истории. Вы не сможете это сделать, если ваша база данных, работая, перезаписала некоторые файлы сегментов WAL, которые привели к моменту времени, к которому нужно вернуться. Таким образом, чтобы избежать этого, необходимо различать серию записей WAL, сгенерированных после выполнения восстановления до момента времени, от тех, которые были сгенерированы в исходной истории базы данных.

Чтобы справиться с этой проблемой, Tantor BE имеет понятие временные шкалы. Всякий раз, когда завершается архивное восстановление, создается новая временная шкала для идентификации серии записей WAL, сгенерированных после этого восстановления. Номер временной шкалы является частью имен файлов сегментов WAL, поэтому новая временная шкала не перезаписывает данные WAL, сгенерированные предыдущими временными шкалами. Например, в имени файла WAL 0000000100001234000055CD, ведущий 00000001 является идентификатором временной шкалы в шестнадцатеричном формате. (Обратите внимание, что в других контекстах, таких как сообщения журнала сервера, идентификаторы временных шкал обычно печатаются в десятичном формате.)

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

Каждый раз, когда создается новая временная шкала, Tantor BE создает файл истории временных шкал, который показывает, от какой временной шкалы она отклонилась и когда. Эти файлы истории необходимы для того, чтобы система могла выбрать правильные файлы сегментов WAL при восстановлении из архива, содержащего несколько временных шкал. Поэтому они архивируются в область архива WAL так же, как и файлы сегментов WAL. Файлы истории - это просто небольшие текстовые файлы, поэтому их долго хранить недорого (в отличие от больших файлов сегментов). Если хотите, вы можете добавить комментарии в файл истории, чтобы записать свои собственные заметки о том, как и почему была создана эта конкретная временная шкала. Такие комментарии будут особенно полезны, когда у вас есть множество разных временных шкал в результате экспериментов.

Сохраняется стандартное поведение восстановления до последней найденной временной линии в архиве. Если нужно восстановиться до временной линии, которая была актуальной на момент создания базовой резервной копии или в конкретную дочернюю временную линию (то есть, нужно вернуться к состоянию, которое было сгенерировано после попытки восстановления), необходимо указать current или идентификатор целевой временной линии в recovery_target_timeline. Вы не можете восстановиться во временные линии, которые отклонились раньше базовой резервной копии.

24.3.6. Советы и примеры #

Ниже приведены некоторые советы по настройке непрерывного архивирования.

24.3.6.1. Отдельные горячие резервные копии #

Возможно использовать средства резервного копирования Tantor BE для создания автономных горячих резервных копий. Это резервные копии, которые нельзя использовать для восстановления в определенный момент времени, но обычно они гораздо быстрее резервного копирования и восстановления, чем дампы pg_dump. (Они также гораздо больше, чем дампы pg_dump, поэтому в некоторых случаях преимущество в скорости может быть уменьшено).

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

24.3.6.2. Сжатые архивные журналы #

Если размер хранилища архива вызывает беспокойство, вы можете использовать gzip для сжатия файлов архива.

archive_command = 'gzip < %p > /mnt/server/archivedir/%f.gz'

Вы затем должны использовать gunzip во время восстановления.

restore_command = 'gunzip < /mnt/server/archivedir/%f.gz > %p'

24.3.6.3. archive_command Скрипты #

Многие люди предпочитают использовать сценарии для определения своей команды archive_command, чтобы их запись в файле postgresql.conf выглядела очень просто:

archive_command = 'local_backup_script.sh "%p" "%f"'

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

Примеры требований, которые могут быть решены в рамках сценария, включают:

  • Копирование данных на безопасное удаленное хранилище данных

  • Группировка файлов журнала предзаписи таким образом, чтобы они передавались каждые три часа, а не по одному

  • Взаимодействие с другими программными средствами резервного копирования и восстановления

  • Взаимодействие с программным обеспечением мониторинга для отчетности об ошибках

Подсказка

При использовании сценария archive_command желательно включить logging_collector. Все сообщения, записанные в stderr из сценария, будут отображаться в журнале сервера базы данных, что позволяет легко диагностировать сложные конфигурации в случае их сбоя.

24.3.7. Ограничения в использовании #

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

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

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

Следует также отметить, что формат WAL по умолчанию довольно громоздкий, так как он включает множество снимков страниц диска. Эти снимки страниц предназначены для поддержки восстановления после сбоев, поскольку нам может потребоваться исправить частично записанные страницы диска. В зависимости от вашего аппаратного и программного обеспечения, риск частичных записей может быть достаточно мал, чтобы его можно было игнорировать, в этом случае вы можете значительно уменьшить общий объем архивируемых файлов WAL, отключив снимки страниц с помощью параметра full_page_writes. (Прочтите примечания и предупреждения в Глава 28 перед тем, как это сделать.) Отключение снимков страниц не препятствует использованию WAL для операций PITR. Областью для будущего развития является сжатие архивированных данных WAL путем удаления ненужных копий страниц, даже когда full_page_writes включен. Тем временем администраторы могут захотеть уменьшить количество снимков страниц, включенных в WAL, увеличив параметры интервала контрольных точек настолько, насколько это возможно.