PostgreSQL 17: Часть 1 или Коммитфест 2023-07

от автора


Продолжаем следить за новостями из мира PostgreSQL. Выпуск PostgreSQL 16 Release Candidate 1 планируется на 31 августа и, если всё будет в порядке, то 16-я версия выйдет 14 сентября.

Что изменилось в 16-й версии после апрельской заморозки кода? Что попало в 17 версию по результатам первого коммитфеста? Обо всем об этом в свежем обзоре.

PostgreSQL 16

В начале, для справки, ссылки на предыдущие статьи о 16-й версии, привязанные к коммитфестам: 2022-07, 2022-09, 2022-11, 2023-01, 2023-03.

С апреля произошли некоторые важные изменения, на которые стоит обратить внимание.

И начнем с потерь. Следующие разработки были отменены:

А некоторые работы получили продолжение:

psql: \drg новая команда для просмотра информации о членстве в ролях
commit: d65ddaca

Новая команда добавлена в 16-ю версию уже после заморозки кода. Обычно так не делают, но это лишь доработка интерфейса psql к возможностям сервера, появившимся в 16-й версии.

Создадим роль alice для администрирования ролей:

CREATE ROLE alice LOGIN CREATEROLE; \c - alice

Пусть при создании ролей alice автоматически наследует привилегии новой роли и возможность переключаться на нее командой SET ROLE:

SET createrole_self_grant = 'INHERIT, SET';  CREATE ROLE bob LOGIN;

Новой командой \drg проверим, что alice включена в роль bob с соответствующими параметрами:

\drg alice

               List of role grants  Role name | Member of |   Options    | Grantor   -----------+-----------+--------------+----------  alice     | bob       | INHERIT, SET | alice  alice     | bob       | ADMIN        | postgres (2 rows)

Отмечаем, что роль alice включена в роль bob дважды. Еще одно включение c ADMIN OPTION выполнено от имени начального суперпользователя. Оно и позволяет alice управлять ролью bob. Знать кто именно включил одну роль в другую, важно, т.к. только включивший может выполнить соответствующую команду REVOKE для исключения.

Создадим роль charlie и включим новую роль в bob:

CREATE ROLE charlie LOGIN; GRANT bob TO charlie WITH ADMIN FALSE, INHERIT FALSE, SET TRUE;  \drg

               List of role grants  Role name | Member of |   Options    | Grantor   -----------+-----------+--------------+----------  alice     | bob       | INHERIT, SET | alice  alice     | bob       | ADMIN        | postgres  alice     | charlie   | INHERIT, SET | alice  alice     | charlie   | ADMIN        | postgres  charlie   | bob       | SET          | alice (5 rows)

В предыдущих версиях членство в ролях проверялось в столбце «Member of» команды \du (или \dg). Но добавить в этот столбец новую информацию о том, кто выдал членство и с какими параметрами, оказалось не просто. Поэтому и была создана новая команда \drg.

А в \du и \dg пришлось убрать столбец «Member of»:

\du

                             List of roles  Role name |                         Attributes                          -----------+------------------------------------------------------------  alice     | Create role  bob       |  charlie   |  postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS

Подробнее о новых возможностях 16-й версии по управлению членством в ролях можно прочитать в предыдущих статьях:

Переименование параметра: io_direct -> debug_io_direct
commit: 319bae9a

Для отладочных целей в 16-й версии появился параметр io_direct. Чтобы название параметра не приводило к желанию его включить, параметр переименовали в debug_io_direct.

Удалены параметры: lc_collate и lc_ctype
commit: b0f6c437

Начиная с 15-й версии для базы данных в качестве провайдера локализации по умолчанию можно использовать библиотеку ICU. Информация о выбранном провайдере и локали сохраняется в столбцах pg_database.datlocprovider и pg_database.daticulocale.

