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 TRIGGERzzz_my_trigger
ONтаблица
RENAME TOyyy_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 выдаст ошибку и отменит свои изменения корректно, но с этими старыми версиями в некоторых случаях было возможно разрушение данных.