Резервное копирование и восстановление в PostgreSQL

    image

    Предположим что у нас есть postgresql в режиме потоковой репликации. master-сервер и hot-standby готовый заменить погибшего товарища. При плохом развитии событий, нам остается только создать trigger-файл и переключить наши приложения на работу с новым мастером. Однако, возможны ситуации когда вполне законные изменения были сделаны криво написанной миграцией и попали как на мастер, так и на подчиненный сервер. Например, были удалены/изменены данные в части таблиц или же таблицы были вовсе удалены. С точки зрения базы данных все нормально, а с точки зрения бизнеса — катастрофа. В таком случае провозглашение горячего hot-standby в мастера, процедура явно бесполезная…
    Для предостережения такой ситуации есть, как минимум, два варианта…

    • использовать периодическое резервное копирование средствами pg_dump;
    • использовать резервное копирование на основе базовых копий и архивов WAL.

    Первый способ достаточно прост в реализации и требует минимум усилий по установке и сопровождению. Ставим «pg_dump | lbzip2» в крон и забываем. Однако этот вариант не предлагает восстановить каталог базы данных на момент предшествующий сбою, алишь на момент выполнения бэкапа. Второй вариант чуть сложней и затратней в плане хранения, но этот вариант является более гибким решением в случае восстановления. О нем как раз и пойдет речь.
    Из плюсов:
    • возможность восстановить кластер базы на любой момент времени относительно времени создания базовой копии и времени сбоя;
    • в качестве условия для восстановления может служить как временная отметка так и конкретная транзакция.

    Минусы:
    • базовая копия занимает приблизительный размер кластера базы данных;
    • необходимость хранения WAL-архивов за период хранения базовой копии.

    Как уже было сказано выше, этот способ резервного копирования предлагает гибкие возможности по восстановлению (можно восстановить состояния базы данных в четко указанный момент времени или в момент до или после выполнения определенной транзакции), но в то же время добавляет значительные требования к хранению резервных копий. Реализация выглядит следующим образом:
    • настройка режима архивирования WAL-логов;
    • настройка резервного копирования;
    • хранение одной или более резервных копий;
    • удаление самой старой резервной копии в случае успешного выполнения п.1;
    • удаление соответствующих WAL-архивов от резервной копии из п.3;
    • опционально можно проводить процедуру проверки резервных копий на предмет их «профпригодности».


    Режим архивирования WAL-логов настраивается через включение параметров archive_mode и archive_command в postgresql.conf и создание директории где будут храниться архивы. Для начала стоит включить режим архивирования и оценить объем архивов создаваемых за одни сутки работы базы данных. Это позволит провести оценку требуемого места для хранения архивов и базовых копий. За архивирование отвечают опции:
    archive_mode = on
    archive_command = 'cp %p /opt/pgsql/pgbackup/archive/%f'

    Непосредственное резервное копирование настраиваем средствами pg_basebackup. Это программа из комплекта утилит идущих вместе с PostgreSQL которую можно использовать как для настройки потоковой репликации, так и для снятия резервных копий. Принцип работы позволяет снимать резервную копию не останавливая кластер базы данных. Исходя из задачи, нам всего лишь нужно запускать pg_basebackup по расписанию в cron. Учитывая требования по месту, нужно позаботиться о достаточном месте на диске, во избежание переполнения.

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

    После завершения создания резервной копии, старую копию можно удалить вместе с архивами. Удаление архивов выполняется с помощью утилиты pg_archivecleanup. Утилита позволяет аккуратно удалить ненужные архивы основываясь на специальных файлах-метках, которые создаются при резервном копировании.

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

    Теперь предположим что случилось наихудшее и нужно выполнить восстановление. Нужно остановить основной кластер postgres и переименовать каталог базы данных в произвольное имя. Каталог резервной копии нужно переименовать в каталог кластера базы данных. При необходимости скопировать файлы конфигурации. После определения конфигурационных файлов, запускаем postgres относительно нашего каталога. При запуске, Postgres обнаружит recovery.conf и запустится в режиме восстановления. Остается дождаться пока postgres восстановит свое состояние с помощью архивов, после чего можно будет подключаться к базе данных и продолжить работу. Вот и все, процедура восстановления завершена.

    Вот так вот. Держите данные в сохранности! Скрипты для резервного копирования и валидации копий здесь.

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 13

      +3
      Тема очень интересная, но статья явно не полная. Добавили бы побольше примеров. Возможно, ссылки на документацию или какие-то похожие статьи.
      По одному вашему описанию не разобраться, а вектор для дальнейшего изучения как то плохо задали.
      Код мельком посмотрел — на своей базе без тщательного изучения не стал бы запускать.
        0
        Наоборот старался сократить объем, в развернутом виде, как мне показалось, получилось слишком много текста и выглядит нудно (более подробно расписал пункты реализации).
        скрипты да, требуют тщательного изучения т.к. при работе могут создать определенную нагрузку
        0
        Я вот в репликации постгреса никак не могу принять одну вещь: то, что на мастере в команде архивирования надо указывать путь к папке на реплике, чтобы мастер туда складывал wal-файлы на время активного pg_base_backup при первоначальной «наливке» реплики (когда идет rsync с мастера, например). Это ломает всю концепцию — мастер должен что-то знать о реплике (репликах).

        Можно, конечно, и не настраивать архивирование; а просто увеличить кол-во хранимых «живых» wal-файлов и rsync-ать их уже после выполнения pg_stop_backup, но в этом случае увеличивается риск того, wal-файлы отротируются раньше, чем закончится rsync наливки реплики. Да и последующий rsync wal-файлов после pg_stop_backup будет лишнее время занимать, ведь начнут копироваться уже устаревшие wal-файлы (коих большинство).

        Ну почему, почему они не сделали так, что после выполнения pg_start_backup можно было спокойно rsync-ать файлы базы без единого wal-файла, а wal-файлы сами бы потом подтягивались через протокол репликации? Это бы значительно упростило наливку реплики (которую приходится делать каждый раз, когда падает мастер, при условии, что реплик несколько, а не одна).
          +1
          >> на мастере в команде архивирования надо указывать путь к папке на реплике, чтобы мастер туда складывал wal-файлы на время активного pg_base_backup при первоначальной «наливке» реплики
          Необязательно складывать архивы на реплику. Можно складывать локально, а потом на слейве указать restore_command = 'scp user@master:/path/to/archive/%f "%p"'. Пусть берет их по сети.
            0
            Но все равно получается, что от реплики к мастеру 2 способа передачи данных идет: через replication protocol и через ssh. Некрасиво это…
          0
          > Однако этот вариант не предлагает восстановить каталог базы данных на момент предшествующий сбою, алишь на момент выполнения бэкапа.

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

              да, можно дергать DBA «эй, сделай-ка нам дамп», но я за автоматизацию)))

            0
            эх… мне бы ваш оптимизм…

            на базах размером в несколько тер, с тысячами схем и миллионами файлов в каталогах, под нагрузкой, все не так уж и радужно.
              0
              кто-то мне в аську стукнулся, но антиспам заблокировал.
                0
                это я))) мы пару лет назад общались по аське на тему постгреса… у меня контакт до сих пор сохранился)))
              0
              Для фанатов — вышла недавно книжкаhow-to на 40 страниц Instant PostgreSQL Backup and Restore How-to. В ней подробно описываются все возможные способы бэкапа и восстановления из него со всеми плюсами и минусами.
                0
                postgresql.leopard.in.ua/ — 10 глава. На проектах я использую часто wal-e, при этом настроены slave сервера, что читают не с мастера, а с s3 бекапов.

                Only users with full accounts can post comments. Log in, please.