Но, по ряду причин, настройки libc всё равно нужны в каждой базе данных. Поэтому в столбцах pg_database.datcollate и pg_database.datctype по-прежнему есть информация о локали libc, даже если для базы данных выбран провайдер ICU. А параметры lc_collate и lc_ctype всегда показывают именно настройки libc. Получается, что для корректного определения локали базы данных просто посмотреть значение lc_ctype или lc_collate недостаточно. Нужно дополнительно проверить значения столбцов datlocprovider и daticulocale.

Чтобы избежать ошибок в определении локали базы данных, параметры lc_collate и lc_ctype удалили. Информацию о локали следует смотреть в pg_database или командой \list в psql.

Документация: видимые в веб-интерфейсе ссылки на ранее скрытые элементы HTML
commit: e2922702

Некоторые страницы документации в формате HTML содержат якоря для секций или терминов внутри страниц. Например каждый параметр конфигурации в главе «Server Configuration» имеет свой якорь и на него можно ссылаться напрямую. Но как узнать точную ссылку без заглядывания в исходный код страницы?

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

Например, если на странице Client Connection Defaults навести мышь на название search_path, то справа появится знак # с прямой ссылкой на параметр:

https://www.postgresql.org/docs/16/runtime-config-client.html#GUC-SEARCH-PATH

Это очень удобно, когда нужно поделиться точной ссылкой.

Заметим, что на сайте postgrespro.ru подобный функционал давно работает для всех версий русскоязычной документации. Только вместо знака # с правой стороны появляется значок со скрепкой с левой стороны.

PostgreSQL 17

Переходим к 17-й версии. В этот обзор после первого коммитфеста попали следующие изменения:

Прогресс очистки индексов в pg_stat_progress_vacuum
Инкрементальная сортировка для индексов GiST и SP-GiST
Ограничения-исключения с секционированными таблицами
Логическая репликация: REPLICA IDENTITY FULL и hash-индексы
pg_archivecleanup: —clean-backup-history
Новый параметр huge_pages_status
Удален параметр db_user_namespace
События ожидания в расширениях
psql: вывод ECHO_HIDDEN обрамлен строками в виде комментариев

Прогресс очистки индексов в pg_stat_progress_vacuum
commit: 46ebdfe1, f1889729

В представлении pg_stat_progress_vacuum появились два новых столбца: indexes_total и indexes_processed. Первый показывает общее количество индексов для очистки, а второй — сколько индексов уже обработано. Информация обновляется во время выполнения фаз очистки, связанных с индексами: vacuuming indexes и cleaning up indexes.

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

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

Инкрементальная сортировка для индексов GiST и SP-GiST
commit: 625d5b3c

Инкрементальная сортировка появилась еще в 13-й версии. Но до сих пор она применялась только с индексами B-дерево. Теперь она работает с индексами GiST и SP-GiST.

Создадим индекс GiST в демонстрационной базе по координатам аэропортов:

CREATE INDEX ON airports_data USING gist (coordinates);

Найдем 10 рейсов из аэропортов, ближайших к заданной точке (для примера с нулевыми координатами), и отсортированные по дате вылета:

EXPLAIN (costs off) SELECT f.* FROM   flights f          JOIN airports a ON (f.departure_airport=a.airport_code) ORDER BY point(0,0) <-> a.coordinates, f.scheduled_departure LIMIT 10;

                                      QUERY PLAN                                       --------------------------------------------------------------------------------------  Limit    ->  Incremental Sort          Sort Key: (('(0,0)'::point <-> ml.coordinates)), f.scheduled_departure          Presorted Key: (('(0,0)'::point <-> ml.coordinates))          ->  Nested Loop                Join Filter: (ml.airport_code = f.departure_airport)                ->  Index Scan using airports_data_coordinates_idx on airports_data ml                      Order By: (coordinates <-> '(0,0)'::point)                ->  Materialize                      ->  Seq Scan on flights f (10 rows)

Результат запроса нам не интересен, а вот узел Incremental Sort с индексом GiST в плане запроса это то, что и хотелось увидеть.

