Этюд по PITR штатными средствами PostgreSQL

    В короткой заметке описан cценарий Point In Time Recovery с использованием средств из стандартной поставки PostgreSQL версии 11.

    Для создания базовой резервной копии используется штатная утилита — pg_basebackeup.
    Для потоковой архивации файлов WAL используется штатная утилита — pg_receivewal

    Общий сценарий довольно подробно описан в документации Непрерывное архивирование и восстановление на момент времени (Point-in-Time Recovery, PITR), однако довольно общими фразами. Поэтому при попытке реализовать на практике возникли некоторые, хотя и вполне преодолимые шероховатости.

    Посмотрел по поиску на Хабре, вроде не нашел статей о PITR штатными средствами. Так, что может быть кому то пригодится, в качестве шаблона-рыбы. Или студентам, как лабораторка ;-)

    Конфигурация для тестирования — самая простая, один сервер RedHat Linux, один сервис PostgreSQL(pgdata=/postgres/pgdata, waldir=/postgres/waldir), pg_receivewal запускается от имени postgres, заполнение тестовыми данными не уточняется и оставлено на личноe усмотрение.

    Порядок действий по пунктам


    1. Создать папки хранения и добавить скрипты


    Создать папки.
    mkdir -p /postgres/wal_arc
    chown postgres:postgres /postgres/wal_arc
    
    mkdir -p /postgres/backup
    chown postgres:postgres /postgres/backups
    
    mkdir -p /postgres/scripts
    chown postgres:postgres /postgres/scripts

    Cкрипты в папке /postgres/scripts

    pg_receivewal.sh
    #!/bin/bash
    # pg_receivewal.sh
    # /postgres/scripts/
    pg_receivewal --no-loop --synchronous --slot=slot_receivewal --directory=/postgres/wal_arc --verbose --host=localhost > /postgres/scripts/pg_receivewal.log 2>&1

    rename.sh
    #!/bin/bash
    # rename.sh
    # /postgres/scripts/
    for f in /postgres/wal_arc/*.partial;
    do
      mv -- "$f" "${f%.partial}"
    done
    exit 0

    2. Запустить непрерывное архивирование WAL-файлов


    Настроить файл .pgpass, для запуска pg_receivewal без пароля:

    vi ~/.pgpass
        localhost:5432:*:postgres:postgres
    chmod 0600 ~/.pgpass

    Настроить сервис для запуска pg_receivewal.Пользователь root.

    pg_receivewal.service
    ##########################################################
    # /etc/systemd/system/
    # pg_receivewal.service
    [Unit]
    Description=Receiving for WAL stream
    [Service]
    Type=simple
    WorkingDirectory=/postgres/scripts
    User=postgres
    Group=postgres
    ExecStart=/postgres/scripts/pg_receivewal.sh
    [Install]
    WantedBy=multi-user.target

    Запускаем сервис.Пользователь root

    systemctl daemon-reload
    systemctl start pg_receivewal.service

    Проверяем.Пользователь root.

    systemctl status pg_receivewal.service

    В случае успешного старта получаем ответ

    ● pg_receivewal.service - Receiving for WAL stream
       Loaded: loaded (/etc/systemd/system/pg_receivewal.service; disabled; vendor preset: disabled)
       Active: active (running) since...

    3. Заполнение тестовыми данными


    Любым способом, на усмотрение читателя.

    4. Создание базовой резервной копии


    Все стандартно и тривиально:

    pg_basebackup  -D /postgres/backups/ --format=tar -Xs --progress --verbose

    Получаем ответ о успешном выполнении:

    pg_basebackup: initiating base backup, waiting for checkpoint to complete
    pg_basebackup: checkpoint completed
    …
    pg_basebackup: base backup completed

    5. Имитируем катастрофу БД


    Остановить сервер PostgreSQL любым способом.

    Удалить папки файлов данных и WAL:

    rm -rf /postgres/pgdata
    rm -rf /postgres/waldir

    6. Восстановление БД


    Создать папки файлов данных и WAL:

    mkdir /postgres/pgdata
    chown postgres:postgres /postgres/pgdata
    chmod 750 /postgres/pgdata 
    
    mkdir /postgres/waldir
    chown postgres:postgres /postgres/waldir
    chmod 750 /postgres/waldir

    Восстановить файлы данных из базовой резервной копии:

    cd /postgres/backups
     cp base.tar /postgres/pgdata
     cd /postgres/pgdata
     tar -xvf base.tar
     rm base.tar
    
     rm -r pg_wal
     ln -s /postgres/waldir pg_wal

    В папке /postgres/wal_arc имеется неполный файл WAL(с расширением partial), нужно его переименовать, на случай если точка восстановления окажется в незаполненном файле WAL. Переименовать файл — вручную или скриптом rename.sh:

    /postgres/scripts/rename.sh

    Для восстановления на заданную точку во времени необходимо подготовить файл recovery.conf:

    restore_command = 'cp /postgres/wal_arc/%f  %p'
    recovery_target_time = '*****'
    recovery_target_action=promote

    recovery_target_time задается требуемая временная точка восстановления в формате timestamp.

    Запустить сервис PostgreSQL любым доступным способом.

    Файл recovery.conf переименован в recovery.done?

    cd /postgres/pgdata
    ls -la recovery.done

    Если файл переименован-восстановление прошло успешно.

    Дополнительно полезно убедиться, что лог файл содержит следующие строки:

    starting point-in-time recovery to ...
    database system is ready to accept connections 

    В случае успешного восстановления перезапускаем потоковую архивацию файлов WAL:

    pg_receivewal --create-slot --slot=slot_receivewal --verbose

    Пользователь root

    systemctl start pg_receivewal.service

    Итог


    В самом простом сценарии, База Данных восстановлена на требуемую точку во времени.

    Similar posts

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

    More

    Comments 6

      0

      Обе эти утилиты заменяются pg_probackup. В документации всё расписано.

        +1

        Конечно заменяют, к тому же pg_probackup обладает более широкими возможностями. Но, что делать, если нет возможности установить дополнительные инструменты на сервер БД?

          0
          1. Как Вы, вероятно, знаете, в PostgreSQL 12 это работать не будет, т.к. в этой версии изменилась логика восстановления. Файл recovery.conf более не используется.
          2. У Вас пишутся логи, когда из systemd-файла вызывается скрипт с перенаправлением?
            0
            1. Отмечено в первом же абзаце.
            2. Данный пример он ведь тестовый. Тема перенаправления потоков и логирования скриптов вызываемых systemd она к теме заметки не относится. Тем более в реальной версии скрипта, все сделано сильно по другому. Без перенаправления потока при вызове, а с помощью echo '****" >> $LOG_FILE 2>&1
            0
            Неплохая инструкция, но:
            1) Нет не слова о настройках конфигурационного файла(хотя бы что надо включить реплику и архивирование).
            2) Нет упоминания, что прежде чем использовать слот репликации — его надо в базе создать.
            P.S. И в пункте о восстановлении не очень понятно почему раздаются права 750, когда вроде должны быть 700… но может я что то пропустил…
              0
              Заметка ни в коем случае не инструкция. Просто мысли по поводу.
              Посмотрел по поиску на Хабре, вроде не нашел статей о PITR штатными средствами. Так, что может быть кому то пригодится, в качестве шаблона-рыбы.


              Вот на основании данной заметки и делалась рабочая инструкция и рабочие скрипты (порядка 20 штук, кстати)

              1) Нет не слова о настройках конфигурационного файла(хотя бы что надо включить реплику и архивирование).

              Зачем? Каким образом PITR связаны с репликацией?
              Архивирование это видимо имеется в виду — периодическое создание базовой резервной копии? По pg_basebackup много материалов, проблем в общем то не было.

              По пункту 2.
              Создание слота:
              pg_receivewal --create-slot --slot=slot_receivewal --verbose

              Запуск потоковой архивации WAL
              systemctl start pg_receivewal.service


              почему раздаются права 750, когда вроде должны быть 700

              Опечатка, спасибо. Хотя в общем то для заметки непринципиально.

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