Инструмент inplace_upgrade
Описание решения
Для выполнения задачи обновления каталога используется инструмент inplace_upgrade.sh
, который применяет заранее подготовленные разработчиками SQL-скрипты обновления системного катал ога (правила написания приведены в разделе «Правила написания SQL-скриптов для обновления системных данных каталога»), а также утилиту update_catalog_version
для изменения версии каталога в global/pg_control
. Скрипт обновления и все что он использует, находится в директории installer/utilities/pg_inplace_upgrade
.
Внимание!
Скрипт
inplace_upgrade.sh
, прилагаемые SQL-скрипты обновления и утилитаupdate_catalog_version
являются необходимыми для корректной работы. Изменение/удаление любого из них приведет к неправильной работе утилиты.Для работы утилиты необходимы пакеты компонентов той версии, на которую будет совершаться обновление.
При обновлении каталога меняется содержимое системных таблиц pg_catalog
(таких, как pg_class
, pg_type
и т.д.). Сами системные таблицы и индексы в данном типе обновления не затрагиваются. Объекты базы данных (функции, представления, типы) описаны в системном каталоге и хранятся в виде записей его таблиц. Добавлять или изменять можно только объекты по OID до 16383 включительно. Все объекты OID которых выше 16383 не должны меняться с помощью SQL-скриптов обновления, так как они относятся к пользовательским объектам, изменение которых не предусмотрено.
inplace_upgrade.sh
использует функцию ядра block_user_data_modification
для установки ограничений на следующий ряд SQL-операций на время ее работы:
DROP TYPE
/FUNCTION
/VIEW
;ALTER TYPE
/FUNCTION
/VIEW ... RENAME
;CREATE OR REPLACE FUNCTION
/VIEW
, кромеCREATE FUNCTION
/VIEW
.
Вышеперечисленные ограничения можно при необходимости снять, тем самым разрешив любые изменения системного и пользовательских каталогов, но это увеличит вероятность порчи пользовательских данных и системного каталога в случае наличия ошибок в SQL скриптах. Снятие ограничений производится флагом --drop-on
.
По сравнению с pg_upgrade
инструмент (inplace_upgrade.sh
) работает гораздо быстрее, так как не выполняет полную выгрузку и загрузку данных системного каталога.
Скрипт inplace_upgrade.sh
Обновление начинается с актуализации номера версии системного каталога в global/pg_control
и переименования каталогов с пользовательскими табличными пространствами PG_<MAJOR_POSTGRESQL>_<CATALOG_VERSION_NO>
. Далее скрипт обновляет системный каталог для всех баз данных СУБД в два этапа:
-
На первом этапе скрипт запускается последовательно во всех базах данных с функцией ROLLBACK.
-
Если тестовая загрузка проходит успешно, начинается второй этап загрузки скриптов, также последовательно во всех базах данных, но уже без функции ROLLBACK.
-
Если тестовая загрузка завершается с ошибкой, второй этап не запускается, и скрипт выполняет откат версии каталога и возвращает названия каталогов с табличными пространствами.
- Если второй этап загрузки завершается с ошибкой, скрипт также выполняет откат версии каталога и возвращает названия каталогов с табличными пространствами.
-
При вызове скрипта inplace_upgrade.sh
испол ьзуются ключи:
-
Обязательные ключи:
-
-s | --utildir
- директория со скриптомinplace_upgrade.sh
, утилитойupdate_catalog_version
и папкойsql_upgrade_6xx
, содержащей SQL-скрипты для обновленияpg_catalog
. SQL-скрипты пишутся разработчиками в соответствии изменениями вpg_catalog
, которые вносят их доработки. В случае стандартной установки данный параметр имеет значениеinstaller/utilities/pg_inplace_upgrade
; -
-d | --pgdatadir
- путь к директории с данными (обычно имеет такое же значение, как и$PGDATA
); -
-l | --logdir
- директория для сохранения логов:- логи PostgreSQL, сгенерированные в процессе обновления, записываются в файл
postgres_update.log
; - полный лог работы скрипта обновления
inplace_upgrade.sh
записываются в файлinplace_upgrade.log
; - короткий отчет обновления
report.log
;
- логи PostgreSQL, сгенерированные в процессе обновления, записываются в файл
-
-h | --host
- хост СУБД для подключенияpg_dump
иpsql
; -
-p | --port
- порт СУБД для подключенияpg_dump
,pg_ctl
иpsql
; -
-u | --user
- пользователь СУБД с правами суперпользователя для подключенияpg_dump
иpsql
; -
-n | --old-version
- текущая версия продукта (например 6.1.8 для СУБД Pangolin 6.1.8). Формат строки проверяется; -
-N | --new-version
- версия продукта на которую происходит обновление (например 6.4.0 для СУБД Pangolin 6.4.0). Формат строки проверяется; -
-b | --dbname
- имя базы данных для подключенияpg_dump
иpsql
(обычно имеет значениеpostgres
); -
-m | --dumpdir
- директория для сохранения дампов (sql-дампы до, после и после отката обновления); -
-B | --backupdir
- директория для сохранения:- резервной копии файлов системного каталога;
- файлов с перечнем таблиц и индексов системного каталога и информацией о соответствующих им файлах;
- файл
user_tbls.txt
с директориями пользовательских табличных пространств; - файл
version.txt
с версией PostgreSQL до обновления;
-
-t | --pg_ctldir
- директория с исполняемыми файлами утилитpg_ctl
иpostgres
новой версии; -
-T | --pg_utildir
- директория с исполняемыми файлами утилитpsql
иpg_dump
новой версии.
-
Необязательные ключи:
-P | --password
- пароль для подключения к СУБД. Если не задан, то пароль берется из переменной окруженияPASSWORD
;-r | --replica
- ключ указывается при запуске утилиты обновления на реплике;-D | --drop_on
- флаг, разрешающий операции, запрещенные функциейblock_user_data_modification
;-k | --test-skip
- флаг, устанавливается для отключения запуска тестов системного каталога;-a | --add-tables
- флаг для выполнения резервного копирования таблицpg_largeobject
,pg_largeobject_metadata
при необходимости;-V | --version
- версия утилиты;-? | --help
- справка.
Команды:
info
- команда проверки актуальности обновления и формирования информационных файловuser_tbls.txt
,version.txt
для последующего запуска обновления;update
- команда запуска обновления;reset
- команда отката обновления. Откат возможен до первого запуска базы с доступом пользователей.
Требования для запуска
Пользователь должен иметь права н а запуск скрипта обновления inplace_upgrade.sh
. Также этот пользователь должен иметь права суперпользователя на доступ к СУБД.
Внимание!
Проверьте, что установленная локаль на узлах соответствует:
LANG: en_US.UTF-8
,LC_ALL: en_US.UTF-8
.
Режимы работы скрипта
Существуют три режима работы скрипта inplace_upgrade.sh
:
info
- проверка возможности обновления;update
- обновление;reset
- откат обновления;
inplace_upgrade.sh в режиме info
В режиме info
скрипт осуществляет проверку возможности обновления (наличие утилиты update_catalog_version
, папок с SQL-скриптами и всех необходимых прав доступа к ним) и необходимость обновления для новой версии СУБД. Также скрипт создает два файла user_tbls.txt
и version.txt
. Файл user_tbls.txt
содержит список директорий пользовательских табличных пространств для последующего их обновления скриптом в режиме update
. Файл version.txt
используется для сохранения значения мажорной версии PostgreSQL (MAJOR_POSTGRESQL
), которая является элементом пути в пользовательском табличном пространстве PG_<MAJOR_POSTGRESQL>_<CATALOG_VERSION_NO>
.
Для кластерной конфигурации необходимо запускать скрипт в режиме info
и на мастере и на реплике.
Запуск скрипта осуществляется при включенной СУБД.
Пример запуска скрипта:
./inplace_upgrade.sh -d <pgdata> -l <директория логов> -s <директория с утилитой> -B <директория резервной копии> -p <порт> -h <хост> -u <суперпользователь> -b <база данных для подключения по умолчанию> -n <текущая версия продукта> -N <новая версия продукта> info --t <директория утилит postgres and pg_ctl> -T <директория утилит psql and pg_dump>
Ограничения
Необходим доступ к папке sql_upgrade_6xx
, ее внутренним папкам и доступ на чтение ко всем файлам внутри папок для администратора СУБД, запускающего утилиту. СУБД должна быть запущена со старыми бинарными файлами.
Коды возврата
Предусмотренные коды:
0
- вызов утилиты требуется;1
- провал запуска утилиты, утилита не может быть запущена корректно;2
- вызов утилиты в режимеupdate
не требуется.
inplace_upgrade.sh в режиме update
В режиме update
скрипт осуществляет обновление таблиц схемы pg_catalog
, номера версии системного каталога в pg_control
и табличных пространств пользователей.
Пример запуска скрипта:
./inplace_upgrade.sh -d <pgdata> -l <директория логов> -p <порт> -h <хост> -u <суперпользователь> -b <база данных для подключения по умолчанию> -s <директория с утилитой> -m <директория для sql-дампов> -B <директория бэкапа> -n <текущая версия продукта> -N <новая версия продукта> update -t <директория утилит postgres and pg_ctl> -T <директория утилит psql and pg_dump>
Примечание:
Процесс восстановления СУБД после неудачного окончания работы скрипта в режиме
update
описан в разделе «Восстановление после неудачного обновления исполняемых файлов».
Ограничения
Перед запуском обновления СУБД должна быть остановлена. Доступ для обычных пользователей должен быть ограничен, чтобы не было проблем при снятии дампов системных каталогов (не менялись системные таблицы pg_class
, pg_type
, pg_proc
и другие) и последующем их анализе, если потребуется при ручном восстановлении СУБД. Бинарные файлы СУБД должны быть новой версии и должны содержать необходимые системные объекты (если требуется). В противном случае может возникн уть проблема как в примере ниже.
Пример отсутствия функции в ядре (при ее добавлении может быть ошибка в транзакции):
"ERROR: Fail script: ERROR: there is no built-in function named \"<name_function>\"", "CONTEXT: SQL statement \"CREATE FUNCTION pg_catalog.name_function()"
Коды возврата
Предусмотренные коды:
0
- успех;1
- провал запуска утилиты, требуется ручное восстановление СУБД;4
- требует ся восстановление файлов из резервной копии системного каталога, также необходим откат исполняемых файлов СУБД к исходной версии;5
- изменения не применились, необходим откат исполняемых файлов СУБД к исходной версии.
inplace_upgrade.sh в режиме reset
В режиме reset
скрипт осуществляет восстановление pg_catalog
и номера каталога СУБД.
Пример запуска скрипта:
./inplace_upgrade.sh -d <pgdata> -l <директория логов> -p <порт> -h <хост> -u <суперпользователь> -b <база данных для подключения по умолчанию> -s <директория с утилитой> -m <директория для sql-дампов> -B <директория бэкапа> reset -t <директория утилит postgres and pg_ctl> -T <директория утилит psql and pg_dump>
Примечание:
Процесс восстановления СУБД после неудачного окончания работы скрипта в режиме
reset
описан в разделе «Ручное восстановление системного каталога СУБД».
Ограничения
Должен быть доступ к папке, указанной в --backupdir
и доступ на чтение к файлам, внутри этой папки.
Перед запуском восстановления СУБД должна быть остановлена. Доступ для обычных пользователей должен быть ограничен.
Коды возврата
0
- успех;1
- провал запуска утилиты, требуется ручное восстановление СУБД.
Утилита update_catalog_version
Пользователь должен иметь права на исполнение утилиты update_catalog_version
, запускающим обновление.
Утилита update_catalog_version
производит сравнение версии текущего каталога, считанной из global/pg_control
(расположение файла по умолчанию $PGDATA/global/pg_control
), с версией на которую планируется обновление. Также проверяется наличие файла резервной копии pg_control.bak
в директории указанной в --backup
, если файл есть (возможно происходит повторный запуск), то утилита заканчивает свою работу, пишет сообщение с описанием ошибки и возвращает код ошибки 1
. В случае совпадения проверяется отличие номера текущей версии от версии на которую необходимо производить обновление, если они совпали, то обновление версии не происходит и утилита заканчивает свою работу, возвращается код 2
. Если новая версия больше текущей версии, то делается резервная копия pg_control.bak
(файл будет располагаться в --backup
) и происходит обновление версии каталога в файле pg_control
. В случае успешного обновления утилита заканчивает свою работу и возвращает код 0
. Если произошла ошибка при обновлении версии, то происходит восстановление pg_control
и завершение работы утилиты с кодом 1
. Если восстановить старый pg_control
из резервной копии не удалось, то утилита возвращает код 3
. Если новая версия меньше текущей версии каталога, то обновление не производится, пишется сообщение об ошибке и возвращается код 1
. Если необходимо понизить версию, то нужно использовать ключ --force
(-f
), с этим ключом не производится проверка повышения версии каталога, также не производится проверка наличия файла резервной копии и он перезаписывается. Если не сделать обновление версии каталога, то бинарные файлы СУБД не смогут запуститься.
Ключи утилиты update_catalog_version
:
-D
,--pgdatadir
- директория с СУБД (PGDATA
);-b
,--backupdir
- директория для сохранения резервной копии файлаpg_control
;-C
,--catalog-version-new
- новая версия системного каталога (на которую происходит обновление) (CATALOG_VERSION_NO
);-c
,--catalog-version-old
- старая версия системного каталога (с которой происходит обновление) (CATALOG_VERSION_NO
);-f
,--force
- флаг принудительной смены версии;-y
,--dry-run
- флаг проверки соответствия версии текущего каталога обновлению, без его изменения;-V
,--version
- флаг печати версии утилиты;-?
,--help
- флаг печати справки об утилите.
Режимы работы утилиты update_catalog_version
Работа утилиты без --force
Утилита запускается с ключами: update_catalog_version -с catalog_version_no_old -C catalog_version_no_new -b <dir_backup> -D <PGDATA>
.
Ход работы:
- Проверяется что заданы все основные параметры (
-D
,-c
,-C
,-b
), если хотя бы один не задан, то пишется сообщение вstdout
и возвращается код ошибки1
. - Проверяется что PostgreSQL не запущен. Если запущен, то выдается сообщение об ошибке и возвращается код возврата
1
. - Проверяется что версия каталога не понижается, если версия понижается, то выдается сообщение об ошибке и возвращается код возврата
1
. - Проверяется наличие файла резервной копии
pg_control.bak
, если он есть, то выдается сообщение об ошибке и возвращается код возврата1
. Это нужно для исключения повторного ошибочного обновления. - Проверяется соответствие версии текущего каталога, версии переданной с ключом
-c
, если версии разные, то выдается сообщение об ошибке и возвращается код возврата1
. - Проверяется соответствие версии текущего каталога, версии переданной с ключом
-С
, если версии одинаковые, то выдается сообщение соответствия версий и возвращается код2
. - Форм ируется файл резервной копии
pg_control.bak
. Если файл не сформировался, то выдается сообщение об ошибке и возвращается код возврата1
. - Обновляется версия системного каталога в файле
pg_control
. Если произошла ошибка, то происходит восстановление файлаpg_control
из резервной копии, выдается сообщение об ошибке и возвращается код1
. Если восстановление файлаpg_control
не получилось, то выдается сообщение об ошибке и выдается код3
.
Работа утилиты с --force
Утилита запускается с ключами: update_catalog_version -с catalog_version_no_old -C catalog_version_no_new -b <dir_backup> -D <PGDATA> -f
.
Ход работы:
- Проверяется что заданы все основные параметры (
-D
,-c
,-C
,-b
), если хотя бы один не задан, то пишется сообщение вstdout
и возвращается код ошибки1
. - Проверяется что PostgreSQL не запущен. Если запущен, то выдается сообщение об ошибке и возвращается код возврата
1
. - Прове ряется соответствие версии текущего каталога, версии переданной с ключом
-c
, если версии разные, то выдается сообщение об ошибке и возвращается код возврата1
. - Проверяется соответствие версии текущего каталога, версии переданной с ключом
-С
, если версии одинаковые, то выдается сообщение соответствия версий и возвращается код2
. - Формируется файл резервной копии
pg_control.bak
. Если файл не сформировался, то выдается сообщение об ошибке и возвращается код возврата1
. - Обновляется версия системного каталога в файле
pg_control
. Если произошла ошибка, то происходит восстановление файлаpg_control
из резервной копии, выдается сообщение об ошибке и возвращается код1
. Если восстановление файлаpg_control
не получилось, то выдается сообщение об ошибке и выдается код3
.
Работа утилиты с --dry-run
Утилита запускается с ключами: update_catalog_version -с catalog_version_no_old -C catalog_version_no_new -b <dir_backup> -D <PGDATA> -y
.
Ход работы:
- Проверяется что заданы все основные параметры (
-D
,-c
,-C
,-b
), если хотя бы один не задан, то пишется сообщение вstdout
и возвращается код ошибки1
. - Проверяется что версия каталога не понижается. Если версия понижается, то выдается сообщение об ошибке и возвращается код возврата
1
. - Проверяется наличие файла резервной копии
pg_control.bak
. Если он есть, то выдается сообщение об ошибке и возвращается код возврата1
. Это нужно для исключения повторного ошибочного обновления. - Проверяется соответствие версии текущего каталога, версии переданной с ключом
-c
. Если версии разные, то выдается сообщение об ошибке и возвращается код возврата1
. - Проверяется соответствие версии текущего каталога версии переданной с ключом
-С
. Если версии одинаковые, то выдается сообщение соответствия версий и возвращается код2
, если версии разные, то выдается сообщение о возможности обновления и возвращается код0
.
Ограничения
Перед запуском update_catalog_version
, для изменения версии каталога, СУБД должна быть остановлена. Доступ для обычных пользователей должен быть ограничен.
Коды возврата утилиты update_catalog_version
Предусмотренные коды:
0
- успешное завершения обновления версии каталога (в режиме проверки--dry-run
данный код означает, что обновление возможно);1
- ошибка обновления версии каталога, файлpg_control
не поменялся;2
- обновление каталога не требуется (в режиме проверки--dry-run
данный код означает, что обновление не требуется);3
- ошибка обновления версии каталога, файлpg_control
поменялся, требуется ручное восстановление из файла резервной копииpg_control.bak
.
Правила написания SQL-скриптов для обновления системных данных каталога
Разработчикам необходимо придерживаться правил написания SQL-скриптов обновления:
- SQL-скрипты должны иметь права на чтение пользователем, запускающим обновление.
- На данный момент возможно добавление в системный каталог объектов: functions, view, type. Добавление других объектов возможно, но на текущий момент это не проверялось.
- Системные объекты (например, функции), с
OID<10000
добавляются по заданному системному OID. Если задаваемый OID уже занят другим системным объектом, то возникнет конфликт, и транзакция откатится с указанием конфликта OID. - Для некоторых системных объектов добавление по заданному OID невозможно, так как они инициализируются в СУБД при вызове
initdb
, а при о бновлении данной утилиты должны добавляться по свободным системных OID в диапазоне12000<=OID<16384
, чтобы не вызвать конфликтов с существующими системными объектами СУБД.
Написание скриптов должно проводиться строго в соответствии с описанными далее шаблонам, отклонение от шаблонов может привести к порче объектов системного каталога.
При создании новых объектов системного каталога необходимо точно знать какие таблицы системного каталога задействуются при создании этого объекта и учесть это в скрипте обновления.
Скрипты должны предоставлять диагностическую информацию об изменяемых данных на случай возникновения проблем обновления и необходимости их ручного восстановления.
Примечание:
При создании новой функции обновляется таблица
pg_proc
системного каталога.
Шаблоны
SQL-скрипты для обновления пишутся разработчиками по шаблонам, описанным в данном разделе.