pg_repack

pg_repack — утилита и расширение Postgres Pro Standard для реорганизации таблиц

Синтаксис

pg_repack [параметр...] [имя_бд]

Описание

Модуль pg_repack — это расширение Postgres Pro Standard, которое позволяет ликвидировать раздувание таблиц и индексов и может дополнительно восстанавливать физический порядок кластеризованных индексов. В отличие от CLUSTER и VACUUM FULL, оно выполняет эти операции «на ходу», обходясь без исключительных блокировок таблиц в ходе их обработки. К тому же pg_repack действует эффективно, демонстрируя производительность, сравнимую с непосредственным использованием CLUSTER.

pg_repack — это альтернативная ветвь развития проекта https://github.com/reorg/pg_reorg.

Вы можете выбрать один из следующих способов реорганизации данных:

  • Неблокирующая кластеризация (CLUSTER) (с упорядочиванием по кластеризующему индексу)

  • Упорядочивание по указанным столбцам

  • Неблокирующая полная очистка (VACUUM FULL) (только упаковка строк)

  • Перестроение или перемещение только индексов таблицы

Примечание

Использовать эту утилиту могут только суперпользователи.

Примечание

В целевой таблице должен быть первичный ключ (PRIMARY KEY) или как минимум уникальный индекс по столбцу NOT NULL.

Установка

Для систем Linux pg_repack поставляется с Postgres Pro в виде отдельного пакета, который требует, чтобы был установлен пакет postgrespro-std-14-server со всеми зависимостями. Список предоставляемых пакетов и подробное описание установки можно найти в Главе 16. В системах Windows pg_repack устанавливается автоматически в составе Postgres Pro.

Установив pg_repack, загрузите расширение pg_repack в базу данных, которую вы хотите обрабатывать, следующим образом:

$ psql -c "CREATE EXTENSION pg_repack" -d ваша_база

Впоследствии вы можете удалить pg_repack из инсталляции Postgres Pro, выполнив DROP EXTENSION pg_repack.

Чтобы обновить ранее установленную версию pg_repack, просто удалите из базы данных старую версию, как описано выше, и установите новую.

Параметры

Параметры реорганизации

-a
--all

Попытаться перепаковать все базы данных в кластере. Базы данных, в которых расширение pg_repack не установлено, будут пропущены.

-t таблица
--table=таблица

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

-c схема
--schema=схема

Перепаковать таблицы только в указанной схеме (схемах). Перепаковать несколько схем можно, добавив несколько ключей -c. Можно использовать в сочетании с --tablespace для перемещения таблиц в другое табличное пространство.

-o столбец[, ...]
--order-by=столбец[, ...]

Выполнить неблокирующую кластеризацию (CLUSTER), упорядочивая данные по указанным столбцам.

-n
--no-order

Выполнить неблокирующую полную очистку (VACUUM FULL). Начиная с версии 1.2, это производится по умолчанию для некластеризованных таблиц.

-N
--dry-run

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

-j num_jobs
--jobs=num_jobs

Установить заданное количество дополнительных соединений к Postgres Pro и использовать эти дополнительные подключения для перестраивания индексов таблиц в параллельном режиме. Параллельное перестроение индексов поддерживается только при реорганизации таблиц полностью, без ключей --index или --only-indexes. Если ваш сервер имеет несколько процессорных ядер и быструю дисковую подсистему, параллельный режим может быть полезен для ускорения pg_repack.

-s табличное_пространство
--tablespace=табличное_пространство

Перенести перепакованные таблицы в заданное табличное пространство: по сути это неблокирующая версия команды ALTER TABLE ... SET TABLESPACE. Индексы таблиц остаются в исходном табличном пространстве, если только дополнительно не указан ключ --moveidx.

-S
--moveidx

Также перенести индексы перепакованных таблиц в табличное пространство, заданное ключом --tablespace.

-i индекс
--index=индекс

Перепаковать только указанный индекс. Перепаковать несколько индексов можно, добавив несколько ключей -i. Можно использовать в сочетании с --tablespace для перемещения индексов в другое табличное пространство.

-x
--only-indexes

Перепаковать только индексы таблиц, заданных ключами --table.

-T сек
--wait-timeout=сек

Расширению pg_repack необходимо получить исключительную блокировку в конце реорганизации. Этот параметр определяет, сколько секунд pg_repack будет ждать получения этой блокировки. Если за это время блокировка не будет получена, pg_repack принудительно отменит конфликтующие запросы. Если же вы используете Postgres Pro или PostgreSQL версии 8.4 и новее, pg_repack прибегнет к вызову pg_terminate_backend(), чтобы отключить все оставшиеся фоновые процессы, после того, как это время истечёт дважды. Значение по умолчанию: 60 сек.

-Z
--no-analyze

Не выполнять ANALYZE после полной реорганизации таблицы. В отсутствие этого ключа после реорганизации ANALYZE выполняется.

Параметры подключения

[-d] имя_бд
[--dbname=]имя_бд

Указывает имя базы данных для реорганизации. Если оно не указано, и параметр -a (или --all) не используется, то имя базы берётся из переменной окружения PGDATABASE. Если и эта переменная не задана, выбирается имя подключающегося пользователя.

-h сервер
--host=сервер

Указывает имя компьютера, на котором работает сервер. Если значение начинается с косой черты, оно определяет каталог Unix-сокета.

-p порт
--port=порт

Указывает TCP-порт или расширение файла локального Unix-сокета, через который сервер принимает подключения.

-U имя_пользователя
--username=имя_пользователя

Имя пользователя для подключения.

-w
--no-password

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

-W
--password

