Info
Content

WAL-G for PostgreSQL

Ты можешь использовать wal-g как инструмент для создания зашифрованых и сжатых postgresql бэкапов (полных и инкрементальных) и для push/fetch их на/с удаленных стораджей без необходимости сохранения на свою ФС

Configuration

WAL-G использует обычные постгресовые переменные окружения для настройки подключения, особенно включая PGHOST, PGPORT, PGUSER, и PGPASSWORD/PGPASSFILE/~/.pgpass

PGHOST может подключить по unix-сокету. Этот режим предпочтительный для локальных подключений. Для его использования задай переменную так - PGHOST=/var/run/postgresql
Если в PGHOST указан IP, то wal-g подключится по TCP

  • WALG_DISK_RATE_LIMIT - нужен для ограничения скорости чтения с диска при backup-push (в байтах в секунду). Параллельность задается переменной ниже
  • WALG_DOWNLOAD_CONCURRENCY - задает как много горутин использовать при backup-fetch и wal-fetch. По умолчанию используется меньшее из кол-ва файлов и 10
  • WALG_PREFETCH_DIR - по умолчанию wal-prefetch сохраняет валы в pg_wal. Эта опция позволяет легко мувнуть волы из временной диры в актуальную откуда их употребить постгрес. Но это может вызвать негативные последствия если ты используешь это вместе с pg_rewind в PostgreSQL 13. PostgreSQL 13 может вызвать restore_command во время pg_rewind. Тогда запрефетченные волы могут вызвать ложную ошибку у pg_rewind. Чтобы обойти это ты можешь либо отключить префетчинг на время pg_rewind'a (установив WALG_DOWNLOAD_CONCURRENCY = 1), либо разместить wal prefetch папку вне PGDATA
  • WALG_UPLOAD_CONCURRENCY - задает кол-во параллельных стримов которые будут отгружать бэкап (по умолчанию 16)
  • WALG_UPLOAD_DISK_CONCURRENCY - задает как много параллельных стримов будут читать диск во время backup-push (по умолчанию 1)
  • TOTAL_BG_UPLOADED_LIMIT (напр. 1024) - переопределяет дефолтное кол-во wal файлов которые будут отгружены во время одного скана. По умолчанию не более 32
  • WALG_SENTINEL_USER_DATA - эта опция позволяет автобэкаперу добавлять дополнительную инфу в JSON sentinel файл во время backup-push. Эта опция может быть использована например для того чтобы давать человеко-понятные имена бэкапам. UserData должна быть валидной json строкой
  • WALG_PREVENT_WAL_OVERWRITE - если указана эта опция, то wal-g будет во время wal-push проверять существование вола перед его загрузкой. Если другой файл уже заархивирован под этим же именем то wal-g вернет ненулевой exit-code чтобы не дать postgres'у удалить этот вол
  • WALG_DELTA_MAX_STEPS - Delta-backup это разница между предыдущим сделанным бэкапом и текущим состоянием. Эта переменная указывает как много может быть дельта-бэкапов между полными бэкапами. По умолчанию 0. Процесс восстановления будет автоматически фетчить все необходимые дельты и базовые бэкапы и составит из них валидные бэкап для восстановления (все равно нужны валы после старта последнего бэкапа чтобы восстановить консистентный кластер). Вычисление дельт базируется на ModTime файловой системы и LSN номера страницы в файлах данных
  • WALG_DELTA_ORIGIN - нужен для указания базы для следующего дельта бэкапа (только если значение предыдущей переменной еще не иссякло). Значением может быть LATEST (цепочный инкремент) или LATEST_FULL (для баз где волатильная часть мала и цепочка не имеет смысла (дельты перезаписывают друг друга))
  • WALG_TAR_SIZE_THRESHOLD - задает размер одного бэкап-бандла в байтах. Меньший размер дает гранулярность и более оптимальный, быстро восстанавливается, но так же увеличивает кол-во запросов к стораджу, а это может выйти в копеечку. По умолчанию стоит 1Gb
  • WALG_TAR_DISABLE_FSYNC - выключает вызов fsync после записи файла при экстрактинге из tar архивов
  • WALG_PG_WAL_SIZE - позволяет задать размер wal сегмента если он отличается от дефолтного (16M)
  • WALG_UPLOAD_WAL_METADATA - загружает метаданные связанные с wal файлами. Может быть INDIVIDUAL (метаданные генерятся для всех волов) или BULK (метаданные генерятся для пачки волов). Если в значении стоит NOMETADATA или переменная не указана то фолбэчится на дефолтную настройу - не генерить метаданные для волов
  • WALG_ALIVE_CHECK_INTERVAL - задает кака часто wal-g должен проверять жив ли постгрес во время backup-push. Если проверка фейлится, то заливка бэкапа прерывается
    • 0 - выключает проверку
    • 1m - проверяет раз в минуту (дефолт)
    • 10s - проверяет каждые 10 секунд
  • WALG_STOP_BACKUP_TIMEOUT - задает таймаут для вызова pg_stop_backup(). По умолчанию таймаута нет
    • 0 - выключает таймаут (дефолт)
    • 10s - таймаут 10 секунд
    • 10m - 10 минут

