E.9. Выпуск 14.3

Дата выпуска: 2022-05-12

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

E.9.1. Миграция на версию 14.3

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

Однако если у вас есть индексы GiST по столбцам типа ltree (предоставляемым расширением contrib/ltree), их нужно переиндексировать после обновления. Об этом рассказывается во втором пункте списка изменений.

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

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

  • Расширение множества операций, выполняемых в «песочнице» как операции с ограничениями по безопасности (Сергей Шиндерук, Ной Миш)

    В коде автоочистки, CLUSTER, CREATE INDEX, REINDEX, REFRESH MATERIALIZED VIEW и pg_amcheck защитный механизм, обеспечивающий безопасное выполнение операции, включался слишком поздно или не включался вовсе при некоторых условиях. Пользователь, имеющий права для создания невременных объектов в базе данных, мог создать такой объект, который позволил бы выполнить произвольный SQL-код с правами суперпользователя при следующей обработке этого объекта процессом автоочистки или одной из перечисленных команд, запущенной суперпользователем.

    Проект PostgreSQL благодарит Александра Лахина за сообщение об этой проблеме. (CVE-2022-1552)

  • Исправление длины сигнатуры по умолчанию для индексов gist_ltree_ops (Томаш Вондра, Александр Коротков)

    Длина сигнатуры по умолчанию (размер хеша) для индексов GiST по столбцам ltree была непредусмотрительно изменена при добавлении поддержки параметров класса в этот класс операторов. Если с таким индексом производились какие-либо операции до того, как расширение ltree было обновлено до версии 1.2, они выполнялись в предположении, что сигнатура имеет длину 28 байт, а не 8 (как было на самом деле). Это значит, что в результате такие индексы, скорее всего, были повреждены. Мы рекомендуем на всякий случай перестроить все индексы GiST по столбцам ltree после установки этого обновления. (Заметьте, что индексы GiST по столбцам ltree[], то есть по массивам значений ltree, этой проблеме не подвержены.)

  • Прекращение обработки заданных в запросе псевдонимов столбцов в переменных «вся строка», ссылающихся на простые таблицы (Том Лейн)

    Столбцы в кортежах, образованных переменными «вся строка» (например, tbl.* во всех контекстах, кроме верхнего уровня списка SELECT), теперь всегда получают имена от соответствующего составного типа, если он имеется. Ранее мы пытались отслеживать все псевдонимы столбцов, заданные в элементе FROM, на который ссылается переменная. Но это сомнительно с точки зрения семантики, так как содержимое переменной при этом фактически вообще не соответствует составному типу, который она в принципе должна представлять. Предыдущие попытки устранить эту несогласованность имели плохие последствия, вплоть до сохранения нечитаемых данных на диске, поэтому было решено отказаться от этой идеи.

    В случаях, когда требуется переименовать такие столбцы, это можно сделать, добавив дополнительный уровень вложенности SELECT, чтобы переменная «вся строка» ссылалась на результат внутреннего SELECT, а не на исходную таблицу. Тогда переменная типа record будет получена из неё, что даст желаемый результат.

  • Исправление некорректного округления при получении значения эпохи Unix из интервалов (Питер Эйзентраут)

    Новый код EXTRACT(), реализованный на базе numeric, выдавал не те результаты, что прежняя реализация на базе float, вследствие непреднамеренного усечения значения DAYS_PER_YEAR до целочисленного.

  • Реализация защиты от вызова pg_stat_get_replication_slot(NULL) (Андрес Фройнд)

    Эта функция должна была иметь пометку strict в каталоге, но в версии 14 эту пометку не добавили, поэтому она была заменена проверкой во время выполнения.

  • Исправление некорректного вывода для типов timestamptz и timetz в table_to_xmlschema() и родственных функциях (Ренан Соарес Лопес)

    Выводимая xml-схема для этих типов включала неправильные регулярные выражения.

  • Предотвращение аварийного сбоя в анализаторе при обработке предложения VALUES с нулём столбцов (Том Лейн)

  • Устранение ошибки планировщика, возникавшей, когда узел Result располагался непосредственно под узлом Append (Эцуро Фудзита)

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

  • Устранение ошибки планировщика в случаях, когда в запросе с предложениями SEARCH или CYCLE фигурировало повторяющееся имя CTE (Том Лейн, Кётаро Хоригути)

    Когда имя рекурсивного запроса WITH использовалось внутри того же запроса, мог произойти сбой или планировщик выдавал странную ошибку вида «could not find attribute 2 in subquery targetlist» (не удалось найти атрибут 2 в целевом списке подзапроса).

  • Исправление ошибок планировщика при обработке конструкций GROUPING(), обращающихся к внешним уровням запроса (Ричард Гуо, Том Лейн)

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

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

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

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

  • Ликвидация утечки памяти на протяжении запроса в узле IndexScan, производящем пересортировку (Александр Каленик)

  • Обеспечение в ALTER FUNCTION поддержки изменения в одной команде и свойства параллельности функции, и списка назначаемых для неё переменных (Том Лейн)

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

  • Улучшение поиска индекса, «принадлежащего» ограничению (Том Лейн, Япинь Ли)

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

  • Устранение ложных сообщений об ошибке при попытке изменить системные столбцы таблиц (Том Лейн)

    Система должна просто сказать, что это нельзя делать, но иногда вместо этого выдавалось сообщение «no owned sequence found» (зависимая последовательность не найдена).

  • Исправление ошибочной сортировки строк таблицы при выполнении CLUSTER по индексу, ведущим ключом которого является выражение (Питер Гейган, Томас Манро)

    Таблица перестраивалась с корректными данными, но порядок сортировки никак не соответствовал порядку индекса.

  • Предотвращение потери данных в случае сбоя системы сразу после перестроения индекса GiST с сортировкой (Хейкки Линнакангас)

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

  • Исключение риска взаимоблокировки при удалении секционированного индекса (Джимми Йи, Гаураб Дей, Том Лейн)

    Теперь требующиеся блокировки таблиц и индексов будут устанавливаться в стандартном порядке (родители, затем потомки; таблицы, затем индексы). В предыдущей реализации DROP INDEX блокировки устанавливались по-другому, что могло привести к взаимоблокировке при одновременном выполнении запросов, устанавливающих блокировки в стандартном порядке.

  • Устранение условий гонки между DROP TABLESPACE и процессом контрольных точек (Натан Боссарт)

    Процедура контрольной точки, выполняемая принудительно командой DROP TABLESPACE, иногда могла не удалить все ставшие ненужными файлы из каталога табличного пространства, вследствие чего выдавалась ошибка «tablespace is not empty» (табличное пространство не пусто).

  • Исключение возможной проблемы при восстановлении после сбоя, которому предшествовало выполнение команды TRUNCATE, наложившееся на контрольную точку (Кётаро Хоригути, Хейкки Линнакангас, Роберт Хаас)

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

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

    Процедура удаления временных объектов при завершении серверного процесса могла прерываться ошибкой «FATAL: cannot fetch toast data without an active snapshot» (ВАЖНО: прочитать данные TOAST без активного снимка нельзя). Обычно это не было проблемой, так как при следующем использовании этой временной схемы она должна была очиститься успешно.

  • Возвращение возможности сделать подчёркивание первым символом в имени дополнительного параметра (Япинь Ли)

    Такие имена ненамеренно были запрещены в 14 версии.

  • Добавление нового значения regress для параметра compute_query_id (Микаэль Пакье)

    Оно предназначается для упрощения тестирования — с данным значением идентификаторы запросов будут вычисляться, но не будут показываться в выводе EXPLAIN.

  • Усовершенствование логики ожидания в RegisterSyncRequest (Томас Манро)

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

  • Реализация ожидания защёлки с возможностью пробуждения во время простоя процесса checkpointer между операциями записи (Томас Манро)

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

  • Устранение сбоя с сообщением «PANIC: xlog flush request is not satisfied» (ПАНИКА: запрос на сброс xlog не выполнен) при повышении ведомого сервера после того, как на нём была пропущена отсутствующая запись продолжения WAL (Сами Имсейх)

  • Устранение возможности самоблокировки при обработке конфликта на сервере горячего резерва (Андрес Фройнд)

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

  • Исправление некорректного определения родительского отношения для публикации изменений при логической репликации (Томаш Вондра, Хоу Чжицзе, Амит Капила)

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

  • Обеспечение возможности перезапуска рабочих процессов применения логической репликации даже при достижении предела max_sync_workers_per_subscription (Амит Капила)

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

  • Внесение в WAL значений столбцов, образующих ключ идентификации реплики, которые не были изменены при изменении строки, но хранятся вне кортежа (Дилип Кумар, Амит Капила)

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

  • Исправление поведения на платформах, которые не поддерживают изменение информации о процессе в ps(1) (Эндрю Дунстан)

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

  • Улучшение стабильности сервера в случаях потери прерываний таймера (Майкл Харрис, Том Лейн)

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

  • Недопущение выполнения функций SPI во время компиляции функции на PL/Perl (Том Лейн)

    Perl позволяет выполнять определённый пользователем код во время компиляции функции на PL/Perl. Однако такому коду нельзя позволять выполнять операции SQL через SPI. В противном случае либо произойдёт сбой, либо возникнет угроза безопасности, так как мы на самом деле не ожидаем, что код будет выполняться во время проверки функции. Теперь во избежание этого добавлена проверка с понятным сообщением об ошибке.

  • Обеспечение в libpq возможности принимать файлы закрытых ключей SSL, принадлежащие root (Дэвид Стил)

    Это изменение уравнивает действующие в libpq правила безопасного владения и разрешений для файлов ключей SSL с правилами, принятыми на стороне сервера, начиная с версии 9.6. А именно, к текущим правилам добавлен случай, когда файлом ключа владеет root и для этого файла заданы разрешения rw-r----- или более строгие. Это облегчает управление файлами ключей на уровне системы.

  • Исправление поведения функции libpq PQisBusy() после ошибки подключения (Том Лейн)

    Ранее в случае возникновения ошибки записи PQisBusy() всегда возвращала true, что некорректно: мы хотим, чтобы чтение производилось в обычном режиме, пока от сервера не будут получены все передаваемые им данные. На практике этот дефект проявлялся в том, что приложения, использующие API асинхронных запросов libpq, обычно обнаруживали потерю подключения, только когда функция PQconsumeInput() сообщала о проблеме. После данного исправления о потере соединения будет сигнализировать ошибка в объекте PGresult, что позволяет обрабатывать это состояние в приложениях более аккуратно.

  • Восстановление возможности использовать шаблоны вида база_данных.схема.таблица в psql, pg_dump и pg_amcheck (Марк Дилгер)

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

  • Добавление в pg_ctl перепроверки существования процесса postmaster во время ожидания действий stop/restart/promote (Том Лейн)

    Ранее утилита pg_ctl проверяла, работает ли postmaster, попутно с тем, как передавала ему сигнал stop или promote, но затем она просто наивно ждала, пока не изменится состояние на диске. Если процесс postmaster завершался нештатно, не удалив свой файл PID или не отразив состояние в управляющем файле, ожидание pg_ctl завершалось только по тайм-ауту. Теперь pg_ctl будет постоянно перепроверять, не исчез ли процесс postmaster.

  • Исправление обработки ошибок в pg_waldump (Кётаро Хоригути, Андрес Фройнд)

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

  • Обеспечение в функциях модуля contrib/pageinspect корректной обработки полностью нулевых страниц (Микаэль Пакье)

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

  • Добавление в contrib/pageinspect защиты от некорректного содержимого «специальной области» страниц, усиление проверок размера страниц и добавление недостающих проверок соответствия типа индекса ожидаемому (Микаэль Пакье, Джастин Призби, Жюльен Руо)

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

  • Отключение в contrib/postgres_fdw массового добавления данных в случаях, когда в сторонней таблице существуют триггеры BEFORE INSERT ... FOR EACH ROW (Эцуро Фудзита)

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

  • Добавление в contrib/postgres_fdw проверки возможности безопасного удалённого выполнения предложения ORDER BY до передачи запроса с удалённой сортировкой, а также дополнение этого предложения указанием USING, когда оно необходимо (Ронан Данклау)

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

  • Исправление configure для платформ, где имеется sys/epoll.h, но отсутствует sys/signalfd.h (Том Лейн)

  • Обновление кода JIT для совместимости с LLVM 14 (Томас Манро)

  • Устранение разнообразных дефектов, выявленных проверками clang -fsanitize=undefined (Том Лейн, Андрес Фройнд, Чжихун Юй)

    Большинство дефектов исправлено только ради формального соответствия букве языка C и стандартов POSIX, вряд ли они могли как-то проявляться в производственных сборках.

  • Исключение зависимостей OpenSSL из файла libpq pkg-config при сборке без OpenSSL (Фабрис Фонтен)

  • Внесение исправлений в код PL/Perl, чтобы он собирался компиляторами C, не поддерживающими вложение операторов в выражения (Том Лейн)

  • Устранение потенциальной ошибки сборки pg_dumpall в Windows при использовании для сборки не MSVC (Андрес Фройнд)

  • Смена применяемой в сборках для Windows программы, создающей файлы DEF, с pexports на gendef (Эндрю Дунстан)

    Таким образом обеспечена совместимость процесса сборки с последней версией инструментария MSys.

  • Предотвращение дополнительного разворачивания шаблонов оболочки в программах, собираемых в MinGW (Эндрю Дунстан)

    По какой-то причине библиотека C, представленная в MinGW, по умолчанию разворачивает символы подстановки, полученные в командной строке программы. Такое поведение вызывает вопросы, как минимум потому что с библиотекой MSVC этого не происходит, поэтому оно отключено.

  • Обновление данных часовых поясов до версии tzdata 2022a, включающее изменение правил перехода на летнее время в Палестине, а также корректировку исторических данных для Чили и Украины.