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

pg_upgrade

примечание

Эта страница переведена при помощи нейросети GigaChat.

warning

Изменено поведение оригинальной утилиты. Изменения описаны в рамках подраздела «Доработки Pangolin».

pg_upgrade — обновляет экземпляр сервера PostgreSQL.

Синтаксис

pg_upgrade -b oldbindir [-B newbindir] -d oldconfigdir -D newconfigdir [option ...]

Описание

pg_upgrade (ранее известная как pg_migrator) позволяет обновить данные в файлах PostgreSQL до более новой версии, избегая необходимости в дампе и восстановлении данных, что обычно требуется при обновлении между основными версиями (например, от 12.14 до 13.10 или от 14.9 до 15.5). Для незначительных обновлений версий (например, от 12.7 к 12.8 или от 14.1 к 14.5) эта операция не требуется.

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

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

pg_upgrade поддерживает обновления с версии 9.2.X и выше до текущей основной версии PostgreSQL, включая моментальные снимки и бета-версии.

warning

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

Параметры

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

-b bindir
--old-bindir=bindir

Указывает каталог старых исполняемых файлов PostgreSQL. Переменная окружения: PGBINOLD.

-B bindir
--new-bindir=bindir

Указывает каталог новых исполняемых файлов PostgreSQL. По умолчанию это каталог, в котором находится pg_upgrade. Переменная окружения: PGBINNEW.

-c
--check

Проверяет кластеры без внесения изменений в данные.

-d configdir
--old-datadir=configdir

Указывает каталог конфигурации старого кластера баз данных. Переменная окружения: PGDATAOLD.

-D configdir
--new-datadir=configdir

Указывает каталог конфигурации нового кластера баз данных. Переменная окружения: PGDATANEW.

-j njobs
--jobs=njobs

Указывает количество одновременных подключений и используемых процессов/потоков.

-k
--link

Использует жесткие ссылки вместо копирования файлов в новый кластер.

-N
--no-sync

Завершает процесс pg_upgrade без ожидания записи файлов на диск. Ускоряет выполнение, но при последующем сбое операционной системы может привести к повреждению каталога данных. По умолчанию утилита ждет, пока все файлы будут надежно записаны на диск.

Параметр используется при тестировании и не предназначен для производственной среды.

-o options
--old-options options

Указывает параметры, которые должны быть переданы старому процессу postgres. Несколько параметров складываются вместе.

-O options
--new-options options

Указывает параметры, которые должны быть переданы новому процессу postgres. Несколько параметров складываются вместе.

-p port
--old-port=port

Указывает номер порта старого кластера. Переменная окружения: PGPORTOLD.

-P port
--new-port=port

Указывает номер порта нового кластера. Переменная окружения: PGPORTNEW.

-r
--retain

Сохраняет файлы SQL и журналов, даже если обновление завершилось успешно.

-s dir
--socketdir=dir

Указывает каталог для сокетов postmaster во время обновления. По умолчанию используется текущий рабочий каталог. Переменная окружения: PGSOCKETDIR.

-U username
--username=username

Указывает имя пользователя, выполняющего установку кластера. Переменная окружения: PGUSER.

-v
--verbose

Включает подробный журнал выполнения.

-V
--version

Выводит версию pg_upgrade и завершается.

--clone

Использует эффективное клонирование файлов (также известное как «reflinks» в некоторых системах) вместо их копирования в новый кластер. Это может значительно ускорить процесс копирования, оставляя старый кластер нетронутым.

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

--copy

Копировать файлы в новый кластер. Это поведение по умолчанию. Подробнее смотрите также --link, --clone, --copy-file-range и --swap.

--copy-file-range

Использовать системный вызов copy_file_range для эффективного копирования. На некоторых файловых системах это дает результаты, аналогичные --clone, совместно используя физические блоки диска, тогда как на других файловых системах он может все равно копировать блоки, но делать это по оптимизированному пути. В настоящее время он поддерживается в Linux и FreeBSD.

--set-char-signedness=option

