Резервное копирование и восстановление данных в PostgreSQL
Секция: Технические науки
XVI Студенческая международная научно-практическая конференция «Технические и математические науки. Студенческий научный форум»
Резервное копирование и восстановление данных в PostgreSQL
Введение
PostgreSQL - это объектно-реляционная система управления базами данных с открытым исходным кодом [1]. Она поддерживает большую часть стандарта SQL и предлагает множество современных функций: сложные запросы, внешние ключи, триггеры, изменяемые представления, транзакционная целостность, многоверсионность.
В данной статье пойдет речь о резервном копировании данных в PostgreSQL. В целом, резервное копирование, а именно процесс создания копии данных, является необходимым процессом при работе с СУБД, так как позволяет восстановить информацию в случае утери рабочей копии информации. Существует достаточное количество различных подходов к резервному копированию данных. Дадим краткий обзор некоторых из них (подробнее о каждом из них расскажем далее):
- Логическое резервирование. Создается мгновенный снимок содержимого базы с учетом транзакционной целостности и сохраняется в виде файла с SQL-командами, при помощи которого можно воссоздать базу данных на другом сервере.
- Физическое резервирование (уровня файловой системы). Копирование файлов, которые СУБД использует для хранения данных в базе данных.
Логическое резервирование используется в тех случаях, когда необходимо одноразово сделать полную копию базы или в повседневной эксплуатации для создания копии не потребуется много времени или места. Когда же выгрузка баз занимает много времени, следует обратить внимание на физическое архивирование. Также хотим обратить внимание, что главным недостатком физического резервирования является невозможность восстановления определенных данных, можно восстановить только всю базу данных, в то время как при логическом резервировании можно выбрать или всю базу, или отдельные таблицы.
Логическое резервирование
Перейдем непосредственно к описанию подходов к резервному копированию в PostgreSQL и начнем с логического резервирования. Идея этого метода заключается в генерации текстового файла с командами SQL, которые при выполнении на сервере пересоздадут базу данных в том же самом состоянии, в котором она была на момент выгрузки. PostgreSQL предоставляет для этой цели вспомогательную программу pg_dump [1]. Простейшее применение этой программы выглядит так:
pg_dump имя_базы > файл_выгрузки
Программа pg_dump является для PostgreSQL обычным клиентским приложением, что означает возможность выполнять процедуру резервного копирования с любого удалённого компьютера, если имеется доступ к нужной базе данных. Данной программе обычно требуется доступ на чтение всех таблиц, которые вы хотите выгрузить, так что для копирования всей базы данных практически всегда её нужно запускать с правами суперпользователя СУБД. Тем не менее, если нет достаточных прав для резервного копирования всей базы данных, можно сделать резервную копию той части базы, доступ к которой имеется, используя такие параметры, как -n схема или -t таблица.
По умолчанию в качестве сервера, к которому подключена программа pg_dump, выбирается localhost. Чтобы указать, к какому серверу должна подключаться программа, можно использовать такие аргументы командной строки: -h сервер и -p порт. Также по умолчанию программа pg_dump подключается к базе данных с именем пользователя, совпадающим с именем текущего пользователя операционной системы. Чтобы переопределить имя, нужно либо добавить параметр -U, либо установить переменную окружения PGUSER.
Текстовые файлы, созданные pg_dump, предназначаются для последующего чтения программой psql. Общий вид команды для восстановления резервной копии:
psql имя_базы < файл_выгрузки ,
где файл_выгрузки – файл, содержащий вывод команды pg_dump, имя_базы – заранее созданная база. Программа psql принимает параметры, указывающие сервер, к которому осуществляется подключение, и имя пользователя, подобно pg_dump.
Перед восстановлением базы данных все пользователи, которые владели объектами или имели права на объекты в выгруженной базе данных, должны уже существовать. Если их нет, при восстановлении будут ошибки пересоздания объектов с изначальными владельцами и/или правами.
Резервное копирование данных на уровне файловой системы
Данный подход подразумевает копирование файлов, в которых хранится содержимое базы данных. Область хранения базы данных на диске называется кластером базы данных.
Кластер представляет собой набор баз, управляемых одним экземпляром работающего сервера. После инициализации кластер будет содержать базу данных с именем postgres, предназначенную для использования по умолчанию утилитами, пользователями и сторонними приложениями. Сам сервер баз данных не требует наличия базы postgres, но многие внешние вспомогательные программы рассчитывают на её существование.
Перейдем к рассмотрению нескольких способов резервного копирования на уровне файловой системы
- Непосредственное копирование файлов
Существует множество способов копирования данных, так, например, можно воспользоваться командой tar. Но такой подход имеет некоторые серьезные недостатки:
- для резервного копирования сервер баз данных должен быть остановлен;
- возможно только полное копирование всех данных, так как невозможно будет работать с отдельными таблицами или табличными пространствами.
- «Холодное» резервное копирование
Данный метод заключается в создании «холодной» копии каталога с данными, содержащего базу данных, полном копировании всего каталога на устройство резервного копирования и последующем удалении этой копии. Словосочетание «холодное резервирование» подразумевает, что, выполняя резервирование, сервер базы данных не будет прекращать свою работу. Однако, когда вы запустите сервер базы данных с сохранёнными данными, он будет считать, что работа сервера была прервана аварийно, и будет накатывать журнал WAL (Write Ahead Log). WAL - является механизмом протоколирования всех транзакций и позволяет восстановить систему после сбоев.
Размер копии на уровне файловой системы обычно гораздо больше, чем при выгрузке в SQL, однако зачастую выполняется быстрее.
Непрерывное резервное копирование
В процессе всей работы базы данных PostgreSQL ведется журнал WAL, в который записываются все изменения, вносимые в файлы данных. Журнал нужен, чтобы можно было безопасно восстановить данные после аварийной остановки сервера, путем воспроизведения всех внесенных изменений после последней контрольной точки. Непрерывное резервное копирование включает в себя резервное копирование на уровне файлов и восстановление записей из журнала WAL. Если потребуется восстановить данные, мы можем восстановить копию файлов, а затем воспроизвести журнал из скопированных файлов WAL, и таким образом привести систему в нужное состояние.
Для успешного восстановления с применением непрерывного архивирования, необходима непрерывная последовательность заархивированных файлов WAL, начинающаяся не позже, чем с момента начала копирования.
Настройка архивирования журнала WAL
В абстрактном смысле, запущенная СУБД PostgreSQL производит неограниченно длинную последовательность записей WAL. СУБД делит эту последовательность на файлы-сегменты WAL. Файлы-сегменты получают цифровые имена, которые обозначают их позицию в абстрактной последовательности WAL. Когда архивирование WAL не применяется, система обычно создаёт только несколько файлов-сегментов и затем перезаписывает их, меняя номер более ненужного файла-сегмента на новый. Предполагается, что файлы-сегменты, чьё содержимое предшествует последней контрольной точке, уже не представляют интереса и могут быть перезаписаны.
При архивировании данных WAL необходимо считывать содержимое каждого файла-сегмента, как только он заполняется, и сохранять эти данные куда-то, прежде чем файл-сегмент будет переработан и использован повторно. Чтобы у администратора баз данных была гибкость в вопросе сохранения файлов-сегментов, PostgreSQL позволяет администратору указать команду оболочки, которая будет запускаться для копирования завершённого файла-сегмента в нужное место.
Чтобы включить архивирование WAL, нужно установить в параметре конфигурации wal_level уровень replica, в archive_mode — значение on, и задать желаемую команду оболочки в параметре archive_command [1]. (Например, archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"'. Она будет копировать архивируемые сегменты WAL в указанный каталог).
Поскольку архивируемые последовательности файлов WAL фактически содержат всё, что есть в вашей базе данных, вам нужно будет защитить архивируемые данные от посторонних глаз; например, сохраните архив в каталог, чтение которого запрещено для группы и остальных пользователей. Также в целях сохранения целостности архива в случае ошибки администратора, требуется не допускать перезаписи любых существующих архивных файлов.
Создание базовой резервной копии
Получить базовую резервную копию, можно несколькими способами:
- Используя программу pg_basebackup. Она охраняет базовую копию в виде обычных файлов или в архиве tar. В данном случае в файл истории резервного копирования записывается метка, которая была передана в pg_basebackup, а также время и новые записи журнала WAL.
- Используя низкоуровневый API. Резервное копирование на низком уровне можно произвести в монопольном или немонопольном режиме. Немонопольное резервное копирование позволяет параллельно запускать другие процессы копирования, а монопольное можно произвести только на ведущем сервере, и оно исключает одновременное выполнение других процессов копирования.
Восстановление непрерывной архивной копии
Чтобы восстановить базу данных из резервной копии нужно:
- Остановить сервер баз данных, если он запущен.
- Если есть место, скопировать весь текущий каталог кластера баз данных и все табличные пространства во временный каталог на случай, если они понадобятся. Если места недостаточно, необходимо сохранить как минимум содержимое подкаталога pg_xlog каталога кластера, так как он может содержать журналы, не попавшие в архив перед остановкой системы.
- Удалить все существующие файлы и подкаталоги из каталога кластера и из корневых каталогов используемых табличных пространств.
- Восстановить файлы базы данных из архивной копии файлов. Важно, чтобы у восстановленных файлов были правильные разрешения и правильный владелец.
- Удалить все файлы из pg_xlog/; они восстановились из резервной копии файлов и поэтому, скорее всего, будут старее текущих.
- Если на шаге 2 вы сохранили незаархивированные файлы с сегментами WAL, скопируйте их в pg_xlog/.
- Создать командный файл восстановления recovery.conf в каталоге кластера баз данных.
- Запустить сервер. Сервер запустится в режиме восстановления и начнёт считывать необходимые ему архивные файлы WAL. Если восстановление будет прервано из-за внешней ошибки, сервер можно просто перезапустить, и он продолжит восстановление. По завершении процесса восстановления сервер переименует файл recovery.conf в recovery.done (чтобы предотвратить повторный запуск режима восстановления), а затем перейдёт к обычной работе с базой данных.
После всех шагов следует просмотреть содержимое базы данных, чтобы убедиться, что она вернулась к желаемому состоянию. Если это не так, вернитесь к шагу 1. Если всё хорошо, разрешите пользователям подключаться к серверу, восстановив обычный файл pg_hba.conf.
Заключение
В заключение, хотим выделить важные особенности рассмотренных методов резервного копирования в PostgreSQL. Важным преимуществом pg_dump в сравнении с другими методами резервного копирования является то, что полученный SQL-файл с помощью программы pg_dump обычно можно загрузить в более новые версии PostgreSQL, в то время как резервная копия на уровне файловой системы и непрерывное архивирование жёстко зависят от версии сервера. Также, только метод с применением pg_dump будет работать при переносе базы данных на другую машинную архитектуру, например, при переносе с 32-битной на 64-битную версию сервера.
Непрерывное резервное копирование позволяет восстанавливать только весь кластер баз данных целиком, но не его части. Кроме того, для архивов требуется большое хранилище: базовая резервная копия может быть объёмной, а нагруженные системы будут генерировать многие мегабайты трафика WAL, который необходимо архивировать. Тем не менее, этот метод резервного копирования предпочтителен во многих ситуациях, где необходима высокая надёжность.