Usage

backup-fetch

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

wal-g backup-fetch ~/extract/to/here example-backup

Можно достать последний бэкап вот так

wal-g backup-fetch ~/extract/to/here LATEST

Можно достать бэкап который имеет определенную UserData указав эту юзердату в ключе --target-user-data или в переменной WALG_FETCH_TARGET_USER_DATA

wal-g backup-fetch /path --target-user-data "{ \"x\": [3], \"y\": 4 }"
Reverse delta unpack

Beta feature: WAL-G может распаковывать дельта бэкапы в обратном порядке для увеличения эффективности
Активировать эту функцию можно либо через переменную WALG_USE_REVERSE_UNPACK, либо через флаг --reverse-unpack

Redundant archives skipping

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

  1. Опционально. Увеличить шанс пропуска архивов, но в результате может замедлиться создание бэкапов. Enable rating tar ball composer for backup-push
  2. Включить пропуск избыточных бэкапов во время backup-fetch (два варианта как):
    1. Проставив переменные WALG_USE_REVERSE_UNPACK и WALG_SKIP_REDUNDANT_TARS
    2. Добавив флаги --reverse-unpack и --skip-redundant-tars
Partial restore (experimental)

Во время частичного восстановления wal-g восстанавливает фалы только определенных баз данных. В качестве параметра используй 'database' или 'database/namespace.table' (схема 'public' может быть опущена)

wal-g backup-fetch /path LATEST --restore-only=my_database,"another database",database/my_table

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

Три выражения ниже - эквивалентны:

  • --restore-only=my_db,"another db"
  • --restore-only=my_db,another" "db
  • --restore-only=my_db,anoth"e"r" "d"b"

Для этого требуются файлы с метаданными которые автоматически собираются во время локального бэкапирования (при удаленном бэкапировании это не работает)

Также автоматически восстанавливаются системные бд и таблицы

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

Опции --skip-redundant-tars и --reverse-unpack проставляются автоматически

backup-push

Для отгрузки бэкапов на сторадж, пользователь должен указать постгресовую датадиру в качестве аргумента

wal-g backup-push $PGDATA

WAL-G проверит, совпадают ли аргумент команды, переменная окружения PGDATA и параметр конфигурации PGDATA, если они установлены

Если бэкап запущен со standby сервера, то wal-g будет следить за таймлайном сервера. Если промоушен или таймлайн изменится во время бэкапа, то данные будут загружены но не финализированы, и wal-g вывалится с ошибкой. Логи будут содержать информацию необходимую для финализации бэкапа (которая может быть использована если ты четко понимаешь все риски)
backup-push может быть также запущен с флагом --permanent, который пометит бэкап как перманентный и убережет его от удаления при запуске команды delete

Remote backup

WAL-G backup-push имеет два варианта стриминга данных:

  1. Запуск прямо на сервере с БД под пользователем постгреса - wal-g может читать файлы базы данных прямо с файловой системы. Этот вариант дает высокую производительность и дополнительные возможности, такие как частичное восстановление или дельта бэкапы

For uploading backups to S3 using streaming option 1, the user should pass in the path containing the backup started by Postgres as in:
bash wal-g backup-push /backup/directory/path

  1. Альтернативно wal-g может стримить бэкапные данные через postgres'овый BASE_BACKUP протокол
    Это позволяет wal-g стримить бэкапы по TCP, быть запущенным удаленно и быть запущенным из под другого пользователя. Wal-g требуется подключение с правом репликации (в статье про base backup это описано). Помни что протокол BASE_BACKUP не умеет в мультитрединг и дельта бэкапы пока не имплементированы

Чтобы завести эту схему, надо покинуть data dir постгри и указать хостнейм постгрес сервера (через env var PGHOST или аргумент параметра --pghost)

# Inline
PGHOST=srv1 wal-g backup-push
# Export
export PGHOST=srv1 wal-g backup-push
# Use commandline option
wal-g backup-push --pghost srv1