Позволяет вручную задать знаковое значение типа char по умолчанию для новых кластеров. Возможные значения: signed и unsigned.

В языке C знаковое значение типа char по умолчанию (если оно не указано явно) различается в зависимости от платформы. Например, на процессорах x86 тип char по умолчанию равен signed char, а на процессорах ARM — unsigned char.

Начиная с PostgreSQL 18, кластеры баз данных поддерживают собственную настройку знакового значения типа char по умолчанию, которая может использоваться для обеспечения согласованного поведения на разных платформах с различными значениями знакового значения типа char по умолчанию. По умолчанию pg_upgrade сохраняет настройку знакового значения типа char при обновлении с существующего кластера. Однако при обновлении с PostgreSQL 17 или более ранних версий pg_upgrade принимает значение знакового значения типа char той платформы, на которой он был создан.

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

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

Если кластер уже был перенесен на платформу с другой знаковой символьной структурой (например, с системы на базе x86 на систему на базе ARM), следует использовать эту опцию, чтобы указать знаковую структуру, соответствующую знаковой символьной структуре по умолчанию исходной платформы. Кроме того, крайне важно не изменять никакие файлы данных между миграцией файлов данных и запуском pg_upgrade. pg_upgrade должна быть первой операцией, которая запускает кластер на новой платформе.

--swap

Переместите каталоги данных из старого кластера в новый кластер. Затем замените файлы каталога файлами, сгенерированными для нового кластера. Этот режим может превосходить по производительности --link, --clone, --copy и --copy-file-range, особенно на кластерах с большим количеством связей.

Однако этот режим создает множество ненужных файлов в старом кластере, что может затянуть этап синхронизации файлов, если используется --sync-method=syncfs. Поэтому рекомендуется использовать --sync-method=fsync с --swap.

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

--sync-method=method

Когда установлено значение fsync, которое является значением по умолчанию, pg_upgrade рекурсивно откроет и синхронизирует все файлы в каталоге данных обновленного кластера. Поиск файлов будет следовать символическим ссылкам для каталога WAL и каждого настроенного табличного пространства.

В Linux вместо syncfs можно использовать запрос к операционной системе для синхронизации всей файловой системы, содержащей каталог данных обновленного кластера, его файлы WAL и каждое табличное пространство.

Этот параметр не оказывает никакого влияния, когда используется --no-sync.

-?
--help

Показывает справку о параметрах командной строки утилиты pg_upgrade и завершается.

Использование

примечание

Этапы обновления кластеров логической репликации здесь не рассматриваются, подробности смотрите в разделе «Обновление».

