02 Занятие 02: Резервное копирование / Базовая резервная копия
Эта страница извлечена из официального PDF в нативный Markdown. Текст слайдов, код и комментарии сохранены в порядке чтения; исходные PDF и HTML остаются эталоном макета. HTML source: dba3_02_backup_base.html Archive: DBA3-handouts-16.zip Страниц PDF: 26
Page 1: Резервное копирование / Базовая резервная копия
Авторские права
© Postgres Professional, 2017–2025 Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов, Алексей Береснев Фото: Олег Бартунов (монастырь Пху и пик Бхрикути, Непал)
Использование материалов курса
Некоммерческое использование материалов курса (презентации, демонстрации) разрешается без ограничений. Коммерческое использование возможно только с письменного разрешения компании Postgres Professional. Запрещается внесение изменений в материалы курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу: edu@postgrespro.ru
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за любые повреждения и убытки, включая потерю дохода, нанесенные прямым или непрямым, специальным или случайным использованием материалов курса. Компания Postgres Professional не предоставляет каких-либо гарантий на материалы курса. Материалы курса предоставляются на основе принципа «как есть» и компания Postgres Professional не обязана предоставлять сопровождение, поддержку, обновления, расширения и изменения.
Page 2: Темы
- Понятие физической резервной копии
- Холодное и горячее резервирование
- Протокол репликации и слот
- Клонирование кластера и архивная копия
- Проверка целостности
- API резервирования
Page 3: Физическая копия
Базовая физическая копия — копия всех файлов кластера
- быстрее, чем логическое резервирование
- восстанавливается статистика
- − можно восстановиться только на совместимой системе
- − и на той же самой основной версии PostgreSQL
- − выборочная копия невозможна, копируется весь кластер
Комментарии преподавателя
Физическое резервирование подразумевает копирование всех файлов, относящихся к кластеру БД (как файлов данных, так и служебных файлов), то есть создание полной двоичной копии.
Копирование файлов работает быстрее, чем выгрузка SQL-команд при логическом резервировании; запустить сервер из созданной физической копии — дело нескольких минут, в отличие от восстановления из логической копии. Кроме того, нет необходимости заново собирать статистику — она также восстанавливается из копии.
Но есть и минусы. Из физической резервной копии можно восстановить систему только на совместимой платформе (та же ОС, та же разрядность, тот же порядок байтов в представлении чисел и т. п.) и только на той же основной версии PostgreSQL. Кроме того, невозможно сделать физическую копию отдельных баз данных кластера, возможно копирование только всего кластера целиком.
Page 4: Холодное резервирование
Выключенный сервер
- если выполнена контрольная точка, то достаточно скопировать файлы
- копию можно развернуть на другом сервере, независимо от PGDATA
- простота
- − требуется прерывание обслуживания
- Снимок файловой системы
- как при неаккуратном выключении: при старте потребуется
- восстановление, но в копию войдут все нужные файлы журнала
- данные, в т. ч. табличные пространства, должны войти в один снимок
- не надо останавливать сервер
- − файловые системы, поддерживающие снимки, работают медленней
Комментарии преподавателя
Смысл холодного резервирования состоит в том, чтобы сделать копию файлов кластера в тот момент, когда данные на диске согласованы, то есть на диск сброшено актуальное состояние всех страниц. Восстановление из такой копии происходит просто: файлы разворачиваются, запускается сервер — и он сразу же готов к работе.
Сделать такую копию можно лишь корректно остановив сервер с выполнением контрольной точки. Минус понятен: необходима остановка сервера (надолго при большом объеме данных).
Время простоя можно сократить за счет предварительного выполнения rsync (или аналогичного инструмента) при работающем сервере. Тогда после останова сервера rsync докопирует только изменения (которых, предположительно, будет немного). Но простоя все равно не избежать.
Другой вариант — сделать несогласованную копию, в которую попадут страницы, сохраненные в разное время. Такая рассогласованность неизбежна при некорректном отключении сервера или при создании снимка файловой системы. В последнем случае все файлы кластера должны попасть в один снимок. Это может оказаться невозможным, если файлы расположены в разных файловых системах.
При восстановлении из несогласованных данных серверу при старте потребуется согласовать страницы. Это обычная автоматическая процедура восстановления после сбоя. Она не представляет проблемы, так как необходимые файлы журнала гарантированно попадут в копию, но потребует некоторого времени.
https://postgrespro.ru/docs/postgresql/16/backup-file
Page 5: Холодная файловая копия
Файлы остановленного кластера можно скопировать и запустить с ними второй сервер. При этом не важно, был ли сервер остановлен корректно. Создадим базу данных и таблицу.
Аварийно останавливаем сервер alpha и копируем файлы на сервер beta:
Сервер beta запускается, восстанавливая согласованность:
Page 6: Горячее резервирование
Работающий сервер
- страницы не согласованы между собой, как при неаккуратном
- выключении
- страница может меняться во время ее копирования
- (проблема неатомарного чтения и записи)
- для восстановления согласованности необходимы журнальные записи
- от последней контрольной точки за все время копирования
- (в процессе копирования сервер может удалить часть файлов)
- не требуется прерывание обслуживания
- − нужны специальные инструменты
Комментарии преподавателя
Горячее резервирование выполняется на работающем сервере, поэтому в копию наверняка попадут несогласованные между собой страницы.
Более того. При резервном копировании данные читаются не через буферный кеш, а напрямую из файлов. Содержимое файлов на диске, очевидно, изменяется во время копирования, а гарантии атомарности чтения/записи страниц PostgreSQL может и не быть (это зависит от файловой системы и оборудования и обсуждается в теме «Настройка журнала» курса DBA2). Поэтому в резервную копию могут попадать «безнадежные» страницы, к которым даже нельзя применить журнальные записи. Это первая сложность.
Вторая сложность состоит в том, что копирование файлов данных может занимать достаточно много времени. Но сервер, после выполнения очередной контрольной точки, может удалить часть файлов журнала, которые уже не нужны ему для восстановления после сбоя, но нужны для резервной копии.
Если не принять специальных мер, сделанная резервная копия будет непригодна для восстановления. Поэтому для горячего резервирования требуются специальные инструменты. PostgreSQL предоставляет низкоуровневый интерфейс, используя который можно реализовать надежное копирование. Этот интерфейс использует и штатная утилита pg_basebackup, и другие сторонние средства резервного копирования.
https://postgrespro.ru/docs/postgresql/16/continuous-archiving#BACKUP-BA SE-BACKUP
Page 7: Протокол репликации
Задачи
- управление резервным копированием и репликацией
- в частности, получение потока журнальных записей
- Обслуживается процессом wal sender
- max_wal_senders = 10
- wal_level = replica или logical, но не minimal
- Подключение
- роль с атрибутом REPLICATION или SUPERUSER
- разрешение на подключение в pg_hba.conf
Комментарии преподавателя
Для упрощения задачи сервер PostgreSQL предоставляет протокол репликации — специальный протокол для управления как собственно репликацией (рассматривается в одноименном модуле), так и резервным копированием. В частности, он позволяет получать поток журнальных записей, которые генерирует сервер.
На сервере подключение по протоколу репликации обслуживается процессом wal sender. Он похож на обычный обслуживающий процесс, который запускается при обычном подключении клиента, но понимает не SQL, а специальные команды. Число одновременно работающих процессов wal_sender ограничено параметром max_wal_senders (значение по умолчанию — 10).
Уровень журнала должен быть не ниже, чем replica. Дело в том, что на уровне minimal такие команды, как CREATE TABLE AS SELECT, CREATE INDEX или COPY FROM не попадают в журнал: долговечность обеспечивается тем, что данные не остаются в оперативной памяти, а сразу записываются на диск. Этого достаточно для восстановления после сбоя и из холодной копии, но недостаточно для восстановления из горячей копии.
Чтобы использовать протокол репликации, клиент должен подключаться к серверу под ролью, имеющей атрибут REPLICATION (либо под суперпользователем). В pg_hba.conf надо разрешить подключение этой роли к базе данных replication (это не название БД, а ключевое слово). Причем разрешения для all недостаточно, подключение к replication должно быть разрешено отдельно.
https://postgrespro.ru/docs/postgresql/16/protocol-replication
Page 8: Слот репликации
Серверный объект для гарантии получения журнальных записей
- помнит, какая запись была передана клиенту последней
- число слотов ограничено max_replication_slots = 10
- Не позволяет удалить сегмент WAL, пока все его записи не переданы клиенту
- клиент может получать данные в удобном режиме,
- в том числе отключаться на время
- при отключении клиента журнальные файлы накапливаются на сервере
- мониторинг состояния: pg_replication_slots
Комментарии преподавателя
Чтобы при выполнении контрольной точки сервер не удалил файлы WAL преждевременно, можно применять слот репликации. Если поток журнальных записей идет через слот, то слот помнит, какие записи уже были переданы клиенту, и не позволяет серверу удалять файл WAL до тех пор, пока клиент не получит все записи из этого файла.
Использование слота позволяет клиенту не беспокоиться о том, что сервер сотрет файл журнала раньше времени. Клиент даже может отключиться и затем через какое-то время подключиться вновь и продолжить получать журнальные записи с того момента, на котором остановился.
Но надо иметь в виду, что при отключении клиента файлы журнала будут накапливаться на сервере и могут занять все свободное место. Поэтому каждый созданный слот следует добавлять в мониторинг (представление pg_replication_slots) и своевременно удалять ненужные слоты.
Общее количество слотов, которые могут быть созданы, ограничено конфигурационным параметром max_replication_slots (значение по умолчанию — 10).
Подробнее применение слотов обсуждается в модуле «Репликация».
https://postgrespro.ru/docs/postgresql/16/warm-standby#STREAMING-REP LICATION-SLOTS
Page 9: Клонирование кластера
{#source-figure-009 caption=“Source slide page 9: Клонирование кластера”}
для физического копирования используется утилита pg_basebackup после копирования новый сервер готов к запуску
Комментарии преподавателя
Для немедленного развертывания нового сервера из копии вызывают pg_basebackup в обычном формате (–format=plain — по умолчанию), запуская утилиту на целевом сервере. Она подключается к серверу-источнику и копирует с него файлы в локальный каталог, указанный параметром –pgdata.
Дополнительные табличные пространства копируются по тем же абсолютным путям, что и на сервере-источнике. Пути можно переназначить, указав соответствия в параметрах –tablespace-mapping утилиты. Это необходимо, если pg_basebackup запускается на самом сервере-источнике.
При потоковой доставке (–wal-method=stream — по умолчанию) утилита устанавливает второе соединение для передачи потока журнальных записей, которые генерирует работающий сервер, в локальный каталог, указанный параметром –waldir.
По умолчанию второе соединение использует временный слот репликации, который создается при подключении и удаляется при завершении работы pg_basebackup. Однако можно указать и имя постоянного слота, который должен существовать на момент запуска утилиты или создаваться ей.
В формате plain можно сжимать данные на сервере, уменьшая нагрузку на сеть. Переданные данные затем распаковываются утилитой. Но журнальные записи в потоковом режиме не сжимаются.
https://postgrespro.ru/docs/postgresql/16/app-pgbasebackup
Page 10: Клонирование кластера
Сделаем базовую копию работающего сервера alpha и восстановим с помощью этой копии сервер beta.
Разрешение на локальное подключение по протоколу репликации в pg_hba.conf уже имеется:
Чтобы утилита pg_basebackup могла подключиться к серверу под ролью student, эта роль должна иметь атрибут REPLICATION:
Остановим сервер beta и удалим каталог данных этого сервера.
Скопируем, выполнив быструю контрольную точку. Данные будут сжаты на стороне сервера и затем распакованы утилитой — это ускоряет передачу по сети, но при локальном подключении не даст эффекта. Параметр –pgdata указывает целевой каталог для записи копии. Каталог создается автоматически, но если он уже существует, то должен быть пуст.
Эта команда использовала значения по умолчанию: –format=plain –wal-method=stream В подкаталог pg_wal скопированы файлы журнала:
Page 11: Проверка целостности
Проверка файлов данных
- задача: гарантировать, что в копию попадут целостные данные
- утилиты pg_basebackup и pg_checksums
- проверяют контрольные суммы страниц файлов отношений
- Проверка резервной копии
- задача: проверить, что целостность данных в копии
- не нарушилась со временем
- файл манифеста backup_manifest
- утилита pg_verifybackup проверяет файлы по списку из манифеста
Комментарии преподавателя
Данные могут повреждаться как при записи на носитель, так и в процессе хранения. Важно убедиться в том, что в копию попали целостные данные и в дальнейшем эта целостность не нарушилась.
Расчет контрольных сумм файлов отношений включается при инициализации кластера (или в процессе работы утилитой pg_checksums). Контрольная сумма сохраняется при каждом изменении страницы в ее заголовке. Вычисленная и сохраненная контрольная сумма сравниваются:
● при каждом чтении страницы в буферный кеш;
● утилитой pg_basebackup при формировании резервной копии;
● утилитой pg_checksums в режиме проверки.
Утилита pg_basebackup включает в копию файл backup_manifest с информацией о файлах (имена, размеры, вычисленные контрольные суммы) и журнальных записях (начальная и конечная позиции WAL, линия времени), а также контрольную сумму самого манифеста.
https://postgrespro.ru/docs/postgresql/16/backup-manifest-format
Утилита pg_verifybackup проверяет соответствие резервной копии манифесту: наличие файлов, корректность контрольных сумм, возможность чтения и разбора записей WAL, необходимых для восстановления.
https://postgrespro.ru/docs/postgresql/16/app-pgverifybackup
Для полной уверенности все же следует развернуть резервную копию и проверить работоспособность сервера, ведь совпадение контрольных сумм не дает гарантии, что данные не были повреждены.
Page 12: Проверка целостности
Резервная копия содержит файл манифеста, вот его начало и конец:
Проверим целостность копии утилитой pg_verifybackup:
Утилита проверяет по манифесту наличие файлов, их контрольные суммы, а также наличие и возможность чтения всех записей WAL, необходимых для восстановления. Запускаем второй сервер.
Теперь оба сервера работают одновременно и независимо. Проверим:
Page 13: Потоковая доставка WAL
{#source-figure-013 caption=“Source slide page 13: Потоковая доставка WAL”}
создание копии для будущего использования
Комментарии преподавателя
Для создания архивных копий используется формат tar. По умолчанию используется потоковая доставка журнальных записей (параметр –wal-method=stream).
Файлы кластера будут сохранены в файле base.tar. Каждое дополнительное табличное пространство копируется в отдельный tar-файл, имя которого совпадает с OID табличного пространства. Сегменты WAL помещаются в отдельный файл pg_wal.tar.
Утилита может выполнять сжатие как на стороне клиента, так и на стороне сервера (в последнем случае pg_wal.tar не сжимается). К именам сжатых tar-архивов добавится суффикс, соответствующий методу сжатия. Например, при сжатии методом gzip основной файл будет называться base.tar.gz.
Для восстановления из такой копии сначала потребуется развернуть tar-файлы по правильным путям. При этом пути табличных пространств можно изменить: для этого нужно перед запуском сервера отредактировать файл tablespace_map или использовать параметр командной строки –tablespace-mapping.
Page 14: Файловая доставка клиенту
{#source-figure-014 caption=“Source slide page 14: Файловая доставка клиенту”}
создание копии для будущего использования
Комментарии преподавателя
При создании архивной копии можно использовать другой режим — файловую доставку журнальных записей (–wal-method=fetch).
В этом случае отдельное соединение не создается, а сегменты журнала копируются и передаются по основному соединению. Это происходит после того, как скопированы все файлы кластера. Необходимо учитывать, что во время контрольной точки сервер может удалить сегменты журнала, уже не нужные для восстановления, поэтому стоит позаботиться об их сохранности, установив достаточно большое значение параметру wal_keep_size.
Журнальные сегменты записываются в файл base.tar вместе с остальными файлами кластера.
В большинстве случаев возможность использовать режим fetch при создании копии на клиенте не нужна. Она осталась с прежних версий и в настоящее время может иметь смысл только для того, чтобы передавать журнальные записи сжатыми — режим stream не дает такой возможности.
Page 15: Архивная копия на стороне клиента
Создадим архивную копию на клиенте. Сжатие будем выполнять также на стороне клиента.
В этой команде по умолчанию была использована потоковая доставка WAL (–wal-method=stream). Посмотрим на получившуюся копию:
При потоковой доставке записей WAL в формате tar для них создается отдельный файл:
Теперь создадим еще одну архивную копию на клиенте, но используем режим доставки fetch. В этом случае сегменты WAL будут передаваться по тому же соединению, что и данные. Сжатие поручим серверу.
В получившейся копии сегменты WAL помещены в файл base.tar.gz.
Page 16: Файловая доставка серверу
{#source-figure-016 caption=“Source slide page 16: Файловая доставка серверу”}
создание копии для будущего использования копия создается на сервере без передачи данных по сети
Комментарии преподавателя
Архивную копию можно создать на сервере, запуская pg_basebackup на клиенте. Данные при этом не передаются по сети.
Создание копии на сервере задается параметром командной строки pg_basebackup –target=server:path, где path — путь к каталогу в файловой системе сервера (по умолчанию подразумевается –target=client).
В этом режиме также можно использовать сжатие, но, конечно, только на стороне сервера.
При создании копии на сервере невозможно использовать потоковый режим доставки WAL (stream), поскольку журнальные записи вообще не передаются клиенту. Необходимо указать режим доставки fetch, при котором накопившиеся журнальные сегменты копируются и помещаются в файл base.tar вместе с остальными файлами кластера.
Page 17: Архивная копия на сервере
Запустим pg_basebackup на клиенте и при этом сохраним архивную копию на сервере. В этом случае мы обязаны использовать режим доставки fetch, поэтому установим параметр wal_keep_size (будем надеяться, что этого значения хватит):
Запустим pg_basebackup, указав каталог на сервере для сохранения архивной копии и режим сжатия zstd.
Получили сжатую архивную копию в формате tar (он подразумевается).
При режиме доставки fetch утилита сохраняет сегменты WAL в общем архиве:
Удалим архивную копию.
Page 18: Низкоуровневый взгляд
{#source-figure-018 caption=“Source slide page 18: Низкоуровневый взгляд”}
на время копирования устанавливается full_page_writes = on в самом начале выполняется контрольная точка (быстро или обычно)
Комментарии преподавателя
Общий алгоритм изготовления резервной копии на низком уровне одинаков как для pg_basebackup, так и для любых сторонних средств (которые могут потребоваться, поскольку pg_basebackup предоставляет только самую базовую функциональность).
- Надо сообщить серверу о том, что начинается резервное копирование.
При этом, во-первых, на время копирования устанавливается параметр full_page_writes: при первом изменении страницы после контрольной точки полный образ этой страницы записывается в журнал. При восстановлении журнальные записи будут применяться не к страницам в файле (из-за неатомарности ввода-вывода части страницы могут оказаться рассогласованными), а к образу страницы из журнала.
Во-вторых, выполняется контрольная точка. Предусмотрено два режима: быстрое выполнение (что может привести к пиковой нагрузке на дисковую подсистему) и протяженное (которое определяется обычным параметром checkpoint_completion_target).
После прохождения контрольной точки можно копировать файлы данных любым удобным способом.
После того, как все скопировано, надо сообщить серверу, что резервное копирование завершено.
Кроме того, так или иначе надо обеспечить попадание в резервную копию всех журнальных записей, сгенерированных с начала копирования и до его окончания.
Page 19: API резервирования
Начало копирования: pg\_backup\_start
- выполняет контрольную точку, устанавливает full_page_writes
- возвращает начальную позицию в журнале
- Конец копирования: pg_backup_stop
- возвращает конечную позицию в журнале
- Копирование файлов
- либо протокол репликации, либо любые средства ОС
- Копирование журнала от начальной до конечной позиции
- протокол репликации + слот либо средства ОС + wal_keep_size
Комментарии преподавателя
Описанный алгоритм резервного копирования можно использовать, чтобы реализовать свою собственную утилиту копирования.
Резервное копирование начинается вызовом функции pg_backup_start. Она устанавливает параметр full_page_writes и выполняет контрольную точку, как рассматривалось выше. Возвращаемое этой функцией значение — позиция в журнале, начиная с которой в копию должны попасть журнальные записи.
В конце копирования вызывается функция pg_backup_stop. Она возвращает конечную позицию в журнале.
Все журнальные записи между начальной и конечной позициями надо поместить в резервную копию. Поскольку при своей работе сервер может удалять журнальные файлы, которые не требуются для восстановления, надо либо пользоваться протоколом репликации и слотом, получая записи во время копирования (как pg_basebackup в режиме доставки –wal-method=stream), либо — что менее удобно — копировать файлы средствами ОС, установив параметр wal_keep_size. Можно копировать файлы в несколько потоков, использовать rsync и т. п.
https://postgrespro.ru/docs/postgresql/16/continuous-archiving#BACKUP-LO WLEVEL-BASE-BACKUP
Page 20: Итоги
Базовая резервная копия — полная копия кластера, включая табличные пространства, плюс журнал для восстановления согласованности
- Горячее резервирование позволяет не останавливать сервер
- Инструменты
- протокол репликации
- слот репликации
- низкоуровневый API резервирования
Page 21: Практика
- В первом кластере создайте табличное пространство и базу данных с таблицей в этом пространстве. 2. Сделайте базовую резервную копию кластера с помощью pg_basebackup в формате tar со сжатием. 3. Разверните второй кластер из этой резервной копии. Табличное пространство разместите в другом каталоге, изменив файл tablespace_map. 4. Запустите второй сервер и проверьте его работоспособность.
Комментарии преподавателя
После выполнения практики удалите базу данных и табличное пространство в обоих кластерах.
Page 22: 1. Табличное пространство и база данных
Табличные пространства может создавать только суперпользователь:
2. Базовая резервная копия
Запускаем pg_basebackup от имени роли student, указывая формат tar со сжатием:
3. Восстановление из базовой резервной копии
Очистим основной каталог данных кластера beta. Права на каталог должны быть лишь у владельца.
Каталог для табличного пространства ts на сервере, который будет развернут из резервной копии:
Разворачиваем резервную копию:
Page 23: Page 23
В каталоге pg_tblspc сейчас пусто:
Символическая ссылка появится при старте сервера в соответствии с файлом tablespace_map (который находился внутри base.tar):
Изменяем в этом файле путь для табличного пространства:
4. Запуск и проверка
Запускаем сервер.
Уборка
Удалим резервную копию.
Чтобы удалить базу данных, надо от нее отключиться.
И для второго сервера:
Page 24: Практика+
- Подключите модуль basebackup_to_shell для создания базовой резервной копии на сервере с помощью определяемой пользователем команды. Эта команда должна сжимать tar-архив копии утилитой bzip2. 2. Выполните резервное копирование на сервере в формате tar. Убедитесь, что полученный архив сжат bzip2. 3. Восстановите кластер beta из полученного сжатого архива и проверьте его работоспособность.
Комментарии преподавателя
- Для подключения модуля укажите одноименную библиотеку в параметре shared_preload_libraries. Параметром basebackup_to_shell.command задайте команду, выполняемую при резервном копировании: bzip2 -c > архив.tar.bz2
https://postgrespro.ru/docs/postgresql/16/basebackup-to-shell
Чтобы задействовать модуль при резервном копировании, укажите pg_basebackup –target=shell
Для извлечения файлов из сжатого утилитой bzip2 архива tar воспользуйтесь командой: tar xjf архив.tar.bz2 -C каталог-назначения
После выполнения практики удалите созданные базы данных и резервную копию.
Page 25: 1. Подключение модуля
Запишем настройки для подключения и конфигурации модуля basebackup_to_shell в подключаемый файл конфигурации.
Перезапустим сервер.
Проверим установки.
Создадим базу данных и таблицу в ней.
2. Резервное копирование
Создадим каталог для резервной копии.
Выполним резервное копирование. Использование потокового режима невозможно, поэтому воспользуемся режимом доставки WAL fetch.
3. Восстановление из резервной копии
Удалим файлы кластера beta.
Page 26: Page 26
{#source-figure-026 caption=“Source slide page 26: Page 26”}
Извлечем файлы из архива.
Проверим, восстановлены ли данные.