Опции удаленного бэкапирования также могут быть использованы для:

  • запуска постгресов на множестве хостов и бэкапирования через wal-g используя мультихост конфигурацию: wal-g backup-push --pghost srv1,srv2
  • запуска постгреса на windows хосте и бэкапинга через wal-g на линукс хосте: PGHOST=winsrv1 wal-g backup-push
  • запуска wal-g как kubernetes cronjob
Rating composer mode

В режиме составителя рэйтинга (?) wal-g во время бэкапа кладет файлы с одинаковой частотой обновления в общие тарболы. Это должно увеличить эффективность пропуска избыточных архивов backup-fetch'а. Будь осторожен, хоть этот режим и позволяет сохранить больше данных, в итоге он может замедлить создание бэкапа по сравнение с дефолтным сборщиком тарболов

Для активации этой фичи сделай одно из:

  • установи переменную WALG_USE_RATING_COMPOSER
  • добавь флаг --rating-composer
wal-g backup-push /path --rating-composer
Copy composer mode

В режиме copy composer, wal-g делает полный бэкап и копирует неизмененные тар-файлы из предыдущего полного бэкапа. В случае если нет предыдущего полного бэкапа будет задействован regular composer

Чтобы активировать эту фичу сделай одно из:

  • установи переменную WALG_USE_COPY_COMPOSER
  • добавь флаг --copy-composer
wal-g backup-push /path --copy-composer
Database composer mode

В этом режиме wal-g отделяет файлы из разных директорий внутри дефолтного tablespace и пакует их в разные тарболы. Это создано для увеличения перфоманса частичного восстановления
Чтобы активировать эту фичу сделай одно из:

  • установи переменную WALG_USE_DATABASE_COMPOSER
  • добавь флаг --database-composer
wal-g backup-push /path --database-composer
Backup without metadata

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

Если выставлен флаг --without-files-metadata или переменная WALG_WITHOUT_FILES_METADATA, то wal-g не будет трэкать метаданные забэкапленных файлов. Это значительно уменьшит потребление памяти на инстансе с более чем 100к файлов

Ограничения:

  • не может быть использовано с rating-composer, copy-composer
  • не может быть использовано с параметром WALG_DELTA_MAX_STEPS или флагами delta-from-user-data, delta-from-name

Чтобы активировать эту фичу сделай одно из:

  • установи переменную WALG_WITHOUT_FILES_METADATA
  • добавь флаг --without-files-metadata
wal-g backup-push /path --without-files-metadata
Create delta backup from specific backup

При создании дельта бэкапа (WALG_DELTA_MAX_STEPS > 0), wal-g по умолчанию использует последний бэкап как базовый. Это поведение может быть изменено с помощью следующих флагов:

  • --delta-from-name или WALG_DELTA_FROM_NAME - задает имя бэкапа который будет взят за базовый для дельта бэкапа
  • --delta-from-user-data или WALG_DELTA_FROM_USER_DATA - задает юзердату бэкап с которой будет взят как базовый для дельта бэкапа
wal-g backup-push /path --delta-from-name base_000000010000000100000072_D_000000010000000100000063
wal-g backup-push /path --delta-from-user-data "{ \"x\": [3], \"y\": 4 }"

Если использовать флаг выше в комбинации с WALG_DELTA_ORIGIN, то его логика будет применяться к указанному бэкапу

list of backups in storage:
base_000000010000000100000040  # full backup
base_000000010000000100000046_D_000000010000000100000040  # 1st delta
base_000000010000000100000061_D_000000010000000100000046  # 2nd delta
base_000000010000000100000070  # full backup

export WALG_DELTA_ORIGIN=LATEST_FULL
wal-g backup-push /path --delta-from-name base_000000010000000100000046_D_000000010000000100000040

wal-g logs:
INFO: Selecting the backup with name base_000000010000000100000046_D_000000010000000100000040 as the base for the current delta backup...
INFO: Delta will be made from full backup.
INFO: Delta backup from base_000000010000000100000040 with LSN 140000060.
Page checksums verification

Чтобы включить верификацию страничных чексумм по время backup-push, используй флаг --verify или переменную WALG_VERIFY_PAGE_CHECKSUMS. Если будут найдены, то кол-во поврежденных блоков будет записано в sentinel json

...
"/base/13690/13535": {
"IsSkipped": true,
"MTime": "2020-08-20T21:02:56.690095409+05:00",
"IsIncremented": false
},
"/base/16384/16397": {
"CorruptBlocks": [
1
],
"IsIncremented": false,
"IsSkipped": false,
"MTime": "2020-08-21T19:09:52.966149937+05:00"
},
...