Ниже приведены шаги для выполнения обновления с помощью pg_upgrade:

  1. Необязательно: переместите старый кластер

    Если используется каталог установки с версией в имени, например /opt/PostgreSQL/18, перемещать старый кластер не нужно. Графические установщики всегда используют такие каталоги.

    Если каталог установки не привязан к версии, например /usr/local/pgsql, необходимо переместить текущую установку PostgreSQL, чтобы она не конфликтовала с новой. После остановки текущего сервера безопасно переименовать каталог установки. Например, если старый каталог — /usr/local/pgsql:

    mv /usr/local/pgsql /usr/local/pgsql.old
  2. Для установок из исходников: соберите новую версию

    Соберите исходный код новой версии PostgreSQL с флагами configure, совместимыми со старым кластером. pg_upgrade проверит pg_controldata, чтобы убедиться в совместимости настроек перед началом обновления.

  3. Установите новые исполняемые файлы PostgreSQL

    Установите бинарные файлы и вспомогательные файлы нового сервера. pg_upgrade входит в стандартную установку.

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

    make prefix=/usr/local/pgsql.new install
  4. Инициализируйте новый кластер PostgreSQL

    Инициализируйте новый кластер с помощью initdb, используя флаги, совместимые со старым кластером. Многие готовые установщики выполняют этот шаг автоматически. Запускать новый кластер не требуется.

  5. Установите shared-объекты расширений

    Многие расширения и пользовательские модули (из contrib или других источников) используют shared-объекты (или DLL), например pgcrypto.so. Если старый кластер их использовал, в новый кластер необходимо установить соответствующие версии этих файлов (обычно через команды ОС). Не загружайте определения схем (например, CREATE EXTENSION pgcrypto), так как они будут перенесены из старого кластера. Если доступны обновления расширений, pg_upgrade сообщит об этом и создаст скрипт для их последующего обновления.

  6. Скопируйте пользовательские файлы полнотекстового поиска

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

  7. Настройте аутентификацию

    pg_upgrade будет многократно подключаться к старому и новому серверам, поэтому рекомендуется установить аутентификацию peer в pg_hba.conf или использовать файл ~/.pgpass.

  8. Остановите оба сервера

    Убедитесь, что оба сервера остановлены. На Unix:

    pg_ctl -D /opt/PostgreSQL/12 stop
    pg_ctl -D /opt/PostgreSQL/18 stop

    На Windows (используя имена служб):

    NET STOP postgresql-12
    NET STOP postgresql-18

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

  9. Подготовьте обновление резервных серверов

    Если резервные серверы обновляются методами из шага 11, убедитесь, что старые резервные серверы синхронизированы: выполните pg_controldata для старого основного и резервных кластеров и проверьте, что значения Latest checkpoint location совпадают. Также убедитесь, что в postgresql.conf нового основного кластера параметр wal_level не установлен в minimal.

  10. Запустите pg_upgrade

    Всегда запускайте бинарный файл pg_upgrade новой версии, а не старой. Укажите пути к каталогам данных и исполняемых файлов (bin) для старого и нового кластеров. Также можно задать пользователя, порт и режим работы с файлами данных: link, clone, swap вместо стандартного копирования.

    РежимПреимуществаОграничения
    --linkБыстро, экономит местоСтарый кластер станет недоступен после запуска нового; оба каталога должны быть в одной ФС
    --cloneКак link, но старый кластер остается рабочимТребует одной ФС; доступен не на всех ОС/ФС
    --swapСамый быстрый при большом числе объектовСтарый кластер недоступен с начала передачи файлов; требует одной ФС

    Параметр --jobs N (N ≥ 2) позволяет обрабатывать базы данных и табличные пространства параллельно. Хорошее начальное значение — количество ядер процессора.

    Для Windows: запустите от имени администратора, используя кавычки для путей:

    pg_upgrade.exe ^
    --old-datadir "C:/Program Files/PostgreSQL/12/data" ^
    --new-datadir "C:/Program Files/PostgreSQL/18/data" ^
    --old-bindir "C:/Program Files/PostgreSQL/12/bin" ^
    --new-bindir "C:/Program Files/PostgreSQL/18/bin"

    После запуска pg_upgrade проверит совместимость кластеров и выполнит обновление. Для предварительной проверки используйте pg_upgrade --check (можно запускать при работающем старом сервере). Этот режим также покажет необходимые ручные изменения после обновления. Для режимов link/clone/copy-file-range/swap добавьте соответствующий флаг к --check для включения специфичных проверок.

    pg_upgrade требует прав на запись в текущем каталоге.

    Во время обновления никто не должен подключаться к кластерам. По умолчанию pg_upgrade использует порт 50432, чтобы избежать случайных подключений. При обновлении можно использовать один порт для обоих кластеров, так как они не работают одновременно. Но при проверке работающего старого сервера порты должны различаться.

    Если при восстановлении схемы возникнет ошибка, pg_upgrade завершится, и потребуется откат к старому кластеру (смотрите шаг 17). Чтобы повторить попытку, измените старый кластер так, чтобы восстановление схемы прошло успешно. Если проблема в модуле contrib, возможно, потребуется удалить его из старого кластера и установить в новый после обновления (если модуль не хранит пользовательские данные).

  11. Обновите резервные серверы потоковой репликации и лог-шиппинга

    При использовании режима link и наличии резервных серверов их можно быстро обновить через rsync на основном сервере. Не запускайте серверы пока.

    Если link не использовался, rsync применяться не должен или требуется более простое решение — пропустите этот раздел и просто пересоздайте резервные серверы после завершения pg_upgrade и запуска нового основного сервера.

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

    2. Убедитесь, что новые каталоги данных резервных серверов не существуют Если initdb был запущен, удалите новые каталоги данных на резервных серверах.

    3. Установите shared-объекты расширений Установите те же shared-объекты расширений, что и в новом основном кластере.

    4. Остановите резервные серверы Если они еще работают, остановите их (смотрите Шаг 8).

    5. Сохраните конфигурационные файлы Сохраните нужные файлы из старых конфигурационных каталогов: postgresql.conf (и включенные файлы), postgresql.auto.conf, pg_hba.conf — они будут перезаписаны или удалены на следующем шаге.

    6. Запустите rsync При использовании режима link резервные серверы можно быстро обновить через rsync. На основном сервере, из каталога выше старых и новых кластеров, выполните для каждого резервного сервера:

      rsync --archive --delete --hard-links --size-only --no-inc-recursive old_cluster new_cluster remote_dir

      Где old_cluster и new_cluster — относительные пути на основном сервере, а remote_dir — путь выше каталогов кластеров на резервном сервере. Структура каталогов должна совпадать. Пример:

      rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/PostgreSQL/12 \
      /opt/PostgreSQL/18 standby.example.com:/opt/PostgreSQL

      Для предварительного просмотра используйте --dry-run. rsync можно запускать на обновленном резервном сервере для обновления других резервных серверов, если он еще не был запущен.

      Механизм: rsync воспроизводит ссылки, созданные pg_upgrade в режиме link, находя соответствующие файлы в старом кластере резервного сервера и создавая ссылки в новом. Файлы, не связанные на основном сервере, копируются (обычно они небольшие). Это обеспечивает быстрое обновление резервных серверов. К сожалению, rsync избыточно копирует файлы временных и unlogged-таблиц, так как они обычно отсутствуют на резервных серверах.

      При наличии табличных пространств выполните аналогичную команду rsync для каждого:

      rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tblsp/PG_12_201909212 \
      /vol1/pg_tblsp/PG_18_202307071 standby.example.com:/vol1/pg_tblsp

      Если pg_wal вынесен за пределы каталога данных, выполните rsync и для этих каталогов.

    7. Настройте потоковую репликацию и лог-шиппинг Настройте серверы для лог-шиппинга. Запускать pg_backup_start() / pg_backup_stop() или делать бэкап ФС не нужно — резервные серверы остаются синхронизированными.

      • Если старый основной сервер версии до 17.0: слоты репликации не копируются — все слоты на старом резервном сервере нужно воссоздать вручную.
      • Если версия 17.0 или новее: копируются только логические слоты; остальные слоты нужно воссоздать вручную.
  12. Восстановите pg_hba.conf

    Если pg_hba.conf изменялось, восстановите исходные настройки. Возможно, потребуется также адаптировать другие конфигурационные файлы нового кластера под старый: postgresql.conf (и включенные файлы), postgresql.auto.conf.

  13. Запустите новый сервер

    Теперь можно безопасно запустить новый сервер, а затем и резервные серверы, обновленные через rsync.

  14. Пост-обработка после обновления

    Если требуется пост-обработка, pg_upgrade выведет предупреждения и сгенерирует скрипты, которые необходимо выполнить администратору. Каждый скрипт подключается к соответствующей базе данных. Выполняйте так:

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

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

    Осторожно В общем случае небезопасно обращаться к таблицам, указанным в скриптах перестроения, до завершения выполнения этих скриптов — это может привести к некорректным результатам или снижению производительности. Таблицы, не упомянутые в скриптах, доступны сразу.

  15. Статистика

    Если не указан параметр --no-statistics, pg_upgrade перенесет большую часть статистики оптимизатора из старого кластера в новый. Не переносятся: статистика, созданная явно через CREATE STATISTICS, кастомная статистика расширений или статистика системы кумулятивной статистики.

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

    1. Быстро создайте минимальную статистику для отношений без нее:
      vacuumdb --all --analyze-in-stages --missing-stats-only

    2. Затем обновите кумулятивную статистику для всех отношений:
      vacuumdb --all --analyze-only

    Для ускорения используйте --jobs. Если установлен vacuum_cost_delay ≠ 0, его можно временно переопределить через PGOPTIONS:

    PGOPTIONS='-c vacuum_cost_delay=0' vacuumdb ...
  16. Удалите старый кластер

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

  17. Откат к старому кластеру

    Если после запуска pg_upgrade требуется вернуться к старому кластеру, варианты:

    • Если использовался --check — старый кластер не изменялся; его можно перезапустить.
    • Если не использовались --link и --swap — старый кластер не изменялся; его можно перезапустить.
    • Если использовался --link:
      • Если pg_upgrade прервался до начала создания ссылок — старый кластер не изменялся.
      • Если новый кластер не запускался — к старому кластеру добавлен суффикс .old у файла $PGDATA/global/pg_control. Удалите суффикс и перезапустите старый кластер.
      • Если новый кластер запускался — общие файлы были изменены; использование старого кластера небезопасно. Требуется восстановление из бэкапа.
    • Если использовался --swap:
      • Если pg_upgrade прервался до сообщения о небезопасности запуска старого кластера — старый кластер не изменялся.
      • Если pg_upgrade сообщил, что старый кластер больше небезопасен для запуска — он был изменен деструктивно. Требуется восстановление из бэкапа.

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

