E.20. Release 16.5 #
Дата выпуска: 2024-11-14
В этот выпуск вошли различные исправления, внесённые после версии 16.4. За информацией о нововведениях версии 16 обратитесь к Разделу E.25.
E.20.1. Миграция на версию 16.5 #
Если используется версия 16.X, выгрузка/восстановление базы не требуется.
Тем не менее, если вы когда-либо выполняли отсоединение секции от секционированной таблицы, которая ссылалась на другую секционированную таблицу при помощи внешнего ключа, и старая секция не была удалена, возможно, вам придётся исправлять повреждение каталогов и/или данных, как подробно описано ниже в пятом пункте списка изменений.
Также, если вы обновляете сервер с более ранней версии, чем 16.3, см. Раздел E.22.
E.20.2. Изменения #
Пометка кешированных планов как зависимых от выполняющих их ролей, когда защита на уровне строк (RLS) применяется для ссылки на таблицу не на верхнем уровне (Натан Боссарт) §
Если общее табличное выражение (CTE), подзапрос, подссылка, представление с контекстом безопасности вызывающего или проекция приведения в запросе ссылались на таблицу с политикой защиты на уровне строк, результирующий план не помечался как потенциально зависимый от выполняющей его роли. Это могло приводить к тому, что последующие запросы в том же сеансе выполнялись с некорректным планом, а скрытые строки возвращались или возвращаемые скрывались.
Проект PostgreSQL благодарит Вольфганга Вальтера за сообщение об этой проблеме. (CVE-2024-10976)
Библиотека libpq теперь игнорирует сообщения об ошибках, получаемые во время согласования протоколов SSL или GSS (Джейкоб Чемпион) §
Злоумышленники могут подменять реальное выходное сообщение сервера об ошибке, получаемое до того, как завершено согласование криптографического протокола. Это может приводить к различным угрозам безопасности, например, злоумышленник может подменить результат запроса, а невнимательный пользователь спутает его с реальным результатом. Лучше всего игнорировать такие сообщения об ошибках и доверять только сообщениям libpq о сбое соединения.
Проект PostgreSQL благодарит Джейкоба Чемпиона за сообщение об этой проблеме. (CVE-2024-10977)
Исправление нежелательного взаимодействия команд
SET SESSION AUTHORIZATIONиSET ROLE(Том Лейн) § §Согласно стандарту SQL, команда
SET SESSION AUTHORIZATIONимеет побочный эффект в виде выполнения командыSET ROLE NONE. Это было реализовано некорректно, что приводило к дополнительному нежелательному взаимодействию между двумя командами. В частности, откат транзакции, в которой была выполнена командаSET SESSION AUTHORIZATION, приводил к откатуROLEдоNONE, даже если ранее было другое значение, и действующий идентификатор пользователя мог отличаться от идентификатора до выполнения транзакции. Временное включениеsession_authorizationв предложенииSETфункции приводило к тому же результату. Дополнительная ошибка заключалась в том, что при исследованииcurrent_setting('role')параллельным рабочим процессом он виделnone, даже если должен был видеть иное значение.Проект PostgreSQL благодарит Тома Лейна за сообщение об этой проблеме. (CVE-2024-10978)
Запрет на изменение переменных окружения доверенным кодом PL/Perl (Эндрю Дунстан, Ной Миш) § § § § §
Возможность изменять переменные окружения процессов, такие как
PATH, позволяет злоумышленнику выполнять произвольный код. Поэтому теперь это запрещено для «доверенных» процедурных языков. Чтобы исправить проблему сplperl, замените%ENVна связанный хеш, который запрещает вносить изменения с выводом предупреждения. Недоверенный языкplperluсохраняет возможность изменять переменные окружения.Проект PostgreSQL благодарит Коби Абрамса за сообщение об этой проблеме. (CVE-2024-10979)
Исправление обновлений состояния каталога для ограничений внешнего ключа при присоединении или отсоединении секций таблицы (Жеан-Гийом де Рорте, Альваро Эррера) § §
Если целевая таблица секционирована, для ссылающейся таблицы, которая является отдельной, а не секцией, необходимы другие записи каталога. Команды
ATTACH/DETACH PARTITIONвыполняли это преобразование некорректно. В частности, после выполнения командыDETACHдля новой отдельной таблицы терялись триггеры обеспечения целостности внешнего ключа, из-за чего в таблице могли появляться строки, не выполняющие требования по ограничению внешнего ключа. Кроме того, последующее повторное присоединение командойATTACHмогло приводить к неожиданным ошибкам.Это можно исправить, выполнив команду
ALTER TABLE DROP CONSTRAINTдля новой отдельной таблицы в отношении каждого ограничения с ошибкой и добавив ограничение заново. Ошибка при повторном добавлении ограничения означает появление ошибочных данных. В этом случае необходимо заново и вручную обеспечить целостность целевой и ссылающейся таблиц, а затем ещё раз добавить ограничение.Используйте запрос ниже, чтобы выявить нарушенные ограничения и подготовить команды для создания таких ограничений заново:
SELECT conrelid::pg_catalog.regclass AS "constrained table", conname AS constraint, confrelid::pg_catalog.regclass AS "references", pg_catalog.format('ALTER TABLE %s DROP CONSTRAINT %I;', conrelid::pg_catalog.regclass, conname) AS "drop", pg_catalog.format('ALTER TABLE %s ADD CONSTRAINT %I %s;', conrelid::pg_catalog.regclass, conname, pg_catalog.pg_get_constraintdef(oid)) AS "add" FROM pg_catalog.pg_constraint c WHERE contype = 'f' AND conparentid = 0 AND (SELECT count(*) FROM pg_catalog.pg_constraint c2 WHERE c2.conparentid = c.oid) <> ((SELECT count(*) FROM pg_catalog.pg_inherits i WHERE (i.inhparent = c.conrelid OR i.inhparent = c.confrelid) AND EXISTS (SELECT 1 FROM pg_catalog.pg_partitioned_table WHERE partrelid = i.inhparent)) + CASE WHEN pg_catalog.pg_partition_root(conrelid) = confrelid THEN (SELECT count(*) FROM pg_catalog.pg_partition_tree(confrelid) WHERE level = 1) ELSE 0 END);Поскольку один или несколько этапов выполнения команды
ADD CONSTRAINTмогут завершиться ошибкой, сохраните вывод запроса в файл и попробуйте заново повторить каждый этап.Предотвращение возможных сбоев и ошибки «could not open relation» (не удалось открыть отношение) при обращении к секционированной таблице, если одновременно с этим выполнялась команда
DETACH CONCURRENTLYи сразу же удалялась отсоединённая секция (Альваро Эррера, Кунтал Гош) § §Запрет выполнения команды
ALTER TABLE ATTACH PARTITION, если у присоединяемой таблицы есть внешний ключ, ссылающийся на секционированную таблицу (Альваро Эррера) § §Такая комбинация действий не поддерживается, и другие варианты её воспроизведения и ранее завершались ошибкой.
Запрет использования соединений или группировки с учётом секционирования, если сортировка в запросе для столбца ключа не соответствует сортировке ключа секционирования (Цзянь Хи, Веббо Хан) § §
Такие планы ранее могли приводить к некорректным результатам.
Исправление возможной ошибки «could not find pathkey item to sort» (не удалось найти элемент ключей пути для сортировки), когда необходима сортировка вывода запроса с оператором
UNION ALL, а столбец сортировки является выражением (Андрей Лепихов, Том Лейн)Устранение падений производительности, связанных с упрощением подзапросов под внешними соединениями, которые позднее преобразуются в обычные соединения (Том Лейн) §
Ранее некоторые запросы выполнялись менее оптимально в версии 16 по сравнению с предыдущими версиями из-за чрезмерного упрощения логики подтягивания запросов.
Возможность отменять второй этап построения индекса для крупных хеш-индексов (Павел Борисов) §
Исправление сбоя проверочного утверждения или сбивающего с толку сообщения об ошибке выполнения команды
COPY (, когдазапрос) TO ...запроспереписывается правиломDO INSTEAD NOTIFY(Тендер Ван, Том Лейн) §Исправление сбоя сервера в случаях, когда вызов
json_objectagg()содержит изменчивую функцию (Амит Ланготе) §Исправление проверки уникальности ключа в конструкторах объектов JSON (Цзюньван Жао, Томаш Вондра) §
При построении объектов больше одного килобайта раньше могли приниматься некорректные вводные данные с дубликатами ключей объектов или выводиться некорректные сообщения о наличии дубликатов ключей.
Исправление выявления асимметричных данных во время параллельного соединения по хешу (Томас Манро)
После пересекционирования внутренней стороны соединения по хешу из-за слишком большого количества накопленных кортежей в одной секции проверялось, что все кортежи секции попадали в одну и ту же дочернюю секцию. Так предполагалось, что у всех кортежей одно хеш-значение и последующее пересекционирование не может привнести улучшений. В некоторых случаях эта проверка не работала, из-за чего выполнялось бессмысленное многократное пересекционирование, что в итоге приводило к ошибке исчерпания ресурсов.
Запрет использования имён локалей, содержащих не ASCII-символы (Томас Манро)
Проблема возникала только в Windows, поскольку такие имена локалей больше нигде не используются. Основная сложность заключается в том, что неясно в какой кодировке они представлены (так как используемая кодировка определена в самой локали). Из-за этого недоразумения в последних выпусках PostgreSQL в библиотеке времени выполнения могли случаться прерывания операций.
При появлении нового сообщения об ошибке следует либо создать новую локаль с именем только из набора ASCII при помощи программы Locale Builder в Windows, либо использовать имена локалей, соответствующие языковому тегу BCP 47, например,
tr-TR.Устранение условий гонки при фиксации сериализуемой транзакции (Хейкки Линнакангас) §
Некорректная обработка недавно зафиксированной транзакции могла приводить к сбою проверочного утверждения или ошибке «could not access status of transaction» (не удалось получить состояние транзакции).
Устранение условий гонки при выполнении команды
COMMIT PREPARED, которые приводили к наличию потерянных файлов двухфазной фиксации (2PC) (У Чэнвэнь) §Параллельное выполнение нескольких команд
PREPARE TRANSACTIONмогло приводить к тому, что командаCOMMIT PREPAREDне удаляла файл состояния двухфазной фиксации на диске для завершённой транзакции. Мгновенно к негативным последствиям это не приводило, однако при последующем восстановлении после сбоя могла возникать ошибка «could not access status of transaction» (не удалось получить состояние транзакции), что требовало ручного удаления потерянного файла для восстановления службы.Предотвращение некорректного обращения к памяти после пропуска нерабочего индекса TOAST во время выполнения команды
VACUUM FULL(Тендер Ван) §Список, отслеживающий подлежащие перестройке индексы, некорректно обновлялся в этом месте кода, что могло приводить сбоям проверочных утверждений или отказам в будущем.
Исправление возможных потерь обновлений каталога «на месте» (Ной Миш) § § § § § § §
При обычном обновлении строк новая версия строки записывается, чтобы сохранить возможность отката транзакции. Однако при обновлении некоторых системных каталогов транзакции намеренно не затрагиваются, и в таком случае строка обновляется на месте. Данное исправление устраняет условия гонки, которые могли приводить к потере обновлений на месте. Одним из примеров была потеря того, что для
pg_class.relhasindexзадано значение true, что приводило к невозможности обновления нового индекса и, следовательно, его повреждению.Сброс кеша каталогов в конце процесса восстановления (Ной Миш) §
Таким образом предотвращаются сценарии, при которых обновления каталога на месте могли быть потеряны из-за использования устаревших данных из кеша каталога.
Предотвращение параллельного выполнения запросов при сдерживании прерываний (Франческо Деграсси, Ной Миш, Том Лейн) § §
С этой ситуацией невозможно было столкнуться во время обычной работы, но можно было воспроизвести при помощи тестовых сценариев, например использовав SQL-функцию в качестве опорной для B-дерева (что слишком медленно для промышленной эксплуатации). При успешном воспроизведении возникала ситуация бесконечного ожидания.
Вывод идентификатора активного запроса для целей статистики в начале обработки сообщений протокола Bind/Execute (Сами Имсейх) §
Теперь в расширенном протоколе запросов информация связывается с корректным запросом.
Защита от переполнения стека в libxml2, если вводные данные XML имеют слишком много уровней вложенности (Том Лейн с благодарностью Нику Велнхоферу)
Теперь вместо функции
xmlXPathCompile()используетсяxmlXPathCtxtCompile(), посколькуxmlXPathCompile()не защищает от переполнения стека при рекурсии в выпусках libxml2 ниже 2.13.4.Исправление проблем с пробельными символами в результате вызова функции
XMLSERIALIZE(... INDENT)(Джим Джонс) §Исправление ошибки добавления отступов для узлов, разделённых пробелами, и гарантия того, что завершающий символ новой строки добавлен не будет.
Запрет игнорирования параллельного выполнения команды
REINDEX CONCURRENTLYв отношении индекса с предикатами или выражениями (Михаил Николаев)Обычно команда
REINDEX CONCURRENTLYне ждёт выполнения операцийREINDEX CONCURRENTLYв других таблицах. Тем не менее, эта оптимизация не работает, если другая операцияREINDEX CONCURRENTLYобрабатывает индекс с предикатами или выражениями, когда такие выражения содержат определённый пользователем код, который обращается к другим таблицам. Ошибки в коде приводили к условиям гонки, а именно тому, что правило применялось неоднородно, а это вызывало нестабильное поведение.Исправление некорректной пересборки списков предложения
ORDER BYпри конфликте имён (Том Лейн) §Если элемент
ORDER BYвSELECTявляется простым идентификатором, анализатор сначала ищет его как имя выходного столбцаSELECT; это необходимо для совместимости с версией SQL-92. Однако ruleutils.c ожидает интерпретацию версии SQL-99, в которой такое имя является именем входного столбца. Поэтому представление могло отображать некорректные данные в случае (весьма неблагоприятном), когда в выходном спискеSELECTпереименовывался другой столбец для соответствия входному столбцу вORDER BY. Исправлено добавлением таких имён таблиц в текст выгруженного представления.Исправление ошибки «failed to find plan for subquery/CTE» (не удалось найти план для подзапроса/CTE) при выполнении команды
EXPLAIN(Ричард Гуо, Том Лейн) § §Проблема возникала при попытке добавления ссылок в поля вывода типа RECORD подзапроса, когда подзапрос был исключён из плана в ходе оптимизации (что было возможно, по крайней мере, потому что условие
WHEREпостоянно не выполнялось). В плане не оставалось данных, позволяющих идентифицировать исходные имена полей, поэтому теперь дляN-го столбца записи снова отображаетсяf. (В действительности это корректное поведение, если вывод типа RECORD является результатом конструкцииNROW().)Запрет предложения
USINGпри изменении типа генерируемого столбца (Питер Эйзентраут) §У генерируемого столбца уже есть выражение с указанием содержимого столбца, поэтому включение предложения
USINGне имеет смысла.Игнорирование ещё не определённых порталов в представлении
pg_cursors(Том Лейн) §Определённый пользователем код, исследующий это представление, мог вызываться при настройке нового курсора. Если это случалось, происходило обращение по нулевому указателю. Проблема решена определением представления так, чтобы исключать курсоры, которые ещё не полностью настроены.
Исправление некорректного вывода представления
pg_stat_ioна 32-битных системах (Бертран Друво) §В столбце
stats_resetс типом данныхtimestampдля таких систем содержались совершенно некорректные данные.Предотвращение некорректного кодирования сообщения об ошибке «trailing junk after numeric literal» (мусорное содержимое после числовой константы) (Карина Лицкевич) §
Указывать идентификаторы сразу после числовых констант запрещено (между ними должен быть пробельный символ). Если сразу после числовой константы был многобайтовый символ, в сообщение о синтаксической ошибке ранее включался только первый байт такого символа, что приводило к некорректному кодированию как в сообщении для клиента, так и в файле журнала postmaster.
Предотвращение ошибки «unexpected table_index_fetch_tuple call during logical decoding» (непредвиденный вызов table_index_fetch_tuple во время логического декодирования) при декодировании транзакции, содержащей вставку значения столбца по умолчанию (Такэси Идэриха, Хоу Чжицзе) § §
Уменьшение потребления памяти при логическом декодировании (Масахико Савада) §
Теперь используется блок по умолчанию меньшего размера для хранения данных кортежей, получаемых во время логического декодирования. Таким образом снижается потеря памяти, которая, как сообщается, была существенной, возникала во время длительных транзакций и даже приводила к сбоям из-за нехватки памяти.
Приостановка исходного процесса при возникновении ошибки или остановке процесса применения изменений логической репликации (Хайато Курода, Швета Малик) §
Ранее существовал риск потери транзакции, так как при возникновении ошибки исходный процесс не останавливался, а исходный сервер не посылал данные повторно.
Повторное отключение отправки сеансовых билетов (TLSv1.2) без сохранения состояния (Даниэль Густафссон) §
Предыдущее изменение, направленное на отключение отправки сеансовых билетов (TLSv1.3) с сохранением состояния, случайным образом влекло повторное включение отправки билетов без сохранения состояния. Из-за этого некоторые клиенты ошибочно полагали, что возобновление сессий TLS возможно.
Предотвращение ошибки «wrong tuple length» (некорректная длина кортежа) при удалении базы данных с большим числом записей в ACL (разрешений) (Аюш Тивари) § §
Возможность корректировать параметры
session_authorizationиroleв параллельных рабочих процессах (Том Лейн) §В коде предусмотрено разрешение на изменение параметров сервера через предложения
SETфункций, но не другими способами внутри параллельного рабочего процесса. Однако ранее для двух этих параметров предложенияSETне работали.Исправление поведения стабильных функций, вызываемых из списка аргументов оператора
CALL, гдеCALLнаходится в блокеEXCEPTIONPL/pgSQL (Том Лейн) §Как и до исправления в предыдущем квартальном выпуске, таким функциям ранее передавался неправильный снимок, в результате чего они получали устаревшие значения строк, которые уже изменились с момента начала внешней транзакции.
Исправление ошибок «cache lookup failed for function» (ошибка поиска в кеше для функции) в особых случаях для команды
CALLв PL/pgSQL (Том Лейн) §Исправление потокобезопасности запасного варианта реализации MD5 (не OpenSSL) на компьютерах с порядком байт от старшего (Хейкки Линнакангас) §
Потокобезопасность уже была обеспечена для сервера, но не для libpq.
Разбор параметра подключения
keepalivesв libpq так же, как и других целочисленных параметров (Юто Сасаки) §В используемом коде запрещались завершающие пробелы в значении параметра, в отличие от других случаев. Это оказалось проблемой, например, в использовании ecpg.
Предотвращение использования
pnstrdup()в ecpglib (Джейкоб Чемпион) §Эта функция вызывает
exit()при нехватке памяти, что нежелательно для библиотеки. Код, вызывающий функцию, уже правильно обрабатывает ошибки выделения памяти.Исправление чтения за пределами выборки при разборе некорректных даты и времени в ecpglib (Брюс Момджян, Павел Некрасов) §
Ранее было возможно попытаться считать расположение непосредственно перед началом константного массива. Однако практические следствия этой ошибки незначительны.
Устранение утечки памяти при многократном использовании команды
\bindв psql (Микаэль Пакье) §Предотвращение зависания в psql, если в команде
\watchуказан интервал менее 1 мс (Андрей Бородин, Микаэль Пакье) §Вместо этого такой интервал будет обрабатываться как равный нулю (без задержки между выполнениями).
Исправление обработки идентификационных последовательностей с характеристикой хранения отношений, отличной от таблицы-владельца, в pg_dump (Том Лейн) §
Начиная с 15-й версии, можно было определять идентификационную последовательность журналируемой, а таблицу-владелец — нежурналируемой, и наоборот. Однако pg_dump не мог воссоздать такой сценарий в режиме обновления в двоичном формате, что приводило к сбою работы pg_upgrade при наличии таких последовательностей. Для исправления введён новый параметр для
ADD/ALTER COLUMN GENERATED AS IDENTITY, который позволяет верно настраивать характеристику хранения отношений во время создания последовательности. Обратите внимание, что выгрузка базы данных, содержащей такую последовательность, будет производиться только на сервер этой корректирующей версии или новее.Включение исходной истории линии времени в вывод отладочных сообщений pg_rewind (Хейкки Линнакангас) §
Так было задумано изначально, но из-за ошибки в коде вместо исходной истории всегда выводилась пустая строка.
Предотвращение попытки перестройки индексов временных таблиц, индексов в vacuumdb и при параллельной перестройке индексов с помощью reindexdb (Вайбхав С, Микаэль Пакье, Фудзии Масао, Натан Боссарт) § § §
Перестройка индексов временных таблиц других сеансов невозможна, но проверка на пропуск отсутствовала в некоторых местах кода, что вело к нежелательным сбоям.
Реализация проверки отношений последовательностей в соответствующих функциях
contrib/pageinspectиcontrib/pgstattuple(Натан Боссарт, Аюш Ватса) § §Такая проверка была реализована ранее, но работала некорректно после реализации нестандартных методов доступа для таблиц.
Исправление некорректного кода, генерируемого LLVM, на платформах ARM64 (Томас Манро, Антонин Боннефой) §
При использовании JIT-компиляции на платформах ARM генерируемый код не поддерживал расстояния перемещения больше 32 бит, из-за чего он мог размещаться неудачно и вызывать сбои сервера в системах с большим объёмом памяти.
Исправление нескольких случаев, в которых допускалось, что время начала процесса (представленное
time_t) уместится в значение типаlong(Макс Джонсон, Натан Боссарт) §На платформах, где тип
longвмещает 32 бита (особенно на Windows), после 2038 года произойдёт сбой. В основном он проявит себя косметически, но в особенности зависнет командаpg_ctl start.Исправление сборки с Strawberry Perl на Windows (Эндрю Дунстан) §
Обновление данных часовых поясов до версии tzdata 2024b (Том Лейн) § §
В этом выпуске tzdata изменяются старые имена часовых поясов, совместимые с System V, теперь они дублируют соответствующие географические зоны. Например,
PST8PDTтеперь является псевдонимом дляAmerica/Los_Angeles. Единственное видимое последствие заключается в том, что для временных отметок до введения стандартизированных часовых поясов часовой пояс будет означать среднее солнечное время для заданного места. Например, вPST8PDTввод с типом данныхtimestamptz, такой как1801-01-01 00:00, раньше отображался как1801-01-01 00:00:00-08, а теперь — как1801-01-01 00:00:00-07:52:58.Кроме того, выполнены корректировки исторических данных для Мексики, Монголии и Португалии. Часовой пояс
Asia/Choibalsanтеперь является псевдонимом дляAsia/Ulaanbaatar, а не отдельным часовым поясом, в основном потому что разница между ними, как оказалось, основана на недостоверных данных.