E.45. Выпуск 12.9

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

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

E.45.1. Миграция на версию 12.9

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

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

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

Если вы обновляете сервер с более ранней версии, чем 12.6, см. также Раздел E.48.

E.45.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, а затем обновлять главный.

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

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

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

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

  • Исправление хеш-функций для типов float4 и float8, чтобы они возвращали одинаковые результаты для значений NaN (Том Лейн) § § §

    Так как в PostgreSQL значения NaN разных типов с плавающей точкой считаются равными, важно, чтобы и хеш-функции выдавали одинаковые хеши для всех комбинация битов, которые воспринимаются как NaN согласно стандарту IEEE 754. Раньше этого не происходило, вследствие чего хеш-индексы и планы запросов, использующие хеши, могли выдавать неправильные результаты для неканонических представлений NaN. (Подобное значение на большинстве машин можно было получить, записав '-NaN'::float8.) Поэтому сейчас рекомендуется переиндексировать хеш-индексы, построенные по столбцам с числами с плавающей точкой, если в них могли оказаться такие значения.

  • Предотвращение потери данных в процессе восстановления после сбоя, произошедшего после выполнения CREATE TABLESPACE, при значении wal_level = minimal (Ной Миш) §

    Если в промежутке между выполнением CREATE TABLESPACE и следующей контрольной точкой происходил сбой сервера, в ходе восстановления полностью удалялось содержимое каталога нового табличного пространства в расчёте на то, что при последующем воспроизведении WAL будет восстановлено всё в этом каталоге. Однако это плохо работает с оптимизациями, которые пропускают запись WAL (например, когда команда COPY записывает данные в создаваемую ей же таблицу). Такие оптимизации применяются, только если для wal_level установлено значение minimal (которое не является значением по умолчанию, начиная с 10 версии).

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

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

  • Обеспечение аннулирования кеша отношений для всех секций секционированной таблицы, добавляемой или удаляемой из публикации FOR ALL TABLES (Хоу Чжицзе, Вигнеш Си)

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

  • Сохранение операции приведения к тому же типу в случае отсутствия модификатора типа (Том Лейн) §

    Например, для столбца f1 типа numeric(18,3) анализатор запроса просто отбрасывал приведение вида f1::numeric, полагая, что оно никак не влияет на выполнение запроса. Это так, но итоговым типом выражения всё же должен считаться простой numeric, а не numeric(18,3). Это важно для правильного разрешения типов во внешних конструкциях, например в рекурсивных UNION.

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

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

  • Запрещение создания правил сортировки, использующих ICU, когда это не поддерживается кодировкой базы (Том Лейн) §

    Ранее такое правило можно было создать, но его нельзя было использовать из-за особенностей поиска правил сортировки; мало того, его нельзя было и удалить.

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

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

  • Исключение ошибок в регулярных выражениях с захватом скобок внутри {0} (Том Лейн) §

    При обработке выражений вида (.){0}...\1 выдавалась ошибка «invalid backreference number» (неправильный номер обратной ссылки). Однако другие процессоры регулярных выражений, например Perl, воспринимают это, так же как некоторые подобные выражения воспринимает и наша реализация. Что хуже, вместо ошибки мог произойти сбой проверочного утверждения. После этого исправления такая ошибка выдаваться не будет, а обратная ссылка будет просто считаться не соответствующей ничему.

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

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

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

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

  • Исправление результатов выражения AT TIME ZONE, применённого к значению типа time with time zone (Том Лейн) §

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

  • Исправление некорректного перевода переменных-местозаполнителей в дочерние отношения в иерархии наследования (Том Лейн) §

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

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

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

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

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

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

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

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

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

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

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

  • Запрещение перематывания курсора с пометкой NO SCROLL в случаях, когда он остаётся от предыдущей транзакции из-за указания WITH HOLD (Том Лейн) §

    Мы давно запрещаем чтение назад из курсора с пометкой NO SCROLL, но по историческим причинам этот запрет не распространялся на случаи, в которых мы перематываем весь запрос и затем повторяем чтение вперёд. Это исключение создавало несогласованность, в частности для удерживаемых курсоров, в которых могут не сохраняться все данные, нужные для перематывания. Поэтому для недопущения худших вариантов несогласованности решено запретить перематывание непрокручиваемых удерживаемых курсоров. (В 15 версии это исключение будет устранено полностью.)

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

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

    Попытка расширить таблицу или индекс сверх предела в 2^32-1 блоков пресекалась и раньше, но с некоторым запозданием, так что успевала нарушиться согласованность внутреннего состояния.

  • Корректировка отслеживания наличия CTE, изменяющих данные, при разворачивании правила DO INSTEAD (Грег Нанкарроу, Том Лейн) §

    Из-за устранённого теперь упущения могли возникнуть проблемы, например, выбирались параллельные планы, когда это было небезопасно.

  • Исправление формирования сообщения об ошибке, связанной с правами доступа к объектам расширенной статистики (Томаш Вондра) § §

    Ранее вместо нужного сообщения выдавалось «cache lookup error» (ошибка поиска в кеше).

  • Исправление некорректной обработки снимков в параллельных исполнителях (Грег Нанкарроу)

    Из-за ошибки параллельные запросы могли работать неправильно на уровне изоляции транзакций ниже REPEATABLE READ.

  • Обеспечение при логическом декодировании фильтрации изменений в TOAST-таблицах, связанных с переходными таблицами (Бертран Друво) §

    При логическом декодировании обычно игнорируются изменения в переходных таблицах, например изменения, происходящие при перезаписи кучи командой ALTER TABLE. Но эта фильтрация не распространялась на связанную TOAST-таблицу, вследствие чего могли возникать ошибки при перезаписи публикуемой таблицы.

  • Обеспечение создания процессами walreceiver всех требующихся файлов уведомлений архива перед выходом (Фудзии Масао) §

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

  • Исключение попыток блокирования псевдоотношений OLD и NEW в правиле, использующем SELECT FOR UPDATE (Масахико Савада, Том Лейн) §

  • Корректировка обработки агрегатных предложений FILTER в анализаторе запросов (Том Лейн) §

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

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

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

  • Предотвращение попытки очистить состояние LLVM после ошибки, возникшей внутри LLVM (Андрес Фройнд, Джастин Призби) §

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

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

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

  • Исправление подсчёта операций сканирования индексов SP-GiST в статистических представлениях (Том Лейн) §

    Увеличение счётчика «количество сканирований индекса» в коде SP-GiST не производилось из-за упущения, хотя счётчики кортежей увеличивались корректно.

  • Пересчёт соответствующих интервалов ожидания в случаях, когда параметр recovery_min_apply_delay меняется во время восстановления (Соумйадип Чакраборти, Ашвин Агравал) §

  • Устранение бесконечного цикла в случае добавления в хеш-таблицу в simplehash.h 2^32 элементов (Юрий Соколов) §

    Вероятность столкнуться с этой ошибкой на практике невелика, так как для этого при существующем варианте использования simplehash.h потребуется задать в work_mem объём в сотни гигабайт.

  • Уменьшение потребления памяти при вычислении расширенной статистики (Джастин Призби, Томаш Вондра) § §

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

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

  • Исправление поведения ecpg при ошибке в malloc() в процессе установления соединения (Микаэль Пакье) §

  • Исправление ошибочного вычисления стабильных функций, вызываемых в аргументах оператора CALL языка PL/pgSQL (Том Лейн) §

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

  • Реализация выхода из самого внешнего блока подпрограммы на PL/pgSQL при выполнении EXIT (Том Лейн) §

    Если в подпрограмме не требуется явный оператор RETURN, такое использование EXIT должно быть возможным, но ранее оно не допускалось.

  • Устранение в pg_ctl жёстких ограничений на общую длину формируемых команд (Фил Крылов) §

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

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

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

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

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

  • Увеличение производительности pg_dump за счёт исключения запросов политик RLS для каждой отдельной таблицы и устранения повторяющихся вызовов format_type() (Том Лейн) § §

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

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

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

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

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

  • Исправление ошибки в индексах contrib/btree_gin по столбцам "char" (не char(n)), проявлявшейся при сканировании индекса с использованием оператора < или <= (Том Лейн) §

    Ранее при таком сканировании выдавались не все элементы, которые должны были.

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

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

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

  • Добавление поддержки циклических блокировок для архитектуры RISC-V (Марек Шуба) §

    Это имеет большое значение для обеспечение хорошей производительности на этой платформе.

  • Обеспечение поддержки OpenSSL 3.0.0 (Питер Эйзентраут, Даниэль Густафссон, Микаэль Пакье) § § § §

  • Установка правильного идентификатора типа для объектов BIO (абстракции ввода/вывода), которые создаёт PostgreSQL (Итамар Гафни) §

    Исправленная теперь ошибка могла быть заметна только для кода, который выполняет такие задачи, как аудит инсталляции OpenSSL. Но всё же формально это было нарушением OpenSSL API, которое стоило устранить.

  • Исправление наших файлов pkg-config для восстановления поддержки статического связывания с libpq (Питер Эйзентраут) §

  • Исправление в pg_regexec() обработки параметра search_start, выходящего за допустимые пределы (Том Лейн) §

    Когда позиция search_start выходит за конец строки, теперь выдаётся результат REG_NOMATCH, тогда как раньше мог произойти сбой. Достижение этого состояния при использовании только ядра PostgreSQL не представляется возможным, однако расширения могут недостаточно строго проверять значение этого параметра.

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

  • Использование данных проекта 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. Для всех этих поясов старое название сохранено в качестве альтернативного.