E.2. Выпуск 14.1

Дата выпуска: 2021-11-11

В этот выпуск вошли различные исправления, внесённые после версии 14.0. За информацией о нововведениях версии 14 обратитесь к Разделу E.3.

E.2.1. Миграция на версию 14.1

Если используется версия 14.X, выгрузка/восстановление базы не требуется.

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

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

E.2.2. Изменения

  • Недопущение обработки сервером посторонних данных после сообщений установления шифрования SSL или GSS (Том Лейн)

    Злоумышленник, имеющий возможность внедрять данные в TCP-соединение, мог вставить некоторый объём незашифрованных данных в начале сеанса, который считался зашифрованным. Эксплуатируя это, можно было передавать серверу подставные команды, хотя это могло сработать, только если сервер не запрашивал никакие данные для аутентификации. (Однако опасность существовала и в случае, когда сервер осуществлял аутентификацию по сертификату.)

    Проект PostgreSQL благодарит Джейкоба Чемпиона за сообщение об этой проблеме. (CVE-2021-23214)

  • Недопущение обработки библиотекой libpq посторонних данных после сообщений установления шифрования SSL или GSS (Том Лейн)

    Злоумышленник, имеющий возможность внедрять данные в TCP-соединение, мог вставить некоторый объём незашифрованных данных в начале сеанса, который считался зашифрованным. Эксплуатируя это, можно было передать поддельные ответы на несколько первых запросов сервера, хотя ввиду других особенностей поведения libpq реализовать это на практике было не так просто. Была возможна и другая линия атаки — перехват пароля клиента или других секретных данных, которые могли передаваться в сеансе ранее. Возможность таких атак была продемонстрирована с сервером, подверженным уязвимости CVE-2021-23214.

    Проект PostgreSQL благодарит Джейкоба Чемпиона за сообщение об этой проблеме. (CVE-2021-23222)

  • Исправление работы физической репликации в случаях нештатной остановки главного сервера после передачи сегмента WAL с неполной записью WAL (Альваро Эррера)

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

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

  • Исключение пропуска индексов при выполнении VACUUM в параллельном режиме (Питер Гейган, Масахико Савада)

    При выполнении VACUUM в параллельном режиме не обрабатывались индексы, размер которых оказывался меньше min_parallel_index_scan_size, если в таблице также было не менее двух индексов большего размера. В результате пропущенные индексы могли повреждаться, так как в них могли оставаться ссылки на элементы в куче, удалённые при том же выполнении VACUUM; это проявлялось в том, что последующие запросы, задействующие эти индексы, могли выдавать строки, которые не должны были. Эта проблема не распространяется на процедуру autovacuum, так как данная процедура не использует параллельный режим. С учётом сказанного, имеет смысл перестроить все таблицы, подвергавшиеся очистке вручную, в которых оказалась подходящая по размеру комбинация индексов.

  • Исправление в CREATE INDEX CONCURRENTLY ожидания последних подготовленных транзакций (Андрей Бородин)

    Строки, добавленные только что подготовленными транзакциями, могли не попасть в новый индекс, вследствие чего запросы, полагающиеся на этот индекс, могли пропускать их. Предыдущее исправление проблем такого рода не учитывало, что команды PREPARE TRANSACTION могли ещё выполняться в тот момент, когда команда CREATE INDEX CONCURRENTLY проверяла их. Как и ранее, в инсталляциях, где включены подготовленные транзакции (max_prepared_transactions > 0), рекомендуется переиндексировать все индексы, построенные неблокирующим способом, на случай, если при их построении возникла подобная ситуация.

  • Исключение условий гонки, в которых обслуживающие процессы могли не добавить записи для новых строк в индекс, создаваемый неблокирующим способом (Ной Миш, Андрей Бородин)

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

  • Обеспечение в реализации REINDEX CONCURRENTLY сохранения параметров класса операторов, связанных с целевым индексом (Микаэль Пакье)

  • Исправление некорректного создания глобальных зависимостей при клонировании базы, содержащей не только встроенные объекты (Александр Алексеев)

    Следствия этой ошибки на практике представляются ограниченными. Теоретически некорректные зависимости могли позволить удалить роль, которой всё ещё принадлежали объекты, но в большинстве случаев желание удалять роль, которая владеет объектами, добавленными в template1, не должно возникать.

  • Обеспечение аннулирования кеша отношений для таблицы, присоединяемой к секционированной таблице или отсоединяемой (Амит Ланготе, Альваро Эррера)

    В результате допущенного упущения последующие операции добавления/изменения, обращённые непосредственно к этой секции, могли выполняться некорректно, но только в рамках уже существующих сеансов.

  • Устранение повреждения в дереве разбора запроса при создании диапазонного типа (Александр Кожемякин, Сергей Шиндерук)

    Команда CREATE TYPE некорректна освобождала элемент в дереве разбора, что затем могло приводить к сбою при выполнении событийного триггера или в случаях, когда команда CREATE TYPE сохранялась в кеше планов и позднее использовалась снова.

  • Исправление изменения полей элементов в массивах доменных типов, созданных поверх составных (Том Лейн)

    Команда вида UPDATE tab SET fld[1].subfld = val работала некорректно, если элементами массива были значения не просто составного, а доменного типа.

  • Запрещение использования FETCH FIRST WITH TIES в сочетании с FOR UPDATE SKIP LOCKED (Дэвид Кристенсен)

    Команда FETCH FIRST WITH TIES по необходимости считывает на одну строку больше, чем требуется, так как она может остановиться, только обнаружив строку, не равную предыдущей. В текущей реализации, когда используется режим FOR UPDATE, эта строка к тому же будет заблокирована, хотя и не будет выдана в результате. Вследствие этого с указанием SKIP LOCKED поведение было некорректным. Исправить это, не привнося другое странное поведение, сложно, поэтому такое сочетание на данный момент запрещено.

  • Запрещение команды ALTER INDEX index ALTER COLUMN col SET (options) (Натан Боссарт, Микаэль Пакье)

    Хотя анализатор запроса принимал такую команду, она не документирована и на самом деле не работала.

  • Устранение потери точности в функции power() при передаче ей особых значений (Дин Рашид)

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

  • Недопущение выбора неправильного оператора сравнения по хешу для планов Memoize (Дэвид Роули)

    В результате неправильного выбора могли выдаваться некорректные результаты запросов или происходить сбои.

  • Ликвидация ошибки планировщика, связанной с поднятием выражений из подзапросов в список отношений функции (Том Лейн)

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

  • Отказ от использования одной лишь статистики MCV для оценивания диапазона значений в столбце (Том Лейн)

    В некоторых особых случаях процедура ANALYZE строит список самых частых значений (MCV), но не строит гистограмму, хотя список MCV не даёт представления обо всех существующих значениях. В таких случаях планировщик не должен использовать только список MCV для оценивания диапазона значений в столбце.

  • Исправление восстановления снимка портала внутри подтранзакции (Бертран Друво)

    В случаях, когда процедура фиксировала или откатывала транзакцию, а следующее её значимое действие выполнялось в новой подтранзакции, управление снимками работало неправильно, вследствие чего мог появиться потерянный указатель или произойти сбой. Типичный пример такой конструкции в PL/pgSQL выглядит как следующий сразу после команды COMMIT блок BEGIN ... EXCEPTION, выполняющий запрос.

  • Обеспечение корректной очистки состояния при отмене транзакции после того, как был экспортирован её снимок (Дилип Кумар)

    Устранённая теперь ошибка могла создавать проблемы, только если тот же сеанс пытался ещё раз экспортировать снимок. Наиболее вероятный сценарий возникновения этой ошибки — создание слота репликации (за которым следует откат транзакции), а затем создание ещё одного слота репликации.

  • Предотвращение зацикливания при отслеживании переполнения подтранзакций на ведомых серверах (Кётаро Хоригути, Александр Коротков)

    Следствием устранённого теперь дефекта могло быть значительное снижение производительности, которое проявлялось в излишнем трафике SubtransSLRU, на ведомых серверах.

  • Обеспечение правильного учёта подготовленных транзакций во время повышения ведомого сервера (Микаэль Пакье, Андрес Фройнд)

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

  • Исправление ошибки «could not find RecursiveUnion ...» (не удалось найти RecursiveUnion ...), возникавшей в EXPLAIN при попытке вывести условие фильтра, присоединённое к узлу WorkTableScan (Том Лейн)

  • Установление корректного уровня блокировки при переименовании таблицы (Натан Боссарт, Альваро Эррера)

    По историческим причинам команду ALTER INDEX ... RENAME можно применять к отношениям любого вида. Уровень блокировки, требующийся для переименования индекса, ниже, чем уровень для таблицы или другого типа отношения, но реализация это не учитывала и всегда использовала низкий уровень, когда команда переименования отношения записывалась как ALTER INDEX.

  • Исключение обращений по нулевому указателю, приводящим к сбою, при удалении роли, владеющей объектами, которые удаляются параллельно (Альваро Эррера)

  • Устранение предупреждения «snapshot reference leak» (утечка ссылки на снимок) при ошибке в lo_export() или связанной функции (Хейкки Линнакангас)

  • Исправление неэффективного кода обработки узлов CoerceToDomain (Ранье Вилела)

  • Уход от алгоритмов сложности O(N^2) в ряде процедур обработки списков (Натан Боссарт, Том Лейн)

    Внесённые исправления ускоряют обработку в различных сценариях, в частности: когда ведомый сервер воспроизводит транзакцию, удерживающую много исключительных блокировок на ведущем; когда после контрольной точки требуется удалить множество файлов; когда при агрегировании по хешу задействуется много пакетов; когда pg_trgm извлекает индексируемые условия из сложного регулярного выражения. На самом деле с мест сообщили только о первом сценарии, но и в остальных неэффективное удаление элементов из списка может негативно сказаться на производительности.

  • Добавление более надёжных проверок в код, осуществляющий разделение списка идентификаторов btree (Питер Гейган)

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

  • Устранение сбоя проверочного утверждения при добавлении NaN в индекс BRIN по значениям float8 или float4, использующий операторы minmax_multi_ops (Томаш Вондра)

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

  • Ускорение реакции процесса, запускающего autovacuum, на запросы pg_log_backend_memory_contexts() (Кою Танигава)

  • Устранение утечки памяти в коде, вычисляющем хеш HMAC (Сергей Шиндерук)

  • Недопущение для параметра huge_pages значения on при использовании sysv в качестве shared_memory_type (Томас Манро)

    Ранее это значение принималось, но никак не действовало ввиду отсутствия реализации.

  • Исправление проверки типа запроса в операторе PL/pgSQL RETURN QUERY (Том Лейн)

    Команда RETURN QUERY должна принимать любой запрос, который может выдавать кортежи, например UPDATE RETURNING. В 14 версии ненамеренно были запрещены все, кроме SELECT; более того, команда RETURN QUERY EXECUTE вообще никак не проверяла тип запроса.

  • Исправление в pg_dump выгрузки прав по умолчанию, определяемых не глобально (Нейл Чен, Масахико Савада)

    Если глобальная (неограниченная) команда ALTER DEFAULT PRIVILEGES отзывала какие-либо представляемые по умолчанию права, например право EXECUTE для функций, а затем ограниченная команда ALTER DEFAULT PRIVILEGES возвращала эти права отдельной роли или схеме, программа pg_dump не могла выгрузить ограниченное назначение прав правильно.

  • Установление в pg_dump разделяемых блокировок для секционированных таблиц, подлежащих выгрузке (Том Лейн)

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

  • Устранение сбоя в pg_dump при попытке выгрузить определение триггера с сервера версии до 8.3 (Том Лейн)

  • Исправление имени файла в сообщении об ошибке, выдаваемом pg_restore при получении неправильного файла с перечнем больших объектов (Даниэль Густафссон)

  • Обеспечение завершения pgbench с ненулевым кодом состояния в случае ошибки на уровне сокета (Юго Нагата, Фабьен Коэльо)

    Ожидаемым поведением должно быть завершение прогона и выход с кодом 2. Также скорректирован вывод сообщения о такой ошибке.

  • Предотвращение проверки программой pg_amcheck временных отношений, а также индексов, находящихся в нерабочем или в не готовом состоянии (Марк Дилгер)

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

  • Исключение из рассмотрения contrib/amcheck нежурналируемых таблиц при выполнении проверок на ведомом сервере (Марк Дилгер)

    Это объясняется тем, что такие таблицы будут пустыми, а нежурналируемые индексы исключались и ранее.

  • Реализация в расширении contrib/pg_stat_statements чтения его файла «текстов запросов» блоками размером не больше 1 ГБ (Том Лейн)

    Файлы очень большого размера с текстами запросов весьма нетипичны, но в случае их наличия ранее происходил сбой в 64-разрядной ОС Windows (в которой один запрос на чтение файла не может прочитать больше 2 ГБ).

  • Устранение в contrib/postgres_fdw обращения по нулевому указателю при попытке сообщить об ошибке преобразования данных (Том Лейн)

  • Обеспечение возможности вызова GetSharedSecurityLabel() в только что начатом сеансе, в котором ещё не получены критически важные для него элементы кеша отношений (Джефф Дэвис)

  • Добавление каталога выполняемого модуля TAP-тестов в переменную PATH (Эндрю Дунстан)

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

  • Использование данных проекта CLDR для сопоставления принятых в Windows названий часовых поясов с часовыми поясами IANA (Том Лейн)

    Программа initdb, запущенная в Windows, пытается установить для нового кластера в параметре timezone часовой пояс IANA, соответствующий часовому поясу, выбранному в системе. Мы использовали таблицу соответствия, которая была сформирована несколько лет назад и обновлялась бессистемно: неудивительно, что в ней содержался ряд неточностей и не хватало добавленных не так давно часовых поясов. Выяснилось, что в CLDR отслеживаются наиболее подходящие сопоставления, поэтому решено использовать их данные. Это изменение затронет только впоследствии создаваемые кластеры, на существующие оно никак не повлияет.

  • Обновление данных часовых поясов до версии tzdata 2021e, включающее изменение правил перехода на летнее время в Иордании, Палестине, на Фиджи и Самоа, а также корректировку исторических данных для Барбадоса, островов Кука, Ниуэ, Гайаны, Португалии и Тонга.

    Кроме того, пояс Pacific/Enderbury был переименован в Pacific/Kanton. Помимо этого, следующие пояса были включены в соседние, более популярные пояса, в которых время было таким же с 1970 г.: Africa/Accra, America/Atikokan, America/Blanc-Sablon, America/Creston, America/Curacao, America/Nassau, America/Port_of_Spain, Antarctica/DumontDUrville и Antarctica/Syowa. Для всех этих поясов старое название сохранено в качестве альтернативного.