wal-fetch

Когда качается wal архив из s3, пользователь должен указать имя архива и имя файла в который надо скачать архив. Этот файл не должен существовать так как wal-g создаст его для тебя

Wal-g предзакачивает wal файлы наперед относительно тех которые запрошены. Эти файлы кэшируются в папку ./.wal-g/prefetch. Закэшированные файлы старше чем последний запрошенный удаляются из кэша для предотвращения разбухания кэша. Если закэшированный файл запрошен через wal-fetch, он будет удален из кэша и будет дернут триггер на скачивание нового

wal-g wal-fetch example-archive new-file-name

Эта команда создана для выполнения из постгресового restore_command

Отметим что wal-fetch будет вылетать с экзиткодом 74 (EX_IOERR: input/output error, ...) если wal файл не доступен в репозитории. Все остальные ошибки приводят к exit code 1, и должны останавливать postgres раньше чем завершается восстановление. Для постгреса это может быть любой код ошибки между 126 и 255, которые могут быть получены через простой скрипт-обертку. См. PR - https://github.com/wal-g/wal-g/pull/1195 (судя по PR это говно уже пофикшено)

wal-push

Для отгрузки вал архивов в S3 пользователь должен указать абсолютный путь до архива

wal-g wal-push /path/to/archive

Эта команда создана для выполнения из постгресовой archive_command

wal-show

Показывает инфу о каталоге хранения wal'ов. Она показывает все таймлайны вол-сегментов доступных в сторадже, отображает доступные бэкапы для них и проверяет их на потерянные сегменты

  • если нет гэпов (потерянных сегментов) в диапазоне, то статус - OK
  • если потерянные сегменты найдены то статус - LOST_SEGMENTS
wal-g wal-show

По умолчанию wal-show показывает доступные бэкапы для каждого таймлайна. Чтобы выключить это поведение добавь флаг --without-backups

По умолчанию выводится таблица, чтобы вывести подробный json, добавь флаг --detailed-json

wal-verify

Запускает серию проверок чтобы убедиться что сторадж wal-сегментов здоров. Доступные проверки:

integrity

Проверка того что история wal-сегментов консистентна для кластера и значит wal-g сможет выполнить PITR для бэкапа. В основном это проверки того что все wal-сегменты в диапазоне [oldest backup start segment, current cluster segment) доступны в сторадже. Если бэкапов не найдено то будет отсканирован диапазон [1, current cluster segment)

Screenshot_2021_02_02-12_49_03-2023-06-26-at-00walghealthcheck.png

В выводе integrity проверки есть 4 статуса:

  • FOUND - сегменты присутствуют в сторадже
  • MISSING_DELAYED - сегментов в сторадже нет, но возможно постгрес просто еще не заслал их
  • MISSING_UPLOADING - сегментов еще нет, но похоже они загружаются прямо сейчас
  • MISSING_LOST - сегментов нет в сторадже но они не delayed и не uploading

Размер диапазона сегментов ProbablyUploading берется из настройки WALG_UPLOAD_CONCURRENCY
Размер диапазона сегментов ProbablyDelayed контролируется настройкой WALG_INTEGRITY_MAX_DELAYED_WALS

Вывод содержит:

  1. Статус integrity проверки:
    • OK - нет пропущенных сегментов
    • WARNING - есть несколько пропущенных сегментов но они не MISSING_LOST
    • FAILURE - есть несколько MISSING_LOST сегментов
  2. Список сегментов в хронологическом порядке сгруппированных по таймлайнам и статусам
timeline

Проверка что текущий таймлайн кластера больше чем или равен какому-либо таймлайну в сторадже
Эта проверка полезна для обнаружения split-brain конфликтов
Обрати внимание что эта проверка будет работать корректно только если создан новый сторадж или старый очищен после восстановления из бэкапа или применения pg_upgrade

Вывод содержит:

  1. Статус timeline проверки:
    • OK - текущий timeline-id матчится с наивысшим таймлайном в сторадже
    • WARNING - не получается определить что текущий таймлайн матичится с наивысшим в сторадже
    • FAILURE - текущий timeline-id не равен наивысшему таймлайну в сторадже
  2. Текущий таймлайн айди
  3. Наивысший таймлайн айди найденный в сторадже

Пример

wal-g wal-verify [space separated list of checks]
# For example:
wal-g wal-verify integrity timeline # perform integrity and timeline checks
wal-g wal-verify integrity # perform only integrity check

По умолчанию вывод wal-verify это плейнтекст. Чтобы переключить на json добавь флаг --json