Некоторые переменные окружения могут использоваться для задания значений параметров командной строки по умолчанию:

PGBINOLD

Каталог исполняемых файлов старой версии PostgreSQL, параметр -b/--old-bindir.

PGBINNEW

Каталог исполняемых файлов новой версии PostgreSQL, параметр -B/--new-bindir.

PGDATAOLD

Каталог конфигурации старого кластера баз данных, параметр -d/--old-datadir.

PGDATANEW

Каталог конфигурации нового кластера баз данных, параметр -D/--new-datadir.

PGPORTOLD

Номер порта старого кластера, параметр -p/--old-port.

PGPORTNEW

Номер порта нового кластера, параметр -P/--new-port.

PGSOCKETDIR

Директория для использования сокетов postmaster во время обновления, параметр -s/--socketdir.

PGUSER

Имя пользователя инсталляции кластера, параметр -U/--username.

Примечания

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

В процессе выполнения pg_upgrade запускает кратковременные серверные процессы PostgreSQL (postmaster) как для старого, так и для нового кластеров. Временные Unix-сокеты для взаимодействия с этими процессами по умолчанию создаются в текущем рабочем каталоге. Однако в некоторых случаях путь к этому каталогу может быть слишком длинным для корректного формирования имени сокета. В таких ситуациях используйте параметр -s, позволяющий указать альтернативный каталог с более коротким путем. Этот каталог должен быть надежно защищен от доступа со стороны других пользователей. Поддержка данного параметра отсутствует в Windows.

