Перейти к основному содержимому

pg_upgrade. Обновление данных без их дампа или восстановления

Версия: 15.15 (собственной версии нет, соответствует версии ядра).

В исходном дистрибутиве установлено по умолчанию: да.

Связанные компоненты: отсутствуют.

pg_upgrade позволяет обновлять данные, хранящиеся в файлах данных PostgreSQL, до более поздней основной версии PostgreSQL без дампа/восстановления данных, обычно требуемых для обновления основных версий, например, с 9.5.8 до 9.6.4 или с 10.7 до 11.2. Для минорных обновлений, например, с 9.6.2 до 9.6.3 или с 10.1 до 10.2 утилита не требуется.

Основные выпуски PostgreSQL часто меняют системные таблицы, но реже — формат хранения. pg_upgrade быстро обновляет кластер, создавая новые системные таблицы и повторно используя файлы пользовательских данных. Если будущий релиз изменит формат так, что старые данные станут нечитаемы, pg_upgrade использовать нельзя.

pg_upgrade проверяет двоичную совместимость старого и нового кластеров (в том числе разрядность 32/64-бит и параметры сборки). Внешние модули также должны быть двоично-совместимы (утилита это не проверяет).

Поддерживаются обновления с версии 9.2.x и выше до текущей основной версии PostgreSQL (включая снепшоты и beta).

Пример миграции с оригинального PostgreSQL на Pangolin приведен в разделе Миграция с оригинального PostgreSQL на Pangolin.

Доработка