Пример обычного вывода:

[wal-verify] integrity check status: OK
[wal-verify] integrity check details:
+-----+--------------------------+--------------------------+----------------+--------+
| TLI | START                    | END                      | SEGMENTS COUNT | STATUS |
+-----+--------------------------+--------------------------+----------------+--------+
|   3 | 00000003000000030000004D | 0000000300000004000000F0 |            420 |  FOUND |
|   4 | 0000000400000004000000F1 | 000000040000000800000034 |            836 |  FOUND |
+-----+--------------------------+--------------------------+----------------+--------+
[wal-verify] timeline check status: OK
[wal-verify] timeline check details:
Highest timeline found in storage: 4
Current cluster timeline: 4

Пример json вывода:

{
   "integrity":{
      "status":"OK",
      "details":[
         {
            "timeline_id":3,
            "start_segment":"00000003000000030000004D",
            "end_segment":"0000000300000004000000F0",
            "segments_count":420,
            "status":"FOUND"
         },
         {
            "timeline_id":4,
            "start_segment":"0000000400000004000000F1",
            "end_segment":"000000040000000800000034",
            "segments_count":836,
            "status":"FOUND"
         }
      ]
   },
   "timeline":{
      "status":"OK",
      "details":{
         "current_timeline_id":4,
         "highest_storage_timeline_id":4
      }
   }
}

wal-receive

Получает wal поток используя postgresql streaming replication и пушит это в сторадж

Ты можешь указать имя слота репликации в переменной WALG_SLOTNAME (по умолчанию walg). Имя слота может содержать только цифры буквы и подчеркивания. Для загрузки wal в s3 пользователь должен указать полный путь до архива

backup-mark

Бэкапы могут быть помечены как постоянные (permanent) для предотвращения удаления их при запуске команды delete. Постоянность бэкапа может быть изменена через эту команду. Нужно скормить сюда имя бэкапа (получить его можно из вывода wal-g backup-list --pretty --detail --json), и тогда он и предыдущие связанные с ним бэкапы будут помечены как постоянные. Обратное действие доступно через флаг -i

catchup-push

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

Пошагово:

  1. Остановка реплики
  2. Получение LSN реплики
  3. Начало загрузки инкрементального бэкапа на мастере
wal-g catchup-push /path/to/master/postgres --from-lsn replica_lsn

catchup-fetch

Чтобы провернуть догон инкрементальным бэкапом сделанным через catchup-push, пользователю нужно указать путь до постгреса на реплике и имя бэкапа

wal-g catchup-fetch /path/to/replica/postgres backup_name

copy

Эта команда поможет изменить сторадж и перенести туда набор бэкапов или записать бэкапы на магнитную ленту
Например: wal-g copy --from=config_from.json --to=config_to.json - скопирует все бэкапы
Флаги:

  • -b, --backup-name string - скопировать конкретный бэкап
  • -f, --from string - сторадж-конфиг стораджа из которого нужно копировать
  • -t, --to string - сторадж-конфиг стораджа на который нужно скопировать
  • -w, --without-history - копировать бэкапы без истории (wal files)

delete garbage

Удаляет просроченные wal архивы и остаточные файлы бэкапов на сторадже (неуспешные бэкапы или частично удаленные). Удалит все неперманентные объекты до самого раннего неперманентного бэкапа. Эта команда полезна когда бэкапы были удалены через delete target

wal-g delete garbage           # Deletes outdated WAL archives and leftover backups files from storage
wal-g delete garbage ARCHIVES      # Deletes only outdated WAL archives from storage
wal-g delete garbage BACKUPS       # Deletes only leftover (partially deleted or unsuccessful) backups files from storage

The garbage target can be used in addition to the other targets, which are common for all storages

wal-restore

Восстанавливает потеряные wal-сегменты которые будут необходимы для выполнения pg_rewind из стораджа. Текущая версия поддерживает только локальные кластеры

wal-g wal-restore path/to/target-pgdata path/to/source-pgdata

daemon

Архивировать и стягивать все wal-сегменты в фоне. Работает с PostgreSQL archive library walg_archive или walg-daemon-client

wal-g daemon path/to/socket-descriptor

pgBackRest backups support (beta version)

https://wal-g.readthedocs.io/PostgreSQL/#pgbackrest-backups-support-beta-version

Failover archive storages (experimental)

https://wal-g.readthedocs.io/PostgreSQL/#failover-archive-storages-experimental

Playground

Ты можешь протестить wal-g в с помощью этого playground

No Comments
Back to top