Привет, Я DocuDroid!
Оценка ИИ поиска
Спасибо за оценку нашего ИИ поиска!
Мы будем признательны, если вы поделитесь своими впечатлениями, чтобы мы могли улучшить наш ИИ поиск для вас и других читателей.
GitHub

Инкрементальное резервное копирование

Павел Семёнов

В этом разделе приводится обзор инкрементальных бэкапов в Greengage DB и инструкции по их созданию и восстановлению с помощью утилит gpbackup и gprestore.

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

ВАЖНО

В некоторых СУБД инкрементальные бэкапы сохраняют только отдельные строки, которые были добавлены или изменены. В Greengage DB инкрементальные бэкапы включают всю таблицу, если в ней произошли какие-либо изменения.

В Greengage DB инкрементальные бэкапы создаются и восстанавливаются теми же утилитами, что и обычные — gpbackup и gprestore. Они выявляют и сохраняют только те оптимизированные для добавления (AO) таблицы и партиции, которые были изменены с момента последнего совместимого бэкапа в том же наборе бэкапов. Размер инкрементальных бэкапов меньше, чем у обычных, поскольку gpbackup исключает AO-таблицы, которые не изменялись с момента предыдущего бэкапа. Эта оптимизация применяется к AO-таблицам как строковой, так и колоночной ориентации.

К операциям, после которых AO-таблица считается измененной, относятся:

  • ALTER TABLE

  • DELETE

  • INSERT

  • TRUNCATE

  • UPDATE

  • Удаление и повторное создание таблицы (DROP TABLE и CREATE TABLE).

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

Для партиционированных AO-таблиц экономия места может быть еще больше: в инкрементальный бэкап включаются только измененные конечные партиции. Если партиционированные AO-таблицы спроектированы так, как предполагается (существующие строки редко обновляются), то инкрементальные бэкапы могут значительно сократить как размер, так и длительность бэкапа.

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

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

Наборы бэкапов

Ключевое понятие механизма инкрементальных бэкапов в Greengage DB — это набор бэкапов. Набор бэкапов включает:

  • Один полный (базовый) бэкап — неинкрементальный бэкап, который сохраняет состояние всей базы данных или выбранных объектов (если выполняется частичный бэкап). Он является основой набора бэкапов.

  • Один или несколько инкрементальных бэкапов — каждый инкрементальный бэкап сохраняет только те таблицы, которые изменились после предыдущего бэкапа в этом же наборе: полного или инкрементального.

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

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

Способы создания наборов бэкапов

Существует два способа объединения бэкапов в наборы:

  • Автоматически — по умолчанию Greengage DB использует метаданные истории бэкапов, чтобы найти последний бэкап, параметры которого совместимы с текущим вызовом gpbackup. Этот бэкап автоматически становится базовым для нового инкрементального бэкапа.

  • Вручную — можно явно указать метку времени существующего бэкапа, чтобы использовать его как базу для нового инкрементального бэкапа.

Пример процесса создания инкрементальных бэкапов, приведенный ниже, показывает, как создавать бэкапы обоими способами.

Совместимость параметров бэкапов

Все бэкапы в одном наборе должны быть созданы с совместимыми параметрами gpbackup. gpbackup проверяет это при выборе базового бэкапа для нового инкрементального бэкапа.

Бэкапы считаются совместимыми для объединения в один набор, если у них совпадают следующие параметры:

  • --dbname — бэкапы должны хранить одну и ту же базу данных.

  • --leaf-partition-data — обязательный параметр: базовый полный бэкап и все инкрементальные бэкапы в наборе должны быть созданы с --leaf-partition-data.

  • --backup-dir — если используется пользовательский каталог для бэкапа, он должен быть одинаковым для всего набора.

  • --single-data-file — все бэкапы в наборе должны одновременно использовать или не использовать хранение данных в одном файле.

  • --plugin-config — если базовый бэкап был создан с использованием плагина, все последующие инкрементальные бэкапы должны использовать тот же плагин и тот же файл конфигурации.

  • --no-compression — если один из бэкапов в наборе не использует сжатие, остальные также должны быть без сжатия.

    ПРИМЕЧАНИЕ

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

  • Для частичных бэкапов фильтры схем и таблиц (такие как --include-schema или --include-table) должны быть одинаковыми. При фильтрации по схеме проверяется только имя схемы, а не содержащиеся в ней объекты.

