Дополнительные инструкции по обновлению, связанные с переходом на ядро PostgreSQL 15.5#
Внимание!
Инструкция актуальна только при обновлении СУБД Pangolin с версий ранее 6.1.0 на версии 6.1.0 и выше.
Особенности миграции#
При переходе на новую версию ядра для миграции данных необходимо использовать pg_dumpall или pg_upgrade. В документации PostgreSQL можно ознакомиться с общими рекомендациями при переходе на обновленную версию ядра для каждого из способов.
Перед обновлением на версию Pangolin 6.x.x:
Удалите расширение
pg_pathman, так как оно больше не поддерживается сообществом. В скриптах обновления расширения участвуют устаревшие объекты. В 6.x.x версии СУБД Pangolin появились встроенные функции по работе с партициями. Подробнее в Документе «Руководство по установке», раздел «Расширение pg_pathman и переход на декларативное секционирование данных».Временно (на период обновления) удалите расширение
pg_repack, так как оно содержит не поддерживаемые полиморфные объекты. По окончании обновления расширение может быть возвращено для дальнейшего использования.
Примечание:
Расширение
pg_stat_kсache, если оно было установлено, при обновлении ядра будет пересоздано. Это может привести к сбросу статистики.
Изменения ролевой модели#
Внимание!
В ядре PostgreSQL версии 15.5 проведены изменения встроенной ролевой модели, касающиеся ролей:
pg_execute_server_program;
pg_monitor;
pg_read_all_settings;
pg_read_all_stats;
pg_read_server_files;
pg_signal_backend;
pg_stat_scan_tables;
pg_write_server_files.
В связи с этим изменились правила наследования встроенных ролей, указанных выше.
Далее рассмотрен пример с ролевой моделью, в рамках которой родительская роль as_admin_read не наследует явно роль pg_read_all_settings. Созданы две дочерние роли - с наследованием и без.
Логика работы ролевой модели до версии 6.1.0:
\du *as_admin_read*
List of roles
┌──────────────────────────────┬───────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────┐
│ Role name │ Attributes │ Member of │
├──────────────────────────────┼───────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────┤
│ as_admin_read │ No inheritance, Cannot login ↵│ {pg_monitor,pg_read_all_settings,pg_read_all_stats,pg_stat_scan_tables,pg_signal_backend} │
│ │ 5 connections ↵│ │
│ │ Password valid until infinity │ │
│ user_as_admin_read_inherit │ Cannot login │ {as_admin_read} │
│ user_as_admin_read_noinherit │ No inheritance, Cannot login │ {as_admin_read} │
└──────────────────────────────┴───────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────┘
-- Для просмотра поля pg_settings.sourceline нужны права pg_read_all_settings
-- Переключение на роль без наследования:
set session authorization user_as_admin_read_noinherit;
select name,sourceline from pg_settings where name='work_mem'\gx
┌─[ RECORD 1 ]────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ name │ work_mem │
│ sourceline │ 129 │
└─────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- Права pg_read_all_settings (без явного наследования ни родительской ролью, хотя есть у дочерней) применились
-- Переключение на роль с наследованием:
set session authorization user_as_admin_read_inherit;
select name,sourceline from pg_settings where name='work_mem'\gx
┌─[ RECORD 1 ]────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ name │ work_mem │
│ sourceline │ 129 │
└─────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- Права pg_read_all_settings (без явного наследования ни родительской ролью, хотя есть у дочерней) применились
Аналогичный пример с логикой работы ролевой модели, начиная с версии 6.1.0:
\du *as_admin_read*
List of roles
┌──────────────────────────────┬───────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Role name │ Attributes │ Member of │
├──────────────────────────────┼───────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ as_admin_read │ No inheritance, Cannot login ↵│ {pg_monitor,pg_read_all_settings,pg_read_all_stats,pg_stat_scan_tables,pg_read_all_perfinsight,pg_signal_backend} │
│ │ 5 connections ↵│ │
│ │ Password valid until infinity │ │
│ user_as_admin_read_inherit │ Cannot login │ {as_admin_read} │
│ user_as_admin_read_noinherit │ No inheritance, Cannot login │ {as_admin_read} │
└──────────────────────────────┴───────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- Для просмотра поля pg_settings.sourceline нужны права pg_read_all_settings
-- Переключение на роль без наследования:
set session authorization user_as_admin_read_noinherit;
select name,sourceline from pg_settings where name='work_mem'\gx
┌─[ RECORD 1 ]────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ name │ work_mem │
│ sourceline │ NUL │
└─────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- Права pg_read_all_settings (без явного наследования ни родительской ролью, хотя есть у дочерней) не применились
-- Переключение на роль с наследованием:
set session authorization user_as_admin_read_inherit;
select name,sourceline from pg_settings where name='work_mem'\gx
┌─[ RECORD 1 ]────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ name │ work_mem │
│ sourceline │ NUL │
└─────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- Права pg_read_all_settings (без явного наследования ни родительской ролью, хотя есть у дочерней) не применились
-- Установка явного наследования родительской ролью:
alter role as_admin_read inherit;
-- Переключение в роль без наследования:
set session authorization user_as_admin_read_noinherit;
select name,sourceline from pg_settings where name='work_mem'\gx
┌─[ RECORD 1 ]────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ name │ work_mem │
│ sourceline │ NUL │
└─────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- Права pg_read_all_settings (без явного наследования дочерней ролью) не применились
-- Переключение в роль с наследованием:
set session authorization user_as_admin_read_inherit;
select name,sourceline from pg_settings where name='work_mem'\gx
┌─[ RECORD 1 ]────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ name │ work_mem │
│ sourceline │ 166 │
└─────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-- Права pg_read_all_settings (только в случае, если все роли имеют явное наследование) применились
Внимание!
Так как ролевая модель определяется и создается на этапе развертывания, необходимо на начальных этапах учесть соответствующие изменения PostgreSQL 15.
Рекомендуется пересмотреть правила наследования полномочий ролей с явным переходом на систему ролей, обладающих соответствующими полномочиями.
Сохранение совместимости с ранними версиями#
Для сохранения совместимости с предыдущими выпусками продукта:
Отзовите у пользователей права
CREATEв схемеpublicдля существующих и новых (требующих защиты от внутренних пользователей) БД (в т.ч. для многопользовательских баз).Для новых баз, не требующих защиты от внутренних пользователей, при предоставлении пользователям права
CREATEбудет получено поведение, принятое в предыдущих версиях.Исключен режим эксклюзивного снятия резервной копии, а также файл
backup_label, функцииpg_backup_start_time()иpg_is_in_backup().Переименуйте вызовы функций при их использовании:
pg_start_backup()→pg_backup_start();pg_stop_backup()→pg_backup_stop().
Примечание:
При автоматической миграции скриптами Pangolin переименование вручную делать не нужно.
Исключите использование удаленных функций
pg_backup_start_time()иpg_is_in_backup().Не используйте процедуры и функции, основанные на Python версий 2.x, т.к. он больше не поддерживается.
Не передавайте пустые строки во входной массив функции
array_to_tsvector(), убедитесь в отсутствии пустых лексем в уже используемых вызовах данной функции.Убедитесь, что функция
chr()нигде не вызывается с отрицательным аргументом - это вызовет ошибку.Не изменяйте правила сортировки выходного столбца в
CREATE OR REPLACE VIEW.Убедитесь, что отсутствуют идентификаторы нулевой длины (в т.ч. в
Unicode).Убедитесь в отсутствии использования числовых констант, оканчивающихся нецифровыми символами: с версии 6.1.0 комбинации вида
123abcв запросе не воспринимаются как отдельные компоненты - числовой123и буквенныйabc.Исключите использование нечислового содержимого при передаче числовых форматов в JSON (например,
1.type()не допустим).Актуализируйте даты с учетом новой логики округления: значение, превышающие месяц, теперь округляются до ближайшего месяца. Например, значение
1.99 yearsбудет преобразовано в2 years(2 года), а не1 year 11 months(1 год 11 месяцев), как раньше.Убедитесь в отсутствии индексов, заданных в текстовом виде и зависящих от значений
interval, т.к. их наличие вызовет ошибку.В случаях логической репликации убедитесь, что пользователь, использующий команды
UPDATE/DELETE, имеет право наSELECTдля таблицы.Удалите устаревшую серверную переменную
stats_temp_directory.В приложениях, использующих
PQsendQuery()в конвейерном режиме, перейдите к использованиюPQsendQueryParams().Удалите использование параметра
--no-synchronized-snapshotsпри вызовеpg_dump, так как теперь синхронные снимки выдаются по умолчанию.Функция
xml_is_well_formed()удалена - убедитесь в отсутствии ее вызовов.Не используйте типы массивов, основанные на базовых типах
information_schema, например,information_schema.yes_or_no(и их производные).Переиндексируйте следующие типы индексов:
GiST;
B-Tree (только для полей с типом
interval);BRIN-индексы, использующие типы данных
date,timestamptz,timestamptz, а также классminmax_multi.
Убедитесь в отсутствии устаревших типов данных
abstime,reltime,tintervalи не используйте их.Не используйте устаревшие типы данных, (включая операторы, классы операторов, семейства операторов, агрегаты, индексы и пр.):
information_schema.sql_languages;information_schema.sql_packages;information_schema.sql_sizing_profiles;pg_catalog.abstime;pg_catalog._abstime;pg_catalog.opaque;pg_catalog.pg_pltemplate;pg_catalog.reltime;pg_catalog._reltime;pg_catalog.smgr;pg_catalog.tinterval;pg_catalog._tinterval.
Не используйте нештатные средства удаления пользователей и ролей СУБД путем модификации таблицы
pg_authid.Не используйте агрегатные функции для полиморфных типов
anyarray,anyelement, например:array_append(anyarray,anyelement);array_cat(anyarray,anyarray);array_prepend(anyelement,anyarray);array_remove(anyarray,anyelement);array_replace(anyarray,anyelement,anyelement);array_position(anyarray,anyelement);array_position(anyarray,anyelement,integer);array_positions(anyarray,anyelement);width_bucket(anyelement,anyarray).
В случае изменения прав на процедуры и функции системного каталога отмените изменения перед началом миграции.
Для 15 версии СУБД изменились сигнатуры (схема, имена, порядок, значения входных переменных по умолчанию) следующих процедур/функций:
pg_catalog.abstime(timestamp without time zone);pg_catalog.abstime(timestamp with time zone);pg_catalog.abstimeeq(abstime, abstime);pg_catalog.abstimege(abstime, abstime);pg_catalog.abstimegt(abstime, abstime);pg_catalog.abstimein(cstring);pg_catalog.abstimele(abstime, abstime);pg_catalog.abstimelt(abstime, abstime);pg_catalog.abstimene(abstime, abstime);pg_catalog.abstimeout(abstime);pg_catalog.abstimerecv(internal);pg_catalog.abstimesend(abstime);pg_catalog.array_append(anyarray, anyelement);pg_catalog.array_cat(anyarray, anyarray);pg_catalog.array_position(anyarray, anyelement);pg_catalog.array_position(anyarray, anyelement, integer);pg_catalog.array_positions(anyarray, anyelement);pg_catalog.array_prepend(anyelement, anyarray);pg_catalog.array_remove(anyarray, anyelement);pg_catalog.array_replace(anyarray, anyelement, anyelement);pg_catalog.ascii_to_mic(integer, integer, cstring, internal, integer);pg_catalog.ascii_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.big5_to_euc_tw(integer, integer, cstring, internal, integer);pg_catalog.big5_to_mic(integer, integer, cstring, internal, integer);pg_catalog.big5_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.binary_upgrade_set_next_toast_pg_type_oid(oid);pg_catalog.btabstimecmp(abstime, abstime);pg_catalog.btreltimecmp(reltime, reltime);pg_catalog.bttintervalcmp(tinterval, tinterval);pg_catalog.close_lb(line, box);pg_catalog.close_sl(lseg, line);pg_catalog.currtid(oid, tid);pg_catalog.date(abstime);pg_catalog.date_part(text, abstime);pg_catalog.date_part(text, reltime);pg_catalog.dist_bl(box, line);pg_catalog.dist_lb(line, box);pg_catalog.euc_cn_to_mic(integer, integer, cstring, internal, integer);pg_catalog.euc_cn_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.euc_jis_2004_to_shift_jis_2004(integer, integer, cstring, internal, integer);pg_catalog.euc_jis_2004_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.euc_jp_to_mic(integer, integer, cstring, internal, integer);pg_catalog.euc_jp_to_sjis(integer, integer, cstring, internal, integer);pg_catalog.euc_jp_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.euc_kr_to_mic(integer, integer, cstring, internal, integer);pg_catalog.euc_kr_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.euc_tw_to_big5(integer, integer, cstring, internal, integer);pg_catalog.euc_tw_to_mic(integer, integer, cstring, internal, integer);pg_catalog.euc_tw_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.gb18030_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.gbk_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.get_bit(bytea, integer);pg_catalog.interval(reltime);pg_catalog.interval_transform(internal);pg_catalog.intinterval(abstime, tinterval);pg_catalog.isfinite(abstime);pg_catalog.iso8859_1_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.iso8859_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.iso_to_koi8r(integer, integer, cstring, internal, integer);pg_catalog.iso_to_mic(integer, integer, cstring, internal, integer);pg_catalog.iso_to_win1251(integer, integer, cstring, internal, integer);pg_catalog.iso_to_win866(integer, integer, cstring, internal, integer);pg_catalog.johab_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.koi8r_to_iso(integer, integer, cstring, internal, integer);pg_catalog.koi8r_to_mic(integer, integer, cstring, internal, integer);pg_catalog.koi8r_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.koi8r_to_win1251(integer, integer, cstring, internal, integer);pg_catalog.koi8r_to_win866(integer, integer, cstring, internal, integer);pg_catalog.koi8u_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.lag(anyelement, integer, anyelement);pg_catalog.latin1_to_mic(integer, integer, cstring, internal, integer);pg_catalog.latin2_to_mic(integer, integer, cstring, internal, integer);pg_catalog.latin2_to_win1250(integer, integer, cstring, internal, integer);pg_catalog.latin3_to_mic(integer, integer, cstring, internal, integer);pg_catalog.latin4_to_mic(integer, integer, cstring, internal, integer);pg_catalog.lead(anyelement, integer, anyelement);pg_catalog.max(abstime);pg_catalog.mic_to_ascii(integer, integer, cstring, internal, integer);pg_catalog.mic_to_big5(integer, integer, cstring, internal, integer);pg_catalog.mic_to_euc_cn(integer, integer, cstring, internal, integer);pg_catalog.mic_to_euc_jp(integer, integer, cstring, internal, integer);pg_catalog.mic_to_euc_kr(integer, integer, cstring, internal, integer);pg_catalog.mic_to_euc_tw(integer, integer, cstring, internal, integer);pg_catalog.mic_to_iso(integer, integer, cstring, internal, integer);pg_catalog.mic_to_koi8r(integer, integer, cstring, internal, integer);pg_catalog.mic_to_latin1(integer, integer, cstring, internal, integer);pg_catalog.mic_to_latin2(integer, integer, cstring, internal, integer);pg_catalog.mic_to_latin3(integer, integer, cstring, internal, integer);pg_catalog.mic_to_latin4(integer, integer, cstring, internal, integer);pg_catalog.mic_to_sjis(integer, integer, cstring, internal, integer);pg_catalog.mic_to_win1250(integer, integer, cstring, internal, integer);pg_catalog.mic_to_win1251(integer, integer, cstring, internal, integer);pg_catalog.mic_to_win866(integer, integer, cstring, internal, integer);pg_catalog.min(abstime);pg_catalog.mktinterval(abstime, abstime);pg_catalog.numeric_fac(bigint);pg_catalog.numeric_transform(internal);pg_catalog.opaque_in(cstring);pg_catalog.opaque_out(opaque);pg_catalog.path_center(path);pg_catalog.pg_backup_start_time();pg_catalog.pg_create_logical_replication_slot(slot_name name, plugin name, temporary boolean DEFAULT false);pg_catalog.pg_is_in_backup();pg_catalog._pg_keysequal(smallint[], smallint[]);pg_catalog.pg_terminate_backend(integer);pg_catalog.pm_grant_to_policy(policy_name name, db_name name, object_kind name, object_name name, actions anyarray);pg_catalog.pm_protect_object(db_name name, object_kind name, object_name name);pg_catalog.pm_revoke_from_policy(policy_name name, db_name name, object_kind name, object_name name, actions anyarray);pg_catalog.pm_unprotect_object(db_name name, object_kind name, object_name name);pg_catalog.point(path);pg_catalog.reltime(interval);pg_catalog.reltimeeq(reltime, reltime);pg_catalog.reltimege(reltime, reltime);pg_catalog.reltimegt(reltime, reltime);pg_catalog.reltimein(cstring);pg_catalog.reltimele(reltime, reltime);pg_catalog.reltimelt(reltime, reltime);pg_catalog.reltimene(reltime, reltime);pg_catalog.reltimeout(reltime);pg_catalog.reltimerecv(internal);pg_catalog.reltimesend(reltime);pg_catalog.set_bit(bytea, integer, integer);pg_catalog.shell_in(cstring);pg_catalog.shell_out(opaque);pg_catalog.shift_jis_2004_to_euc_jis_2004(integer, integer, cstring, internal, integer);pg_catalog.shift_jis_2004_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.sjis_to_euc_jp(integer, integer, cstring, internal, integer);pg_catalog.sjis_to_mic(integer, integer, cstring, internal, integer);pg_catalog.sjis_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.smgreq(smgr, smgr);pg_catalog.smgrin(cstring);pg_catalog.smgrne(smgr, smgr);pg_catalog.smgrout(smgr);pg_catalog.time(abstime);pg_catalog.timemi(abstime, reltime);pg_catalog.timenow();pg_catalog.timepl(abstime, reltime);pg_catalog.timestamp(abstime);pg_catalog.timestamp_izone_transform(internal);pg_catalog.timestamp_transform(internal);pg_catalog.timestamptz(abstime);pg_catalog.timestamp_zone_transform(internal);pg_catalog.time_transform(internal);pg_catalog.tinterval(abstime, abstime);pg_catalog.tintervalct(tinterval, tinterval);pg_catalog.tintervalend(tinterval);pg_catalog.tintervaleq(tinterval, tinterval);pg_catalog.tintervalge(tinterval, tinterval);pg_catalog.tintervalgt(tinterval, tinterval);pg_catalog.tintervalin(cstring);pg_catalog.tintervalle(tinterval, tinterval);pg_catalog.tintervalleneq(tinterval, reltime);pg_catalog.tintervallenge(tinterval, reltime);pg_catalog.tintervallengt(tinterval, reltime);pg_catalog.tintervallenle(tinterval, reltime);pg_catalog.tintervallenlt(tinterval, reltime);pg_catalog.tintervallenne(tinterval, reltime);pg_catalog.tintervallt(tinterval, tinterval);pg_catalog.tintervalne(tinterval, tinterval);pg_catalog.tintervalout(tinterval);pg_catalog.tintervalov(tinterval, tinterval);pg_catalog.tintervalrecv(internal);pg_catalog.tintervalrel(tinterval);pg_catalog.tintervalsame(tinterval, tinterval);pg_catalog.tintervalsend(tinterval);pg_catalog.tintervalstart(tinterval);pg_catalog.uhc_to_utf8(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_ascii(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_big5(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_euc_cn(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_euc_jis_2004(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_euc_jp(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_euc_kr(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_euc_tw(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_gb18030(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_gbk(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_iso8859(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_iso8859_1(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_johab(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_koi8r(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_koi8u(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_shift_jis_2004(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_sjis(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_uhc(integer, integer, cstring, internal, integer);pg_catalog.utf8_to_win(integer, integer, cstring, internal, integer);pg_catalog.varbit_transform(internal);pg_catalog.varchar_transform(internal);pg_catalog.width_bucket(anyelement, anyarray);pg_catalog.win1250_to_latin2(integer, integer, cstring, internal, integer);pg_catalog.win1250_to_mic(integer, integer, cstring, internal, integer);pg_catalog.win1251_to_iso(integer, integer, cstring, internal, integer);pg_catalog.win1251_to_koi8r(integer, integer, cstring, internal, integer);pg_catalog.win1251_to_mic(integer, integer, cstring, internal, integer);pg_catalog.win1251_to_win866(integer, integer, cstring, internal, integer);pg_catalog.win866_to_iso(integer, integer, cstring, internal, integer);pg_catalog.win866_to_koi8r(integer, integer, cstring, internal, integer);pg_catalog.win866_to_mic(integer, integer, cstring, internal, integer);pg_catalog.win866_to_win1251(integer, integer, cstring, internal, integer);pg_catalog.win_to_utf8(integer, integer, cstring, internal, integer).