Как работает POINT-IN-TIME RECOVERY в PostgreSQL
На рис. 118 показана основная концепция PITR. В режиме PITR PostgreSQL воспроизводит WAL-данные архивных журналов на базовой резервной копии, начиная с точки REDO, созданной командой pg_backup_start, и заканчивая точкой, которую Вы хотите восстановить.
Итак, давайте посмотрим, как же работает PITR.
Предположим, что 1 января 2024 года в 12:05 Вы допустили ошибку. В этом случае Вам следует удалить кластер базы данных и восстановить резервную копию базы, сделанную ранее.
В первую очередь необходимо задать команду в параметре 'restore_command', а также установить время в параметре 'recovery_target_time' на момент, когда Вы допустили ошибку (в данном случае 12:05) в файле postgresql.conf (в версии 11 и более ранних версиях - recovery.conf).
# Place archive logs under /mnt/server/archivedir directory. restore_command = 'cp /mnt/server/archivedir/%f %p' recovery_target_time = "2024-1-1 12:05 GMT"
При запуске PostgreSQL переходит в режим PITR, если в кластере баз данных есть файл 'backup_label', а также файл 'recovery.signal' (в версии 11 и более ранних версиях -'recovery.conf').
Примечание: recovery.conf / recovery.signal
В версии 12 файл recovery.conf был упразднен, теперь все параметры, связанные с восстановлением БД, должны быть записаны в файле postgresql.conf. Более подробную информацию Вы найдете в официальном документе.
В версии 12 и новее при восстановлении сервера из резервной копии в первую очередь необходимо создать пустой файл recovery.signal в каталоге кластера баз данных.
$ touch /usr/local/pgsql/data/recovery.signal
Процесс PITR (Point-in-Time Recovery) практически не отличается от обычного процесса восстановления, описанного в разделе 9.8. Главные отличия одного процесса от другого заключаются в следующем:
- Откуда считываются сегменты WAL/журналы архива?
- Обычный режим восстановления - из подкаталога pg_wal (в версии 9.6 и более ранних версиях - подкаталог pg_xlog) в базовом каталоге.
- Режим PITR - из архивного каталога, заданного в параметре 'archive_command'.
- Откуда считывается местоположение контрольной точки?
- Обычный режим восстановления - из файла pg_control.
- Режим PITR - из файла backup_label.
Итак, процесс PITR выглядит следующим образом:
(1) Для того, чтобы найти точку REDO, PostgreSQL считывает значение 'CHECKPOINT LOCATION' из файла backup_label с помощью внутренней функции read_backup_label();
(2) PostgreSQL считывает некоторые значения параметров из postgresql.conf, такие как 'restore_command' и 'recovery_target_time');
(3) PostgreSQL начинает воспроизведение WAL-данных с точки REDO, которую можно получить из значения параметра 'CHECKPOINT LOCATION'. Данные WAL считываются из архивных журналов, которые копируются из архивной области во временную область путем выполнения команды, записанной в параметре 'restore_command'. (Скопированные файлы журналов во временной области удаляются после использования).
В нашем случае PostgreSQL считывает и воспроизводит данные WAL из точки REDO до временной метки '2024-1-1 12:05:00', поскольку параметр 'recovery_target_time' установлен именно на эту временную метку.
(4) По завершении процесса восстановления в подкаталоге pg_wal (в версиях 9.6 и более ранних - в подкаталоге pg_xlog) создается файл timeline history, например '00000002.history'.
Если включена функция архивирования журналов, то такой же файл создается и в каталоге архива. Содержимое и роль этого файла описаны в следующих разделах.
Записи действий фиксации и отмены содержат метку времени, в которую каждое действие было выполнено (часть данных XLOG для обоих действий определена в xl_xact_commit и xl_xact_abort соответственно).
xl_xact_commit
typedef struct xl_xact_commit
{
TimestampTz xact_time; /* time of commit */
uint32 xinfo; /* info flags */
int nrels; /* number of RelFileNodes */
int nsubxacts; /* number of subtransaction XIDs */
int nmsgs; /* number of shared inval msgs */
Oid dbId; /* MyDatabaseId */
Oid tsId; /* MyDatabaseTableSpace */
/* Array of RelFileNode(s) to drop at commit */
RelFileNode xnodes[1]; /* VARIABLE LENGTH ARRAY */
/* ARRAY OF COMMITTED SUBTRANSACTION XIDs FOLLOWS */
/* ARRAY OF SHARED INVALIDATION MESSAGES FOLLOWS */
} xl_xact_commit;l_xact_abort
ypedef struct xl_xact_abort
{
TimestampTz xact_time; /* time of abort */
int nrels; /* number of RelFileNodes */
int nsubxacts; /* number of subtransaction XIDs */
/* Array of RelFileNode(s) to drop at abort */
RelFileNode xnodes[1]; /* VARIABLE LENGTH ARRAY */
/* ARRAY OF ABORTED SUBTRANSACTION XIDs FOLLOWS */
} xl_xact_abort;
Поэтому, если в параметре 'recovery_target_time' задано целевое время, всякий раз, когда воспроизводит XLOG-запись действия фиксации или отмены, PostgreSQL может выбирать, продолжать восстановление или нет. Когда XLOG-запись каждого действия воспроизводится, PostgreSQL сравнивает целевое время и каждую временную метку, записанную в записи, и если временная метка превышает целевое время, процесс PITR завершается.
Примечание:
Функция read_backup_label() определена в src/backend/access/transam/xlog.c.
Структуры xl_xact_commit и xl_xact_abort определены в src/include/access/xact.h.
Примечание: Почему мы можем использовать обычные средства архивации для создания базовой резервной копии?
Процесс восстановления - это процесс восстановления кластера баз данных до согласованного состояния. PITR может восстановить кластер базы данных, даже если базовая резервная копия представляет собой ряд непоследовательных файлов. Именно поэтому мы можем использовать обычные средства архивации без необходимости создания снимков файловой системы или использования каких-либо специальных инструментов.