Создание инкрементального бэкапа

Чтобы создать инкрементальный бэкап базы данных, выполните команду gpbackup с параметрами --incremental и --leaf-partition-data:

$ gpbackup --dbname marketplace --leaf-partition-data --incremental

При запуске с этими параметрами gpbackup ищет в истории бэкапов совместимый бэкап, который можно использовать как базу для нового. Если он найден, его метка времени отображается в выводе утилиты, например:

[INFO]:-Basing incremental backup off of backup with timestamp = 20251017091457

Затем gpbackup формирует состав инкрементального бэкапа, то есть AO-таблицы и партиции, измененные с момента базового бэкапа. Состав определяет, какие данные будут сохранены в каталоги бэкапа на сегмент-хостах. Все heap-таблицы всегда включаются в инкрементальные бэкапы, независимо от того, были ли они изменены.

Если совместимый базовый бэкап не найден, gpbackup завершает работу с ошибкой следующего вида:

[CRITICAL]:-There was no matching previous backup found with the flags provided. Please take a full backup.

В этом случае создайте новый полный бэкап с совместимыми параметрами и повторите попытку создания инкрементального.

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

<...>
incremental:              True
incremental backup set:
20251017091457
20251017091528
<...>

Чтобы явно указать, на каком предыдущем бэкапе должен основываться инкрементальный, используйте параметр --from-timestamp и укажите метку времени этого бэкапа:

$ gpbackup --dbname marketplace --leaf-partition-data --incremental --from-timestamp 20251017091457

Пример процесса инкрементального резервного копирования

В этом разделе приведен пошаговый пример использования инкрементальных бэкапов в Greengage DB. Пусть демонстрационная база данных marketplace содержит таблицы разных типов, показанные в таблице ниже.

Имя Тип хранения OID

customers

heap

19135

products

оптимизированная для добавления

19125

sales

оптимизированная для добавления, партиционированная

19357, 19366, 19375, 19384

ПРИМЕЧАНИЕ

OID таблиц используются для идентификации файлов данных, в которых хранится содержимое таблиц. Они указаны в файле содержания бэкапа (gpbackup_YYYMMDDhhmmss_toc.yaml в каталоге бэкапа на мастер-хосте). Для партиционированной таблицы sales указаны OID конечных партиций.

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

Шаг 1: создание полного бэкапа

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

Бэкап должен быть создан с параметром --leaf-partition-data:

$ gpbackup --dbname marketplace --leaf-partition-data

Эта команда создает обычный бэкап Greengage DB, который при необходимости можно восстановить независимо. В данном примере бэкап имеет следующую метку времени (1 января):

[INFO]:-Backup Timestamp = 20250101091457

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

$ ls -l /data1/primary/gpseg0/backups/20250101/20250101091457/
total 76
-rw------- 1 gpadmin gpadmin 39724 Jan  1 09:14 gpbackup_0_20250101091457_19125.gz
-rw------- 1 gpadmin gpadmin  1123 Jan  1 09:14 gpbackup_0_20250101091457_19135.gz
-rw------- 1 gpadmin gpadmin    20 Jan  1 09:14 gpbackup_0_20250101091457_19357.gz
-rw------- 1 gpadmin gpadmin  8530 Jan  1 09:14 gpbackup_0_20250101091457_19366.gz
-rw------- 1 gpadmin gpadmin  6179 Jan  1 09:14 gpbackup_0_20250101091457_19375.gz
-rw------- 1 gpadmin gpadmin  7392 Jan  1 09:14 gpbackup_0_20250101091457_19384.gz

Каждый файл соответствует таблице или партиции в базе данных: customers (19135), products (19125) и четырем партициям таблицы sales.

Шаг 2: создание набора бэкапов

Для создания набора бэкапов нужно добавить к базовому бэкапу инкрементальный. Чтобы создать первый инкрементальный бэкап, выполните ту же команду, добавив параметры --incremental и --leaf-partition-data:

$ gpbackup --dbname marketplace --leaf-partition-data --incremental

При запуске с этими параметрами gpbackup автоматически ищет совместимый полный бэкап для использования в качестве основы. В выводе утилиты отображаются метки времени нового и базового бэкапов (1 и 2 января):

[INFO]:-Backup Timestamp = 20250102091528
<...>
[INFO]:-Basing incremental backup off of backup with timestamp = 20250101091457

После завершения новый инкрементальный бэкап образует набор бэкапов вместе с базовым полным. Эта информация отображается в отчете о бэкапе:

$ cat /data1/master/gpseg-1/backups/20250102/20250102091528/gpbackup_20250102091528_report
<...>
incremental:              True
incremental backup set:
20250101091457
20250102091528
<...>

Чтобы проверить, какие данные были включены, просмотрите каталог бэкапа на сегменте:

$ ls -l /data1/primary/gpseg0/backups/20250102/20250102091528/
total 56
-rw------- 1 gpadmin gpadmin 39724 Jan  2 09:15 gpbackup_0_20250102091528_19125.gz
-rw------- 1 gpadmin gpadmin  1123 Jan  2 09:15 gpbackup_0_20250102091528_19135.gz
-rw------- 1 gpadmin gpadmin  8530 Jan  2 09:15 gpbackup_0_20250102091528_19366.gz

Здесь видно, что инкрементальный бэкап включает только:

  • heap-таблицу customers (19135);

  • измененную AO-таблицу products (19125);

  • измененную партицию таблицы sales (19366).

Неизмененные партиции sales пропущены, так как их данные уже сохранены в базовом бэкапе.

С этого момента можно либо восстановить базу данных из этого набора бэкапов, либо продолжить добавлять в него новые инкрементальные бэкапы.

Шаг 3: добавление новых инкрементальных бэкапов

Чтобы добавить очередной инкрементальный бэкап в тот же набор, повторите ту же команду:

$ gpbackup --dbname marketplace --leaf-partition-data --incremental

Новый бэкап (от 3 января) автоматически основывается на последнем бэкапе набора (от 2 января):

[INFO]:-Backup Timestamp = 20250103091621
<...>
[INFO]:-Basing incremental backup off of backup with timestamp = 20250102091528

Теперь набор включает три бэкапа:

$ cat /data1/master/gpseg-1/backups/20250103/20250103091621/gpbackup_20250103091621_report
<...>
incremental:              True
incremental backup set:
20250101091457
20250102091528
20250103091621
<...>

Каждый последующий инкрементальный бэкап добавляется в набор по цепочке.

Проверьте содержимое последнего бэкапа:

$ ls -l /data1/primary/gpseg0/backups/20250103/20250103091621/
total 16
-rw------- 1 gpadmin gpadmin 1123 Jan 03 09:16 gpbackup_0_20250103091621_19135.gz
-rw------- 1 gpadmin gpadmin 8530 Jan 03 09:16 gpbackup_0_20250103091621_19366.gz

Вывод показывает, что с момента предыдущего инкрементального бэкапа была изменена только партиция таблицы sales с OID 19366. Heap-таблица customers (19135) включается в инкрементальные бэкапы всегда.

Шаг 4: создание инкрементального бэкапа от указанной метки времени

Иногда может потребоваться создать инкрементальный бэкап от более раннего момента времени, например, чтобы заменить несколько бэкапов одним или зафиксировать выбранный диапазон изменений для восстановления.

Для этого выполните gpbackup с параметром --from-timestamp, передав временную метку нужного базового бэкапа:

$ gpbackup --dbname marketplace --leaf-partition-data --incremental --from-timestamp 20250102091528

В этом случае gpbackup создаст новый бэкап на основе указанного базового, даже если доступны более новые совместимые бэкапы:

[INFO]:-Backup Timestamp = 20250104094401
<...>
[INFO]:-Basing incremental backup off of backup with timestamp = 20250102091528

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

$ cat /data1/master/gpseg-1/backups/20250104/20250104094401/gpbackup_20250104094401_report
incremental:              True
incremental backup set:
20250101091457
20250102091528
20250104094401
ПРИМЕЧАНИЕ

Ранее созданный бэкап с меткой времени 20250103091621 остается действительным в рамках своего набора бэкапов, созданного на предыдущем шаге.