Ограничения-исключения с секционированными таблицами
commit: 8c852ba9

Для секционированных таблиц появилась возможность создавать ограничения-исключения.

Создадим таблицу бронирования переговорных с секционированием по номеру комнаты:

CREATE TABLE booking(     room integer,     meeting_id integer,     during tstzrange NOT NULL,     CONSTRAINT bookings_pk PRIMARY KEY (room, meeting_id) ) PARTITION BY RANGE(room);  CREATE TABLE booking_1_10     PARTITION OF booking FOR VALUES FROM (1) TO (10); CREATE TABLE booking_11_20     PARTITION OF booking FOR VALUES FROM (11) TO (20);

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

CREATE EXTENSION btree_gist;  ALTER TABLE booking ADD CONSTRAINT no_intersect     EXCLUDE USING gist(room WITH =, during WITH &&);

Разные комнаты из разных секций можно бронировать на одно и тоже время:

INSERT INTO booking(room, meeting_id, during) VALUES     (1, 1, '[today 13:00,today 16:00)'::tstzrange),     (11, 1, '[today 13:00,today 16:00)'::tstzrange);

INSERT 0 2

Но нельзя забронировать одну и ту же комнату на пересекающиеся диапазоны времени:

INSERT INTO booking(room, meeting_id, during)     VALUES (1, 2, '[today 14:00,today 18:00)'::tstzrange);

ERROR:  conflicting key value violates exclusion constraint "booking_1_10_room_during_excl" DETAIL:  Key (room, during)=(1, ["2023-11-12 14:00:00+03","2023-11-12 18:00:00+03")) conflicts with existing key (room, during)=(1, ["2023-11-12 13:00:00+03","2023-11-12 16:00:00+03")).

[2023.11.12] Для корректной демонстрации работы ограничения-исключения в таблицу добавлен столбец meeting_id. Спасибо nvv за найденную неточность в примере.

Логическая репликация: REPLICA IDENTITY FULL и hash-индексы
commit: edca3424

Возможность использовать неуникальный индекс для идентификации измененных строк на подписчике появилась в 16-й версии. Но только для индексов типа B-дерево. В 17-й версии могут использоваться и индексы типа hash.

pg_archivecleanup: —clean-backup-history
commit: dd7c60f1, 4a7556f7, 3f8c98d0

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

Новый параметр huge_pages_status
commit: a14354ca

Новый параметр huge_pages_status показывает статус использования огромных страниц:

\dconfig huge*

List of configuration parameters      Parameter     | Value -------------------+-------  huge_pages        | try  huge_page_size    | 2MB  huge_pages_status | off (3 rows)

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

Удален параметр db_user_namespace
commit: 884eee5b

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

События ожидания в расширениях
commit: c9af0546

Разработчики расширений получили возможность определять собственные события ожидания. Сейчас все расширения используют один тип событий ожидания: Extension. Но если установлено несколько расширений, то из pg_stat_activity сложно понять, в каком именно расширении произошла задержка.

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

psql: вывод ECHO_HIDDEN обрамлен строками в виде комментариев
commit: 19c590f6

Включение ECHO_HIDDEN в командной строке или одноименной переменной приводит к выводу запросов SQL, используемых в командах psql:

$ psql --echo-hidden -c '\db';

/******** QUERY *********/ SELECT spcname AS "Name",   pg_catalog.pg_get_userbyid(spcowner) AS "Owner",   pg_catalog.pg_tablespace_location(oid) AS "Location" FROM pg_catalog.pg_tablespace ORDER BY 1; /************************/         List of tablespaces     Name    |  Owner   | Location ------------+----------+----------  pg_default | postgres |  pg_global  | postgres | (2 rows)

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

Такие же изменения сделаны для параметров —log-file и —single-step.


На этом всё. Ждем выхода PostgreSQL 16 и сентябрьского коммитфеста 17-й версии.


ссылка на оригинал статьи https://habr.com/ru/articles/757028/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *