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 Standard в виде отдельного пакета pg-repack-std-16, который требует, чтобы был установлен пакет postgrespro-std-16-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. По умолчанию реорганизуются все подходящие таблицы в целевых базах данных.-Iтаблица--parent-table=таблицаРеорганизовать как указанную таблицу (таблицы), так и дочерние. Реорганизовать несколько иерархий таблиц можно, добавив несколько ключей
-I.-cсхема--schema=схемаПерепаковать таблицы только в указанной схеме (схемах). Перепаковать несколько схем можно, добавив несколько ключей
-c. Можно использовать в сочетании с--tablespaceдля перемещения таблиц в другое табличное пространство.-oстолбец[, ...]--order-by=столбец[, ...]Выполнить неблокирующую кластеризацию (
CLUSTER), упорядочивая данные по указанным столбцам.-n--no-orderВыполнить неблокирующую полную очистку (
VACUUM FULL). Начиная с версии 1.2, это производится по умолчанию для некластеризованных таблиц.-N--dry-runТолько показать, какие таблицы будут перепакованы, и завершиться.
-jnum_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 будет ждать получения этой блокировки. Если за это время блокировка не будет получена и параметр
--no-kill-backendне указан, pg_repack принудительно отменит конфликтующие запросы. Если же вы используете Postgres Pro или PostgreSQL версии 8.4 и новее, pg_repack прибегнет к вызовуpg_terminate_backend(), чтобы отключить все оставшиеся фоновые процессы, после того, как это время истечёт дважды. Значение по умолчанию: 60 сек.-D--no-kill-backendПропускать перепаковку таблицы вместо отмены конфликтующих запросов, если блокировка не может быть получена в течение времени, указанного в
--wait-timeout. Значение по умолчанию —false.-Z--no-analyzeНе выполнять
ANALYZEпосле полной реорганизации таблицы. В отсутствие этого ключа после реорганизацииANALYZEвыполняется.-k--no-superuser-checkПропускать проверку суперпользователя клиентом. Этот параметр полезен при использовании pg_repack на платформах, которые поддерживают запуск расширения не от имени суперпользователя.
-C--exclude-extensionПропускать таблицы, которые принадлежат указанному расширению (расширениям). Время планирования некоторых расширений может сильно зависеть от таких таблиц.
--switch-thresholdПереключать таблицы, когда в таблице журнала остаётся заданное число кортежей. Этот параметр можно использовать, чтобы иметь возможность нагнать таблицы с большим объёмом записи.
Параметры подключения
Параметры подключения к серверам. Параметр --all нельзя использовать вместе с --dbname, --table или --parent-table.
-a--allРеорганизовать все базы данных.
[-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 и завершиться.
Переменные окружения
PGDATABASEPGHOSTPGPORTPGUSERПараметры подключения по умолчанию
Эта утилита, как и большинство других утилит Postgres Pro, также использует переменные среды, поддерживаемые libpq (см. Раздел 33.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_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 выдаст ошибку и отменит свои изменения корректно, но с этими старыми версиями в некоторых случаях было возможно разрушение данных.
pg_repack
pg_repack — utility and Postgres Pro Standard extension to reorganize tables
Synopsis
pg_repack [option...] [dbname]
Description
pg_repack is a Postgres Pro Standard extension which lets you remove bloat from tables and indexes, and optionally restore the physical order of clustered indexes. Unlike CLUSTER and VACUUM FULL it works online, without holding an exclusive lock on the processed tables during processing. pg_repack is efficient to boot, with performance comparable to using CLUSTER directly.
pg_repack is a fork of the previous https://github.com/reorg/pg_reorg project.
You can choose one of the following methods to reorganize data:
Online
CLUSTER(ordered by cluster index)Ordering by specified columns
Online
VACUUM FULL(packing rows only)Rebuild or relocate only the indexes of a table
Note
Only superusers can use the utility.
Note
Target table must have a PRIMARY KEY, or at least a UNIQUE total index on a NOT NULL column.
Installation #
On Linux systems, pg_repack is provided together with Postgres Pro Standard as a separate pre-built package pg-repack-std-16 and requires the postgrespro-std-16-server package to be installed with all the dependencies. For the list of available packages and detailed installation instructions, see Chapter 16. On Windows systems, pg_repack is automatically installed as part of Postgres Pro.
Once you have pg_repack installed, load the pg_repack extension in the database you want to process, as follows:
$ psql -c "CREATE EXTENSION pg_repack" -d your_database
You can later remove pg_repack from a Postgres Pro installation using DROP EXTENSION pg_repack.
If you are upgrading from a previous version of pg_repack, just drop the old version from the database as explained above and install the new version.
Options
Reorganization Options
-a--allAttempt to repack all the databases of the cluster. Databases where the
pg_repackextension is not installed will be skipped.-ttable--table=tableReorganize the specified table(s) only. Multiple tables may be reorganized by writing multiple
-tswitches. By default, all eligible tables in the target databases are reorganized.-Itable--parent-table=tableReorganize both the specified table(s) and its inheritors. Multiple table hierarchies may be reorganized by writing multiple
-Iswitches.-cschema--schema=schemaRepack the tables in the specified schema(s) only. Multiple schemas may be repacked by writing multiple
-cswitches. Can be used in conjunction with--tablespaceto move tables to a different tablespace.-ocolumn[, ...]--order-by=column[, ...]Perform an online
CLUSTERordered by the specified columns.-n--no-orderPerform an online
VACUUM FULL. Since version 1.2 this is the default for non-clustered tables.-N--dry-runShow what would be repacked and exit.
-jnum_jobs--jobs=num_jobsCreate the specified number of extra connections to Postgres Pro, and use these extra connections to parallelize the rebuild of indexes on each table. Parallel index builds are only supported for full-table repacks, not with
--indexor--only-indexesoptions. If your server has extra cores and disk I/O available, this can be a useful way to speed up pg_repack.-stablespace--tablespace=tablespaceMove the repacked tables to the specified tablespace: essentially an online version of
ALTER TABLE ... SET TABLESPACE. The tables' indexes are left in the original tablespace unless--moveidxis specified too.-S--moveidxAlso move the indexes of the repacked tables to the tablespace specified by the
--tablespaceoption.-iindex--index=indexRepack the specified index(es) only. Multiple indexes may be repacked by writing multiple
-iswitches. May be used in conjunction with--tablespaceto move the index(es) to a different tablespace.-x--only-indexesRepack only the indexes of the specified table(s), which must be specified with the
--tableoption.-Tsecs--wait-timeout=secspg_repack needs to take an exclusive lock at the end of the reorganization. This setting controls how many seconds pg_repack will wait to acquire this lock. If the lock cannot be taken after this duration and
--no-kill-backendoption is not specified, pg_repack will forcibly cancel the conflicting queries. If you are using Postgres Pro or PostgreSQL version 8.4 or newer, pg_repack will fall back to usingpg_terminate_backend()to disconnect any remaining backends after this timeout has passed twice. The default is 60 seconds.-D--no-kill-backendSkip repacking a table if the lock cannot be taken for duration specified in
--wait-timeout, instead of cancelling conflicting queries. The default isfalse.-Z--no-analyzeDisable
ANALYZEafter a full-table reorganization. If not specified,ANALYZEis executed after the reorganization.-k--no-superuser-checkSkip the superuser checks in the client. This setting is useful for using pg_repack on platforms that support running it as non-superusers.
-C--exclude-extensionSkip tables that belong to the specified extension(s). Some extensions may heavily depend on such tables at planning time etc.
--switch-thresholdSwitch tables when that many tuples are left in the log table. This setting can be used to avoid the inability to catch up with write-heavy tables.
Connection Options
Options to connect to servers. You cannot use --all and --dbname or --table or --parent-table together.
-a--allReorganize all databases.
[-d]dbname[--dbname=]dbnameSpecifies the name of the database to be reorganized. If this is not specified and
-a(or--all) is not used, the database name is read from the environment variablePGDATABASE. If that is not set, the user name specified for the connection is used.-hhost--host=hostSpecifies the host name of the machine on which the server is running. If the value begins with a slash, it is used as the directory for the Unix domain socket.
-pport--port=portSpecifies the TCP port or local Unix domain socket file extension on which the server is listening for connections.
-Uusername--username=usernameUser name to connect as.
-w--no-passwordNever issue a password prompt. If the server requires password authentication and a password is not available by other means such as a
.pgpassfile, the connection attempt will fail. This option can be useful in batch jobs and scripts where no user is present to enter a password.-W--passwordForce pg_repack to prompt for a password before connecting to a database.
This option is never essential, since pg_repack will automatically prompt for a password if the server demands password authentication. However, pg_repack will waste a connection attempt finding out that the server wants a password. In some cases it is worth typing
-Wto avoid the extra connection attempt.
Generic Options
-e--echoEcho the commands that pg_repack generates and sends to the server.
-Elevel--elevel=levelChoose the output message level from
DEBUG,INFO,NOTICE,WARNING,ERROR,LOG,FATAL, andPANIC. The default isINFO.--helpShow help about pg_repack command line arguments, and exit.
-V--versionPrint the pg_repack version and exit.
Environment
PGDATABASEPGHOSTPGPORTPGUSERDefault connection parameters
This utility, like most other Postgres Pro utilities, also uses the environment variables supported by libpq (see Section 33.15).
Examples
Perform an online CLUSTER of all the clustered tables in the database test, and perform an online VACUUM FULL of all the non-clustered tables:
$ pg_repack test
Perform an online VACUUM FULL on the tables foo and bar in the database test (an eventual cluster index is ignored):
$ pg_repack --no-order --table foo --table bar test
Move all indexes of table foo to tablespace tbs:
$ pg_repack -d test --table foo --only-indexes --tablespace tbs
Move the specified index to tablespace tbs:
$ pg_repack -d test --index idx --tablespace tbs
Diagnostics
Error messages are reported when pg_repack fails. The following list shows the cause of errors.
You need to cleanup by hand after fatal errors. To cleanup, just remove pg_repack from the database and install it again.
For Postgres Pro or PostgreSQL 9.1 and newer execute:
DROP EXTENSION pg_repack CASCADE
in the database where the error occurred, followed by
CREATE EXTENSION pg_repack
For previous versions load the script $SHAREDIR/contrib/uninstall_pg_repack.sql into the database where the error occurred and then load $SHAREDIR/contrib/pg_repack.sql again.
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.
Create the pg_repack extension in the database.
ERROR: pg_repack VER is not installed in the database:
pg_repack is not installed in the database specified by --dbname
Create the pg_repack extension in the database.
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).
The mismatch could be due to the wrong binary in the PATH or the wrong database being addressed. Check the program directory and the database; if they are what expected you may need to repeat pg_repack installation.
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.
You should drop the extension from the database and reload it as described in the section called “Installation”.
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.
Define a PRIMARY KEY or a UNIQUE constraint on the table.
ERROR: query failed: ERROR: column "col" does not exist:
The target table doesn't have columns specified by --order-by option.
Specify existing columns.
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.
You can remove all the temporary objects by dropping and re-creating the extension: see the section called “Installation” for the details.
WARNING: trigger "trg" conflicting on table "tbl":
The target table has a trigger whose name follows z_repack_trigger
in alphabetical order.
The z_repack_trigger should be the last BEFORE trigger to fire. Please rename your trigger so that it sorts alphabetically before pg_repack one; you can use:
ALTER TRIGGERzzz_my_triggerONsometableRENAME TOyyy_my_trigger;
ERROR: Another pg_repack command may be running on the table. Please try again later.
There is a chance of deadlock when two concurrent pg_repack commands are run on the same table. So, try to run the command after some time.
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.
A temporary index apparently created by pg_repack has been left behind, and we do not want to risk dropping this index ourselves. If the index was in fact created by an old pg_repack job which didn't get cleaned up, you should just use DROP INDEX and try the repack command again.
Restrictions
pg_repack comes with the following restrictions.
- Temporary tables
pg_repack cannot reorganize temporary tables.
- GiST indexes
pg_repack cannot cluster tables by
GiSTindexes.- DDL commands
You will not be able to perform DDL commands of the target table(s) except
VACUUMorANALYZEwhile pg_repack is working. pg_repack will hold anACCESS SHARElock on the target table during a full-table repack, to enforce this restriction.If you are using version 1.1.8 or earlier, you must not attempt to perform any DDL commands on the target table(s) while pg_repack is running. In many cases pg_repack would fail and rollback correctly, but there were some cases in these earlier versions which could result in data corruption.