pg_upgrade
Эта страница переведена при помощи нейросети GigaChat.
Изменено поведение оригинальной утилиты. Изменения описаны в рамках подраздела «Доработки 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, включая моментальные снимки и бета-версии.
Обновление кластера приводит к выполнению на целевом сервере произвольного кода по выбору суперпользователей исходного сервера. Перед обновлением убедитесь, что суперпользователи исходного сервера являются доверенными.
Параметры
Для утилиты 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:
-
Необязательно: переместите старый кластер
Если используется каталог установки с версией в имени, например
/opt/PostgreSQL/18, перемещать старый кластер не нужно. Графические установщики всегда используют такие каталоги.Если каталог установки не привязан к версии, например
/usr/local/pgsql, необходимо переместить текущую установку PostgreSQL, чтобы она не конфликтовала с новой. После остановки текущего сервера безопасно переименовать каталог установки. Например, если старый каталог —/usr/local/pgsql:mv /usr/local/pgsql /usr/local/pgsql.old -
Для установок из исходников: соберите новую версию
Соберите исходный код новой версии PostgreSQL с флагами
configure, совместимыми со старым кластером.pg_upgradeпроверитpg_controldata, чтобы убедиться в совместимости настроек перед началом обновления. -
Установите новые исполняемые файлы PostgreSQL
Установите бинарные файлы и вспомогательные файлы нового сервера.
pg_upgradeвходит в стандартную установку.Для сборок из исходников, если требуется установить новый сервер в пользовательский каталог, используйте переменную
prefix:make prefix=/usr/local/pgsql.new install -
Инициализируйте новый кластер PostgreSQL
Инициализируйте новый кластер с помощью
initdb, используя флаги, совместимые со старым кластером. Многие готовые установщики выполняют этот шаг автоматически. Запускать новый кластер не требуется. -
Установите shared-объекты расширений
Многие расширения и пользовательские модули (из
contribили других источников) используют shared-объекты (или DLL), напримерpgcrypto.so. Если старый кластер их использовал, в новый кластер необходимо установить соответствующие версии этих файлов (обычно через команды ОС). Не загружайте определения схем (например,CREATE EXTENSION pgcrypto), так как они будут перенесены из старого кластера. Если доступны обновления расширений,pg_upgradeсообщит об этом и создаст скрипт для их последующего обновления. -
Скопируйте пользовательские файлы полнотекстового поиска
Скопируйте любые пользовательские файлы полнотекстового поиска (словари, синонимы, тезаурусы, стоп-слова) из старого кластера в новый.
-
Настройте аутентификацию
pg_upgradeбудет многократно подключаться к старому и новому серверам, поэтому рекомендуется установить аутентификациюpeerвpg_hba.confили использовать файл~/.pgpass. -
Остановите оба сервера
Убедитесь, что оба сервера остановлены. На Unix:
pg_ctl -D /opt/PostgreSQL/12 stop
pg_ctl -D /opt/PostgreSQL/18 stopНа Windows (используя имена служб):
NET STOP postgresql-12
NET STOP postgresql-18Серверы потоковой репликации и лог-шиппинга должны быть запущены во время остановки, чтобы получить все изменения.
-
Подготовьте обновление резервных серверов
Если резервные серверы обновляются методами из шага 11, убедитесь, что старые резервные серверы синхронизированы: выполните
pg_controldataдля старого основного и резервных кластеров и проверьте, что значенияLatest checkpoint locationсовпадают. Также убедитесь, что вpostgresql.confнового основного кластера параметрwal_levelне установлен вminimal. -
Запустите
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, возможно, потребуется удалить его из старого кластера и установить в новый после обновления (если модуль не хранит пользовательские данные). -
Обновите резервные серверы потоковой репликации и лог-шиппинга
При использовании режима
linkи наличии резервных серверов их можно быстро обновить черезrsyncна основном сервере. Не запускайте серверы пока.Если
linkне использовался,rsyncприменяться не должен или требуется более простое решение — пропустите этот раздел и просто пересоздайте резервные серверы после завершенияpg_upgradeи запуска нового основного сервера.-
Установите новые бинарные файлы PostgreSQL на резервные серверы Убедитесь, что новые бинарные и вспомогательные файлы установлены на всех резервных серверах.
-
Убедитесь, что новые каталоги данных резервных серверов не существуют Если
initdbбыл запущен, удалите новые каталоги данных на резервных серверах. -
Установите shared-объекты расширений Установите те же shared-объекты расширений, что и в новом основном кластере.
-
Остановите резервные серверы Если они еще работают, остановите их (смотрите Шаг 8).
-
Сохраните конфигурационные файлы Сохраните нужные файлы из старых конфигурационных каталогов:
postgresql.conf(и включенные файлы),postgresql.auto.conf,pg_hba.conf— они будут перезаписаны или удалены на следующем шаге. -
Запустите
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и для этих каталогов. -
Настройте потоковую репликацию и лог-шиппинг Настройте серверы для лог-шиппинга. Запускать
pg_backup_start()/pg_backup_stop()или делать бэкап ФС не нужно — резервные серверы остаются синхронизированными.- Если старый основной сервер версии до 17.0: слоты репликации не копируются — все слоты на старом резервном сервере нужно воссоздать вручную.
- Если версия 17.0 или новее: копируются только логические слоты; остальные слоты нужно воссоздать вручную.
-
-
Восстановите
pg_hba.confЕсли
pg_hba.confизменялось, восстановите исходные настройки. Возможно, потребуется также адаптировать другие конфигурационные файлы нового кластера под старый:postgresql.conf(и включенные файлы),postgresql.auto.conf. -
Запустите новый сервер
Теперь можно безопасно запустить новый сервер, а затем и резервные серверы, обновленные через
rsync. -
Пост-обработка после обновления
Если требуется пост-обработка,
pg_upgradeвыведет предупреждения и сгенерирует скрипты, которые необходимо выполнить администратору. Каждый скрипт подключается к соответствующей базе данных. Выполняйте так:psql --username=postgres --file=script.sql postgresСкрипты можно запускать в любом порядке и удалить после выполнения.
Осторожно В общем случае небезопасно обращаться к таблицам, указанным в скриптах перестроения, до завершения выполнения этих скриптов — это может привести к некорректным результатам или снижению производительности. Таблицы, не упомянутые в скриптах, доступны сразу.
-
Статистика
Если не указан параметр
--no-statistics,pg_upgradeперенесет большую часть статистики оптимизатора из старого кластера в новый. Не переносятся: статистика, созданная явно черезCREATE STATISTICS, кастомная статистика расширений или статистика системы кумулятивной статистики.Поскольку не вся статистика переносится, в конце обновления будут предложены команды для ее восстановления. Возможно, потребуется настроить параметры подключения под новый кластер.
- Быстро создайте минимальную статистику для отношений без нее:
vacuumdb --all --analyze-in-stages --missing-stats-only - Затем обновите кумулятивную статистику для всех отношений:
vacuumdb --all --analyze-only
Для ускорения используйте
--jobs. Если установленvacuum_cost_delay ≠ 0, его можно временно переопределить черезPGOPTIONS:PGOPTIONS='-c vacuum_cost_delay=0' vacuumdb ... - Быстро создайте минимальную статистику для отношений без нее:
-
Удалите старый кластер
После успешного обновления можно удалить каталоги данных старого кластера, запустив скрипт, упомянутый при завершении
pg_upgrade. (Автоматическое удаление невозможно, если в старом каталоге данных есть пользовательские табличные пространства.) Также можно удалить старые установочные каталоги (bin,shareи так далее). -
Откат к старому кластеру
Если после запуска
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:
regcollationregconfigregdictionaryregnamespaceregoperregoperatorregprocregprocedure
Обновление возможно для типов 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
Во вторую фазу попадают все остальные объекты, не попавшие в первую фазу.
Более подробно алгоритм работы утилиты выглядит так:
-
Создание дампов всех баз данных обновляемого сервера в режиме
--schema-only. -
Для базы
template1применяется двухфазное обновление:- Восстановление на новом сервере только схем объектов расширений.
- Копирование файлов данных, относящихся только к объектам расширений.
- Восстановление на новом сервере схем БЕЗ объектов расширений.
- Копирование файлов данных, НЕ относящихся к объектам расширений.
-
Для всех остальных баз данных (исключая
template1) применяется двухфазное обновление:- Восстановление на новом сервере только схем объектов расширений.
- Копирование файлов данных, относящихся только к объектам расширений.
- Восстановление на новом сервере схем БЕЗ объектов расширений.
- Линковка файлов данных, НЕ относящихся к объектам расширений.
Обработка базы данных 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
Использование вместе параметров --no-two-phases и --two-phases-extensions недопустимо и приведет к остановке работы утилиты pg_upgrade.
Различия в выводе можно увидеть здесь:
| Журнал двухфазного обновления | Журнал однофазного обновления |
|---|---|
| Performing Consistency Checks | Performing Consistency Checks |
| Checking cluster versions ok | Checking cluster versions ok |
| Checking old cluster type Pangolin | Checking old cluster type Pangolin |
| Checking database user is the install user ok | Checking database user is the install user ok |
| Checking database connection settings ok | Checking database connection settings ok |
| Checking for prepared transactions ok | Checking for prepared transactions ok |
| Checking for system-defined composite types in user tables ok | Checking for system-defined composite types in user tables ok |
| Checking for reg* data types in user tables ok | Checking for reg* data types in user tables ok |
| Checking for arrays of predefined domains in user tables ok | Checking for arrays of predefined domains in user tables ok |
| Checking for contrib/isn with bigint-passing mismatch ok | Checking for contrib/isn with bigint-passing mismatch ok |
| Creating dump of global objects ok | Creating dump of global objects ok |
| Creating dump of extensions schemas | Creating dump of database schemas |
| ok | ok |
| Creating dump of database schemas excluding extensions | ok |
| ok | |
| ok | |
| Checking protection status ok | Checking protection status ok |
| Checking for presence of required libraries ok | Checking for presence of required libraries ok |
| Checking for hardlink for PG_VERSION ok | Checking for hardlink for PG_VERSION ok |
| Checking for hardlink for PRODUCT_VERSION ok | Checking for hardlink for PRODUCT_VERSION ok |
| Checking for hardlink for global/enc_keys.json is absent ok | Checking for hardlink for global/enc_keys.json is absent ok |
| Checking for hardlink for global/enc_settings.cfg is absent ok | Checking for hardlink for global/enc_settings.cfg is absent ok |
| Checking database user is the install user ok | Checking database user is the install user ok |
| Checking for prepared transactions ok | Checking for prepared transactions ok |
| Checking for new cluster tablespace directories ok | Checking for new cluster tablespace directories ok |
| If pg_upgrade fails after this point, you must re-initdb the | If pg_upgrade fails after this point, you must re-initdb the |
| new cluster before continuing. | new cluster before continuing. |
| Performing Upgrade | Performing Upgrade |
| Analyzing all rows in the new cluster ok | Analyzing all rows in the new cluster ok |
| Freezing all rows in the new cluster ok | Freezing all rows in the new cluster ok |
| Deleting files from new pg_xact ok | Deleting files from new pg_xact ok |
| Copying old pg_xact to new server ok | Copying old pg_xact to new server ok |
| Setting oldest XID for new cluster ok | Setting oldest XID for new cluster ok |
| Setting next transaction ID for new cluster ok | Setting next transaction ID for new cluster ok |
| Deleting files from new pg_multixact/offsets ok | Deleting files from new pg_multixact/offsets ok |
| Copying old pg_multixact/offsets to new server ok | Copying old pg_multixact/offsets to new server ok |
| Deleting files from new pg_multixact/members ok | Deleting files from new pg_multixact/members ok |
| Copying old pg_multixact/members to new server ok | Copying old pg_multixact/members to new server ok |
| Setting next multixact ID and offset for new cluster ok | Setting next multixact ID and offset for new cluster ok |
| Resetting WAL archives ok | Resetting WAL archives ok |
| Moving TDE settings ok | Moving TDE settings ok |
| Setting frozenxid and minmxid counters in new cluster ok | Setting frozenxid and minmxid counters in new cluster ok |
| Restoring global objects in the new cluster ok | Restoring global objects in the new cluster ok |
| Pre-phase of restoring template1 schema in the new cluster ok | Restoring database template schemas in the new cluster |
| Pre-phase of copying user relation files | ok |
| 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 ok | Merging TDE settings ok |
| Adding ".old" suffix to old global/pg_control ok | Adding ".old" suffix to old global/pg_control ok |
| If you want to start the old cluster, you will need to remove | If 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 safely | Because "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 files | Linking user relation files |
| ok | ok |
| Setting next OID for new cluster ok | Setting next OID for new cluster ok |
| Sync data directory to disk ok | Sync data directory to disk ok |
| Creating script to delete old cluster ok | Creating script to delete old cluster ok |
| Checking for extension updates ok | Checking for extension updates ok |
| Upgrade Complete | Upgrade 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 |