Если во время обновления потребуются переиндексация или перестройка объектов, pg_upgrade отобразит соответствующие сообщения. При этом будут автоматически созданы SQL-сценарии для пересоздания затронутых таблиц и индексов после обновления. При автоматизации обновления множества кластеров стоит учитывать, что кластеры с одинаковыми структурами баз данных, как правило, требуют одинакового набора последующих действий, поскольку они определяются схемой, а не содержимым баз данных.

Для предварительного тестирования можно создать копию старого кластера, включающую только структуру (схему), дополнить ее фиктивными данными и выполнить обновление.

pg_upgrade не поддерживает обновление баз данных, содержащих столбцы, использующие системные типы данных семейства reg*, ссылающиеся на OID:

  • regcollation
  • regconfig
  • regdictionary
  • regnamespace
  • regoper
  • regoperator
  • regproc
  • regprocedure

Обновление возможно для типов regclass, regrole и regtype.

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

Для получения корректной копии работающего кластера рекомендуется сначала создать так называемую «грязную» копию с помощью rsync, пока старый сервер продолжает работать. Затем необходимо остановить сервер и снова выполнить rsync с параметром --checksum, чтобы учесть все возможные изменения и добиться согласованности копии. Параметр --checksum критичен, так как rsync использует точность времени модификации файлов с шагом в одну секунду.