Принудительно запрашивать пароль перед подключением к базе данных.

Это несущественный параметр, так как pg_repack запрашивает пароль автоматически, если сервер проверяет подлинность по паролю. Однако чтобы понять это, pg_repack лишний раз подключается к серверу. Поэтому иногда имеет смысл ввести -W, чтобы исключить эту ненужную попытку подключения.

Общие параметры

-e
--echo

Выводить команды, которые pg_repack формирует и передаёт на сервер.

-E уровень
--elevel=уровень

Устанавливает уровень выводимых сообщений: DEBUG, INFO, NOTICE, WARNING, ERROR, LOG, FATAL и PANIC. Уровень по умолчанию: INFO.

--help

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

-V
--version

Вывести версию pg_repack и завершиться.

Переменные окружения

PGDATABASE
PGHOST
PGPORT
PGUSER

Параметры подключения по умолчанию

Эта утилита, как и большинство других утилит Postgres Pro, также использует переменные среды, поддерживаемые libpq (см. Раздел 32.15).

Примеры

Выполнение неблокирующей кластеризации (CLUSTER) всех кластеризованных таблиц и полной очистки (VACUUM FULL) всех некластеризованных таблиц в базе данных test:

$ pg_repack test

Выполнение неблокирующей полной очистки (VACUUM FULL) в таблицах foo и bar в базе данных test (кластерные индексы, если они есть, игнорируются):

$ pg_repack --no-order --table foo --table bar test

Перемещение всех индексов таблицы foo в табличное пространство tbs:

$ pg_repack -d test --table foo --only-indexes --tablespace tbs

Перемещение указанного индекса в табличное пространство tbs:

$ pg_repack -d test --index idx --tablespace tbs

Диагностика

В случае ошибок pg_repack выдаёт соответствующие сообщения. В следующем списке поясняются причины ряда ошибок.

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

Для Postgres Pro или PostgreSQL версии 9.1 и новее выполните:

DROP EXTENSION pg_repack CASCADE

в базе данных, где произошла ошибка. Затем выполните:

CREATE EXTENSION pg_repack

Для предыдущих версий загрузите скрипт $SHAREDIR/contrib/uninstall_pg_repack.sql в базу данных, где произошла ошибка, а затем повторно загрузите $SHAREDIR/contrib/pg_repack.sql.


INFO: database "db" skipped:
pg_repack VER is not installed in the database:
pg_repack is not installed in the database when the --all option is specified.

Создайте расширение pg_repack в базе данных.


ERROR: pg_repack VER is not installed in the database:
pg_repack is not installed in the database specified by --dbname

Создайте расширение pg_repack в базе данных.


ERROR: program 'pg_repack V1' does not match database library 'pg_repack V2':
There is a mismatch between the pg_repack binary and the database library
(.so or .dll).

Обнаруженное несоответствие версий может быть связано с нахождением некорректной программы в переменной PATH или обращением к неправильной базе данных. Проверьте корректность каталога программы и базы данных; если всё верно, возможно, вам придётся переустановить pg_repack.


ERROR: extension 'pg_repack V1' required, found 'pg_repack V2':
The SQL extension found in the database does not match the version required by the pg_repack program.

Столкнувшись с такой ошибкой, удалите расширение из базы данных и пересоздайте его, как описано в Разделе «Установка».


ERROR: relation "table" must have a primary key or not-null unique keys:
The target table doesn't have a PRIMARY KEY or any UNIQUE constraints defined.

Создайте в указанной таблице ограничение PRIMARY KEY или UNIQUE.


ERROR: query failed: ERROR: column "col" does not exist:
The target table doesn't have columns specified by --order-by option.

Укажите существующие столбцы.


WARNING: the table "tbl" already has a trigger called z_repack_trigger:
The trigger was probably installed during a previous attempt
to run pg_repack on the table which was interrupted
and for some reason failed to clean up the temporary objects.

Вы можете ликвидировать все временные объекты, удалив и создав расширение заново: это описано подробно в Разделе «Установка».


WARNING: trigger "trg" conflicting on table "tbl":
The target table has a trigger whose name follows z_repack_trigger
in alphabetical order.

Триггер z_repack_trigger должен быть последним триггером в наборе BEFORE. Переименуйте свой триггер, чтобы он шёл в алфавитном порядке перед pg_repack; это можно сделать командой:

ALTER TRIGGER zzz_my_trigger
 ON таблица RENAME TO yyy_my_trigger;

ERROR: Another pg_repack command may be running on the table. Please try again later.

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


WARNING: Cannot create index "schema"."index_xxxxx", already exists
DETAIL: An invalid index may have been left behind by a previous
pg_repack on the table which was interrupted. Please use DROP INDEX
"schema"."index_xxxxx" to remove this index and try again.

Похоже, что в базе данных остался временный индекс, созданный программой pg_repack, но он не удаляется автоматически во избежание недоразумений. Если этот индекс действительно был создан старым заданием pg_repack и по какой-то причине не удалился, вы можете просто выполнить DROP INDEX и повторить команду repack ещё раз.

Ограничения

pg_repack имеет следующие ограничения.

Временные таблицы

pg_repack не может реорганизовывать временные таблицы.

Индексы GiST

pg_repack не может кластеризовать таблицу согласно индексу GiST.

Команды DDL

Пока работает pg_repack, нельзя выполнять команды DDL с целевыми таблицами, за исключением VACUUM и ANALYZE. Для реализации этого ограничения pg_repack устанавливает блокировку ACCESS SHARE в целевой таблице на время реорганизации таблицы.

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

См. также

clusterdb, vacuumdb