Восстановление инкрементальных бэкапов

ВАЖНО

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

Существуют два основных способа использования инкрементальных бэкапов при восстановлении:

  • Полное восстановление — восстанавливает всю базу данных из полного набора бэкапов.

  • Инкрементальное восстановление — восстанавливает набор данных из отдельного инкрементального бэкапа.

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

Для полного восстановления базы данных из набора бэкапов выполните gprestore с параметром --timestamp. В значении опции укажите последнюю резервную копию в наборе — ту, которая определяет целевое состояние базы данных.

Например, для восстановления набора резервных копий, созданного ранее, используйте метку времени 20250103091621:

$ gprestore --timestamp 20250103091621

Команда восстанавливает базу данных следующим образом:

  • AO-таблицы и партиции восстанавливаются из их последних версий, которые могут находиться в разных бэкапах набора.

  • Heap-таблицы восстанавливаются из указанного бэкапа, то есть последнего в наборе.

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

При использовании опции --verbose вывод команды показывает, из какого именно бэкапа восстанавливается каждая таблица. Например:

[DEBUG]:-Restoring data for 1 tables from backup with timestamp: 20250102091528
[DEBUG]:-Executing "COPY public.products(id,name,description,created_at,price) FROM PROGRAM 'cat <SEG_DATA_DIR>/backups/20250102/20250102091528/gpbackup_<SEGID>_20250102091528_19125.gz | gzip -d -c' WITH CSV DELIMITER ',' ON SEGMENT;" on master
<...>
[DEBUG]:-Restoring data for 2 tables from backup with timestamp: 20250103091621
[DEBUG]:-Executing "COPY public.customers(id,name) FROM PROGRAM 'cat <SEG_DATA_DIR>/backups/20250103/20250103091621/gpbackup_<SEGID>_20250103091621_19135.gz | gzip -d -c' WITH CSV DELIMITER ',' ON SEGMENT;" on master
<...>
[DEBUG]:-Restoring data for 3 tables from backup with timestamp: 20250101091457
[DEBUG]:-Executing "COPY public.sales_1_prt_other_dates FROM PROGRAM 'cat <SEG_DATA_DIR>/backups/20250101/20250101091457/gpbackup_<SEGID>_20250101091457_19357.gz | gzip -d -c' WITH CSV DELIMITER ',' ON SEGMENT;" on master

Этот лог показывает, как gprestore выбирает бэкап для восстановления каждой таблицы на основе времени последних изменений.

Поскольку любое подмножество бэкапов из набора, идущее в его начале последовательно, также является набором бэкапов, вы можете восстановить базу данных к более раннему состоянию по его метке времени. Например, восстановление из инкрементального бэкапа 20250102091528 вернет базу данных к состоянию на 2 января.

Инкрементальное восстановление

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

Инкрементальное восстановление восстанавливает данные, хранимые в одном инкрементальном бэкапе:

  • heap-таблицы;

  • AO-таблицы, которые были изменены между созданием бэкапа и его базового бэкапа;

  • партиции таблиц, измененные в тот же период.

ВНИМАНИЕ

При инкрементальном восстановлении gprestore очищает целевую таблицу и загружает ее заново из указанного бэкапа. Для партиционированных таблиц эта операция выполняется на уровне партиций: партиции, не включенные в бэкап, остаются без изменений, а измененные партиции перезаписываются.

Важно понимать, что инкрементальное восстановление не изменяет отдельные строки таблиц. Вместо этого оно заменяет целые таблицы или партиции их полными копиями из бэкапа. Например, если в AO-таблицу была добавлена одна строка, инкрементальное восстановление приведет всю таблицу к состоянию после этой вставки, а не просто добавит недостающую строку. Аналогично, для партиционированных таблиц полностью перезаписываются все измененные партиции.

Для выполнения инкрементального восстановления укажите временную метку бэкапа и две дополнительные опции: --incremental и --data-only. Целевые таблицы должны существовать в базе данных на момент восстановления.

$ gprestore --timestamp 20250103091621 --incremental --data-only

Эта команда восстанавливает только данные, сохраненные в инкрементальном бэкапе 20250103091621. Таблицы, не включенные в этот бэкап, остаются неизмененными.