При необходимости можно исключить отдельные файлы, такие как postmaster.pid, как указано в разделе «Создание резервной копии базы данных с использованием низкоуровневого API», чтобы избежать нежелательного поведения.

сли файловая система поддерживает снимки файловой системы или копирование при записи, эти возможности можно использовать для создания резервной копии старого кластера и табличных пространств. Однако такие снимки и копии должны быть сделаны одновременно либо в период, когда сервер базы данных остановлен.

Смотрите также

initdb, pg_ctl, pg_dump, postgres

Доработки Pangolin

Для обеспечения корректной работы обновления стендов, где используются расширения с предопределенными SRID, а также типы данных geometry и geography в виде массивов и объекты физического хранения на их основе, алгоритм работы pg_upgrade был разделен на 2 фазы. В общем случае в первую фазу обновления попадают только объекты, относящиеся к расширениям, определенным по умолчанию или заданным с помощью параметра --two-phases-extensions. Список расширений заданных по умолчанию приведен ниже:

fuzzystrmatch, postgis, postgis_raster, postgis_sfcgal, postgis_topology, postgis_tiger_geocoder, address_standardizer, address_standardizer_data_us, pgrouting

Во вторую фазу попадают все остальные объекты, не попавшие в первую фазу.

Более подробно алгоритм работы утилиты выглядит так:

  1. Создание дампов всех баз данных обновляемого сервера в режиме --schema-only.

  2. Для базы template1 применяется двухфазное обновление:

    1. Восстановление на новом сервере только схем объектов расширений.
    2. Копирование файлов данных, относящихся только к объектам расширений.
    3. Восстановление на новом сервере схем БЕЗ объектов расширений.
    4. Копирование файлов данных, НЕ относящихся к объектам расширений.
  3. Для всех остальных баз данных (исключая template1) применяется двухфазное обновление:

    1. Восстановление на новом сервере только схем объектов расширений.
    2. Копирование файлов данных, относящихся только к объектам расширений.
    3. Восстановление на новом сервере схем БЕЗ объектов расширений.
    4. Линковка файлов данных, НЕ относящихся к объектам расширений.

Обработка базы данных template1 явно делается перед обработкой всех остальных баз данных, как это и было сделано в ванильной версии, так как из template1 создаются все остальные базы.

На этапах 2.2, 2.4, 3.2 производится принудительное копирование данных для обеспечения отказоустойчивости и возможности восстановления работы обновляемого сервера без каких-либо дополнительных манипуляций в случае, если работа pg_upgrade будет прервана по какой-либо причине вплоть до этапа 3.4. До этого момента никакие данные обновляемого сервера еще не затронуты. После выполнения этапа 3.4 и запуска нового сервера данные обновляемого сервера уже необходимо восстанавливать из резервной копии.

Чтобы отделить отношения объектов расширений от остальных объектов базы данных при линковке/копировании, используется запрос вида:

SQL-запрос выводящий список OID отношений объектов расширений