В pg_upgrade добавлена поддержка аутентификации по сертификату (PEM, PKCS#12) при обновлении СУБД Pangolin.

В базовой реализации pg_upgrade подключение к временным процессам postmaster, запускаемым со старым и новым каталогами данных, выполняется через Unix-сокеты. Unix-сокеты не поддерживают SSL/TLS, поэтому аутентификация по сертификату невозможна. В таких случаях в журнале могут появляться сообщения:

LOG:  cert authentication is only supported on hostssl connections
FATAL: could not load pg_hba.conf

Для устранения ограничения в pg_upgrade реализован режим запуска временных процессов postmaster на TCP/IP-сокете с прослушиванием localhost. Режим активируется опцией --use-tcp (-t). Использование TCP/IP позволяет применять SSL/TLS и настраивать аутентификацию по сертификату через правила hostssl в pg_hba.conf.

Опции для настройки SSL-подключения

Для задания SSL-параметров в pg_upgrade добавлены опции подключения к старому и новому кластеру.

Параметры для старого кластера:

  • --old-sslmode — режим SSL (disable, allow, prefer, require, verify-ca, verify-full);
  • --old-sslcert — путь к клиентскому сертификату;
  • --old-sslkey — путь к закрытому ключу для клиентского сертификата;
  • --old-sslrootcert — путь к доверенному сертификату;
  • --old-sslrootpath — путь к директории с доверенными сертификатами;
  • --old-sslcrl — путь к файлу со списком отозванных сертификатов (CRL);
  • --old-sslcrldir — путь к директории с файлами CRL;
  • --old-pkcs12-config-path — путь к настроечному файлу .p12.cfg, содержащему путь до локального контейнера PKCS#12;
  • --old-sslconnstr — строка подключения (поддерживает использование только SSL-параметров).

Параметры для нового кластера:

  • --new-sslmode;
  • --new-sslcert;
  • --new-sslkey;
  • --new-sslrootcert;
  • --new-sslrootpath;
  • --new-sslcrl;
  • --new-sslcrldir;
  • --new-pkcs12-config-path;
  • --new-sslconnstr.

Если один и тот же SSL-параметр указан и в --old(new)-sslconnstr, и в соответствующей опции командной строки pg_upgrade, приоритет имеет значение, заданное отдельной опцией командной строки.

Переменные окружения

Сохранена возможность настройки SSL-параметров через переменные окружения с меньшим приоритетом по сравнению с --old(new)-sslconnstr и опциями командной строки:

  • PGSSLMODE — аналог --old(new)-sslmode;
  • PGSSLCERT — аналог --old(new)-sslcert;
  • PGSSLKEY — аналог --old(new)-sslkey;
  • PGSSLROOTCERT — аналог --old(new)-sslrootcert;
  • PGSSLROOTPATH — аналог --old(new)-sslrootpath;
  • PGSSLCRL — аналог --old(new)-sslcrl;
  • PGSSLCRLDIR — аналог --old(new)-sslcrldir;
  • PKCS12_CONFIG_PATH — аналог --old(new)-pkcs12-config-path;
  • PKCS12_PASSPHRASE — парольная фраза для доступа к контейнеру PKCS#12.

Ввод пароля и парольной фразы PKCS#12

Для управления интерактивным вводом секретов в pg_upgrade добавлены опции:

  • --password-prompt (-W) — запрос пароля или парольной фразы;
  • --password-prompt-timeout — время ожидания ввода (по умолчанию 30 секунд);
  • --no-passphrase-prompt — не использовать введенный текст как парольную фразу PKCS#12;
  • --use-pty — использовать pseudo-terminal для ввода пароля (рекомендуется при --jobs).

Если парольная фраза для PKCS#12 отсутствует в .p12.cfg (поле passphrase), для аутентификации требуется ввод парольной фразы вручную. При использовании --jobs необходимо указывать --use-pty, иначе возможны ошибки чтения парольной фразы утилитами pg_dump и pg_restore.

Доработки вспомогательных утилит

Утилиты pg_dump, pg_restore и vacuumdb, используемые в процессе обновления, могут многократно подключаться к СУБД и запрашивать парольную фразу для PKCS#12. Для сокращения числа запросов парольной фразы в них добавлен параметр --passphrase-pkcs12.

Логирование плагина PKCS#12

Введен параметр --plugin-log-level для настройки уровня логирования сообщений плагина извлечения сертификата и закрытого ключа из контейнера PKCS#12. Значение по умолчанию — WARNING.

Ограничения

Утилита не поддерживает базы с системными типами regcollation, regconfig, regdictionary, regnamespace, regoper, regoperator, regproc, regprocedure.

Расширения и внешние модули должны быть собраны заново для новой версии.

Старый и новый кластеры должны быть одинаковой разрядности (32/64-бит).

Для режима --link и --clone требуется, чтобы каталоги находились на одной файловой системе.

Установка

Устанавливается по умолчанию с ядром PostgreSQL, дополнительных действий не требуется.

Настройка

pg_upgrade принимает следующие аргументы командной строки:

  • -b каталог_bin, --old-bindir=каталог_bin – каталог с исполняемыми файлами старой версии PostgreSQL, переменная окружения PGBINOLD;

  • -B каталог_bin, --new_bindir=каталог_bin – каталог с исполняемыми файлами новой версии PostgreSQL, по умолчанию это каталог, в котором располагается pg_upgrade, переменная окружения PGBINNEW;

  • -c, --check – только проверить кластеры, не изменять никакие данные;

  • -d каталог_конфигурации, --old-datadir=каталог_конфигурации – каталог конфигурации старого кластера, переменная окружения PGDATAOLD;

  • -D каталог_конфигурации каталог конфигурации нового кластера;

  • --new-datadir=каталог_конфигурации переменная окружения PGDATANEW;

  • -j число_заданий, --jobs=число_заданий – число одновременно задействуемых процессов или потоков;

  • -k, --link – использовать жесткие ссылки вместо копирования файлов в новый кластер;

  • -l, --log-path – опция для изменения директории логирования pg_upgrade;

  • -N, --no-sync – по умолчанию, pg_upgrade будет ждать, пока все файлы обновленного кластера будут безопасно записаны на диск. Эта опция заставляет pg_upgrade вернуться без ожидания, что быстрее, но означает, что последующий сбой операционной системы может привести к повреждению каталога данных. В целом, эта опция полезна для тестирования, но не должна использоваться в производственной установке;

  • -o опции, --old-options опции – опции, которые должны быть переданы непосредственно команде старого postgres, несколько вызовов параметров добавляются;

  • -O опции, --new-options опции – параметры, которые должны быть переданы непосредственно новой команде postgres, несколько вызовов параметров добавляются;

  • -p порт, --old-port=порт – старый номер порта кластера, переменная среды PGPORTOLD;

  • -P порт, --new-port=порт – новый номер порта кластера, переменная среды PGPORTNEW;

  • -r, --retain – сохранять файлы SQL и журнала даже после успешного завершения;

  • -s директория, --socketdir=директория – директория для использования сокетов postmaster во время обновления, по умолчанию используется текущая рабочая директория, переменная окружения PGSOCKETDIR;

  • -U username, --username=username – имя пользователя установщика кластера, переменная окружения PGUSER;

  • -v, --verbose – включить подробное внутреннее ведение журнала;

  • -V, --version – отобразите информацию о версии, затем выйдите;

  • --clone – использование эффективного клонирования файлов (также известного как «reflinks» в некоторых системах) вместо копирования файлов в новый кластер. Это может обеспечить практически мгновенное копирование файлов данных, обеспечивая преимущества скорости -k/--link, при этом оставляя старый кластер нетронутым.

    примечание

    Клонирование файлов поддерживается только в некоторых операционных системах и файловых системах. Если оно выбрано, но не поддерживается, выполнение pg_upgrade завершится ошибкой. В настоящее время это поддерживается в Linux (ядро 4.5 или более поздней версии) с использованием Btrfs и XFS (в файловых системах, созданных с поддержкой reflink), а также в macOS с APFS.

  • --test – запуск утилиты pg_upgrade для экземпляров (кластеров) с одинаковой версией системного каталога;

  • -?, --help – показать справку, затем выйти.

Использование модуля

Обновление с помощью утилиты

  1. Определите тип каталога инсталляции:

    • если используете версионный каталог (например, /opt/PostgreSQL/15) — ничего не перемещайте.
    • если используете не версионный каталог (например, /usr/local/pgsql) — переименуйте старую инсталляцию после остановки сервера:
    mv /usr/local/pgsql /usr/local/pgsql.old
  2. Соберите (для исходных установок) или установите новую версию PostgreSQL. Для пользовательского пути установки выполните:

    make prefix=/usr/local/pgsql.new install
  3. Инициализируйте новый кластер initdb с флагами, совместимыми со старым кластером. Новый кластер не запускайте.

  4. Установите в новый кластер общие объектные файлы (DLL/so) используемых расширений, соответствующие новой версии сервера. Не выполняйте CREATE EXTENSION — схемы будут перенесены автоматически. Если доступны обновления расширений, pg_upgrade сообщит и сгенерирует скрипт.

  5. Скопируйте пользовательские файлы полнотекстового поиска (словари, синонимы, тезаурусы, стоп-слова) из старого кластера в новый.

  6. Настройте аутентификацию (peer в pg_hba.conf или используйте ~/.pgpass) — pg_upgrade несколько раз подключается к старому и новому серверам.

  7. Остановите оба кластера:

    pg_ctl -D /opt/PostgreSQL/9.6 stop
    pg_ctl -D /opt/PostgreSQL/15 stop

    Серверы резервного копирования и потоковой репликации должны продолжать работу, чтобы принять все изменения.

  8. Проверьте состояние старого primary и standby с помощью pg_controldata. Убедитесь, что местоположение последней контрольной точки совпадает, а в postgresql.conf нового primary wal_level не равен minimal.

  9. Запустите pg_upgrade из новой версии. Укажите каталоги данных и bin старого/нового кластеров, при необходимости — пользователя и порты.

    При использовании --link обновление проходит быстрее и требует меньше места, но старый кластер после запуска нового использовать нельзя, для --link каталоги данных должны быть на одной ФС. --clone дает ту же скорость/экономию и сохраняет работоспособность старого кластера (также требует одной ФС и поддержки ОС/ФС).

    Задайте --jobs для параллелизма. Выполните --check для предварительных проверок (при планировании --link/--clone укажите их вместе с --check). Утилите требуется право записи в текущий каталог.

    Во время обновления исключите клиентские подключения (по умолчанию используется порт 50432).

  10. Обновите standby при режиме ссылок/клонирования с помощью rsync (на primary), либо пересоздайте реплики после запуска нового primary:

    • установите новые бинарии и расширения на все standby;
    • убедитесь, что новые каталоги данных standby отсутствуют или пусты (при необходимости удалите результаты initdb);
    • сохраните нужные конфигурационные файлы (postgresql.conf, postgresql.auto.conf, pg_hba.conf);
    • выполните rsync для каталогов кластера, табличных пространств и отдельного pg_wal (если вынесен);
    • настройте логическую репликацию (слоты не копируются и создаются заново).
  11. Восстановите изменения в pg_hba.conf и, при необходимости, приведите postgresql.conf/postgresql.auto.conf нового кластера к требуемым значениям.

  12. Запустите новый сервер, затем — обновленные standby (если применимо).

  13. Выполните пост-скрипты, сгенерированные pg_upgrade (находятся в pg_upgrade_output.d):

    psql --username=postgres --file=script.sql postgres

    Скрипты можно выполнять в любом порядке и удалять после выполнения.

    Внимание!

    До завершения скриптов перестройки не обращайтесь к таблицам, на которые они ссылаются (риск неверных результатов/низкой производительности). К остальным таблицам доступ разрешен сразу.

  14. Перестройте статистику планировщика:

    vacuumdb --all --analyze-only --jobs=4

    При необходимости ускорьте первичный сбор статистики опцией --analyze-in-stages и/или PGOPTIONS='-c vacuum_cost_delay=0'.

  15. Удалите каталоги данных старого кластера, запустив скрипт, указанный pg_upgrade (автоудаление невозможно при наличии пользовательских табличных пространств). При желании удалите каталоги старой инсталляции (bin, share).

  16. Вернитесь к старому кластеру при необходимости:

    • если использовался --check или не использовался --link — старый кластер не изменен, перезапустите его;

    • если использовался --link:

      • pg_upgrade прервался до расстановки ссылок — перезапустите старый кластер;
      • новый кластер не запускался — удалите суффикс .old у $PGDATA/global/pg_control и перезапустите старый кластер;
      • новый кластер запускался — общий набор файлов изменен, восстановите старый кластер из резервной копии.

Особенности использования

pg_upgrade создает рабочие файлы (дампы схем и прочее) в pg_upgrade_output.d нового кластера, при каждом запуске — подкаталог с меткой времени в формате ISO-8601 (%Y%m%dT%H%M%S). При успешном завершении каталог удаляется, при ошибках его содержимое пригодно для диагностики.

Утилита запускает временные postmaster в старом и новом каталогах данных. По умолчанию сокеты Unix создаются в текущем рабочем каталоге; при слишком длинном пути используйте -s для указания более короткого пути и обеспечьте недоступность каталога для чтения/записи посторонним.

Все случаи сбоев/восстановления/переиндексации будут отражены в сообщениях pg_upgrade; скрипты пост-обработки для перестроения таблиц и индексов создаются автоматически. При массовой автоматизации учтите: кластеры с одинаковыми схемами требуют одинаковых шагов пост-обработки (они зависят от схем, а не от пользовательских данных).

Для тестирования развертывания создайте копию кластера «только схема», заполните фиктивными данными и проведите обновление.

pg_upgrade не поддерживает обновление баз данных, содержащих столбцы с reg*-типами, ссылающимися на OID: regcollation, regconfig, regdictionary, regnamespace, regoper, regoperator, regproc, regprocedure.

примечание

regclass, regrole, regtype поддерживаются.

Если требуется --link, но необходимо исключить изменения старого кластера при запуске нового, используйте --clone. Если недоступно — сделайте копию старого кластера и обновите ее в режиме ссылок. Для валидной копии выполните rsync (грязная копия при работающем сервере), затем остановите сервер и повторите rsync --checksum для согласования. При необходимости исключите служебные файлы (например, postmaster.pid) или задействуйте снепшоты/копирование-при-записи — снимки/копии должны создаваться одновременно или при остановленном сервере.

Тестовый режим

При запуске утилиты с опцией --test она переходит в тестовый режим, который проверяет готовность к миграции табличных пространств без выполнения фактического переноса данных. Режим сопровождается использованием параметров --old-tablespace и --new-tablespace, предназначенных для указания путей к текущим и целевым табличным пространствам.

В тестовом режиме утилита анализирует совместимость между старым и новым табличными пространствами, заменяет их имена и выводит потенциальные проблемы или предупреждения.

Параметры --test, --old-tablespace и --new-tablespace разработаны исключительно для тестирования и не вызывают изменений в действующих базах данных.

Цель данной комбинации параметров — тестирование готовности инфраструктуры к миграции табличных пространств безопасным способом, исключающим потерю данных.