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-10-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 Standard и использовать эти дополнительные подключения для перестраивания индексов таблиц в параллельном режиме. Параллельное перестроение индексов поддерживается только при реорганизации таблиц полностью, без ключей - --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 (см. Раздел 31.14).
Примеры
Выполнение неблокирующей кластеризации (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_triggerONтаблица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 выдаст ошибку и отменит свои изменения корректно, но с этими старыми версиями в некоторых случаях было возможно разрушение данных.