WITH cnst(exts,objs) AS (
VALUES ('{fuzzystrmatch,postgis,postgis_raster,postgis_sfcgal,postgis_topology,postgis_tiger_geocoder,address_standardizer,address_standardizer_data_us,pgrouting}'::name[]
,'{extension,schema,default acl,language,type,array type,table,default value,sequence,operator,operator class,operator family,cast,aggregate,function,procedure,view,materialized view,rule}'::name[])
), objs(classid,objid,objsubid,extname,"type","schema","name","identity") AS (
SELECT
pgd.classid,
pgd.objid,
pgd.objsubid,
pge.extname,
(pg_catalog.pg_identify_object(pgd.classid,pgd.objid,pgd.objsubid)).*
FROM pg_catalog.pg_depend pgd
JOIN pg_catalog.pg_extension pge ON pge.oid=pgd.refobjid
JOIN cnst ON true
WHERE
pge.extname= ANY(exts)
AND pgd.deptype IN ('e','x')
AND pgd.refclassid='pg_catalog.pg_extension'::pg_catalog.regclass
), ext_objs(classid,objid,objsubid,extname,"type","schema","name","identity") AS (
SELECT DISTINCT
'pg_catalog.pg_class'::regclass::oid,
pgo.oid,
0::oid,
objs.extname,
(pg_catalog.pg_identify_object('pg_catalog.pg_class'::regclass,pgo.oid,0::int4)).*
FROM pg_catalog.pg_class pgc
JOIN objs ON objs.classid='pg_catalog.pg_class'::regclass::oid AND objs.objid = pgc.oid
JOIN pg_catalog.pg_class pgo ON pgc.oid=pgo.oid
OR pgo.oid=pgc.reltoastrelid
OR pgo.oid IN (SELECT indexrelid FROM pg_catalog.pg_index WHERE indrelid=pgc.oid)
OR pgo.oid IN (SELECT indexrelid FROM pg_catalog.pg_index WHERE indrelid=pgc.reltoastrelid)
WHERE pgo.relkind =ANY('{r,i,t,m,G}')
)
SELECT ext_objs.objid FROM ext_objs
JOIN cnst ON ext_objs.extname=ANY(cnst.exts)
ORDER BY objid
;

В данной реализации предусмотрена возможность отключения механизма двухфазного обновления с помощью параметра утилиты pg_upgrade --no-two-phases. Использование этого ключа вернет pg_upgrade к оригинальному поведению.

Параметр -e, --two-phases-extensions позволяет задать свой список расширений, объекты которых попадут в первую фазу обработки. Порядок следования расширений в этом списке важен, так как обработка и попадание в дампы первой фазы будет идти как раз в порядке следования в списке слева-направо. Это важно, если одно расширение зависит от другого. Пример использования новых параметров:

pg_upgrade --old-bindir=/usr/pangolin/bin --new-bindir=/opt/pangolin-dbms-server/bin --new-bindirclient=/opt/pangolin-dbms-client/bin --old-datadir=/pgdata/xx/pgdata --new-datadir=/pgdata/xx/pgdata --retain --link --no-two-phases

pg_upgrade --old-bindir=/usr/pangolin/bin --new-bindir=/opt/pangolin-dbms-server/bin --new-bindirclient=/opt/pangolin-dbms-client/bin --old-datadir=/pgdata/xx/pgdata --new-datadir=/pgdata/xx/pgdata --retain --link --two-phases-extensions=fuzzystrmatch,postgis
warning

Использование вместе параметров --no-two-phases и --two-phases-extensions недопустимо и приведет к остановке работы утилиты pg_upgrade.

Различия в выводе можно увидеть здесь:

Журнал двухфазного обновленияЖурнал однофазного обновления
Performing Consistency ChecksPerforming Consistency Checks
Checking cluster versions okChecking cluster versions ok
Checking old cluster type PangolinChecking old cluster type Pangolin
Checking database user is the install user okChecking database user is the install user ok
Checking database connection settings okChecking database connection settings ok
Checking for prepared transactions okChecking for prepared transactions ok
Checking for system-defined composite types in user tables okChecking for system-defined composite types in user tables ok
Checking for reg* data types in user tables okChecking for reg* data types in user tables ok
Checking for arrays of predefined domains in user tables okChecking for arrays of predefined domains in user tables ok
Checking for contrib/isn with bigint-passing mismatch okChecking for contrib/isn with bigint-passing mismatch ok
Creating dump of global objects okCreating dump of global objects ok
Creating dump of extensions schemasCreating dump of database schemas
okok
Creating dump of database schemas excluding extensionsok
ok
ok
Checking protection status okChecking protection status ok
Checking for presence of required libraries okChecking for presence of required libraries ok
Checking for hardlink for PG_VERSION okChecking for hardlink for PG_VERSION ok
Checking for hardlink for PRODUCT_VERSION okChecking for hardlink for PRODUCT_VERSION ok
Checking for hardlink for global/enc_keys.json is absent okChecking for hardlink for global/enc_keys.json is absent ok
Checking for hardlink for global/enc_settings.cfg is absent okChecking for hardlink for global/enc_settings.cfg is absent ok
Checking database user is the install user okChecking database user is the install user ok
Checking for prepared transactions okChecking for prepared transactions ok
Checking for new cluster tablespace directories okChecking for new cluster tablespace directories ok
If pg_upgrade fails after this point, you must re-initdb theIf pg_upgrade fails after this point, you must re-initdb the
new cluster before continuing.new cluster before continuing.
Performing UpgradePerforming Upgrade
Analyzing all rows in the new cluster okAnalyzing all rows in the new cluster ok
Freezing all rows in the new cluster okFreezing all rows in the new cluster ok
Deleting files from new pg_xact okDeleting files from new pg_xact ok
Copying old pg_xact to new server okCopying old pg_xact to new server ok
Setting oldest XID for new cluster okSetting oldest XID for new cluster ok
Setting next transaction ID for new cluster okSetting next transaction ID for new cluster ok
Deleting files from new pg_multixact/offsets okDeleting files from new pg_multixact/offsets ok
Copying old pg_multixact/offsets to new server okCopying old pg_multixact/offsets to new server ok
Deleting files from new pg_multixact/members okDeleting files from new pg_multixact/members ok
Copying old pg_multixact/members to new server okCopying old pg_multixact/members to new server ok
Setting next multixact ID and offset for new cluster okSetting next multixact ID and offset for new cluster ok
Resetting WAL archives okResetting WAL archives ok
Moving TDE settings okMoving TDE settings ok
Setting frozenxid and minmxid counters in new cluster okSetting frozenxid and minmxid counters in new cluster ok
Restoring global objects in the new cluster okRestoring global objects in the new cluster ok
Pre-phase of restoring template1 schema in the new cluster okRestoring database template schemas in the new cluster
Pre-phase of copying user relation filesok
ok
Restoring template1 schema in the new cluster ok
Copying user relation files
ok
Pre-phase of restoring no template1 db's schemas in the new cluster
ok
Pre-phase of copying user relation files
ok
Restoring no template1 db's schemas in the new cluster
ok
Merging TDE settings okMerging TDE settings ok
Adding ".old" suffix to old global/pg_control okAdding ".old" suffix to old global/pg_control ok
If you want to start the old cluster, you will need to removeIf you want to start the old cluster, you will need to remove
the ".old" suffix from /usr/pangolin-6.4/pgdata/global/pg_control.old.the ".old" suffix from /usr/pangolin-6.4/pgdata/global/pg_control.old.
Because "link" mode was used, the old cluster cannot be safelyBecause "link" mode was used, the old cluster cannot be safely
started once the new cluster has been started.started once the new cluster has been started.
Linking user relation filesLinking user relation files
okok
Setting next OID for new cluster okSetting next OID for new cluster ok
Sync data directory to disk okSync data directory to disk ok
Creating script to delete old cluster okCreating script to delete old cluster ok
Checking for extension updates okChecking for extension updates ok
Upgrade CompleteUpgrade Complete
Optimizer statistics are not transferred by pg_upgrade.Optimizer statistics are not transferred by pg_upgrade.
Once you start the new server, consider running:Once you start the new server, consider running:
/usr/pangolin-dbms-client-6.6/bin/vacuumdb --all --analyze-in-stages/usr/pangolin-dbms-client-6.6/bin/vacuumdb --all --analyze-in-stages
Running this script will delete the old cluster's data files:Running this script will delete the old cluster's data files:
./delete_old_cluster.sh./delete_old_cluster.sh