|
| 1 | + |
| 2 | +:sectnums: |
| 3 | +:sectnumlevels: 5 |
| 4 | + |
| 5 | += pg_repack |
| 6 | + |
| 7 | +== Overview |
| 8 | +pg_repack is an extension for PostgreSQL used to *rebuild tables and indexes online and eliminate storage bloat*. It can achieve effects similar to `VACUUM FULL` and `CLUSTER` (reclaiming space, reordering physical layout by index), while *barely blocking business read/write operations*. pg_repack rebuilds a table by creating a new table rather than modifying it in place. Throughout the process, it only holds a brief exclusive lock at the very start and end; the rest of the time the table remains available for normal SELECT, INSERT, UPDATE, and DELETE operations. |
| 9 | + |
| 10 | +Both the PG mode and Oracle compatibility mode of IvorySQL have been adapted for pg_repack. Note that in Oracle compatibility mode, before compiling pg_repack, you need to manually modify the lib/pg_repack.control.in file in the extension source code to add a configuration item `pg_dialect = true`, otherwise the installation will fail. |
| 11 | + |
| 12 | +Github: <https://github.com/reorg/pg_repack> |
| 13 | + |
| 14 | +Documentation: <https://reorg.github.io/pg_repack/> |
| 15 | + |
| 16 | +License: BSD-3-Clause License |
| 17 | + |
| 18 | +== Principle |
| 19 | +`VACUUM FULL` / `CLUSTER` hold an `ACCESS EXCLUSIVE` lock on the entire table while rewriting it, during which reads and writes are not possible. pg_repack avoids long-duration table locking by means of "shadow table + triggers + file node swap". |
| 20 | + |
| 21 | +=== Shadow Table and Change Capture |
| 22 | +* Create a shadow table with the same structure as the original table (`repack.table_<oid>`), and bulk-copy the original table's data into it. |
| 23 | + |
| 24 | +* Install row-level triggers on the original table to record the `INSERT` / `UPDATE` / `DELETE` operations that occur during the rebuild into a log table (`repack.log_<oid>`). |
| 25 | + |
| 26 | +* After the data copy is complete, replay the log so that the shadow table catches up with the latest state of the original table. |
| 27 | + |
| 28 | +=== Swap and Cleanup |
| 29 | +* At the system catalog level, *swap the physical file nodes of the original table and the shadow table*. This step is instantaneous and only requires a brief exclusive lock. |
| 30 | + |
| 31 | +* Remove the triggers, log tables, and other temporary objects, and run `ANALYZE` on the new table. |
| 32 | + |
| 33 | +[NOTE] |
| 34 | +==== |
| 35 | +Prerequisites for use: the target table must have a *primary key or a non-null unique key*; the operation requires approximately *twice the table size* of temporary disk space during the process. |
| 36 | +==== |
| 37 | + |
| 38 | +== Installation and Enabling |
| 39 | +IvorySQL 5.0 or above is already installed in the environment. pg_repack consists of two parts: the server-side extension (`pg_repack.so` and SQL scripts) and the client-side command-line tool `pg_repack`. |
| 40 | + |
| 41 | +=== Source Code Installation |
| 42 | +* Set the PG_CONFIG environment variable |
| 43 | +[literal] |
| 44 | +---- |
| 45 | +export PG_CONFIG=/usr/local/ivorysql/bin/pg_config |
| 46 | +---- |
| 47 | + |
| 48 | +* Pull the pg_repack source code |
| 49 | +[literal] |
| 50 | +---- |
| 51 | +git clone --branch ver_1.5.3 https://github.com/reorg/pg_repack.git |
| 52 | +---- |
| 53 | + |
| 54 | +* Compile and install pg_repack |
| 55 | + |
| 56 | +To install pg_repack in IvorySQL's Oracle compatibility mode, you need to first modify the lib/pg_repack.control.in file of pg_repack to add the `pg_dialect` configuration item: |
| 57 | +[literal] |
| 58 | +---- |
| 59 | +# pg_repack/lib/pg_repack.control.in |
| 60 | +pg_dialect = true |
| 61 | +---- |
| 62 | + |
| 63 | +Perform compilation and installation: |
| 64 | +[literal] |
| 65 | +---- |
| 66 | +cd pg_repack |
| 67 | +sudo --preserve-env=PG_CONFIG make |
| 68 | +sudo --preserve-env=PG_CONFIG make install |
| 69 | +---- |
| 70 | + |
| 71 | +* Create the pg_repack extension |
| 72 | +[literal] |
| 73 | +---- |
| 74 | +[ivorysql@localhost ivorysql]$ psql |
| 75 | +psql (18.0) |
| 76 | +Type "help" for help. |
| 77 | +
|
| 78 | +ivorysql=# CREATE EXTENSION pg_repack; |
| 79 | +CREATE EXTENSION |
| 80 | +---- |
| 81 | + |
| 82 | +[NOTE] |
| 83 | +==== |
| 84 | +Note: `CREATE EXTENSION pg_repack` must be executed by a superuser; the client tool `pg_repack` also requires connecting and running as a superuser by default. After installation, the client tool is located at `/usr/local/ivorysql/bin/pg_repack`. |
| 85 | +==== |
| 86 | + |
| 87 | +== Usage |
| 88 | +pg_repack is driven through the command-line client. The connection parameters are the same as those of psql (`-h` host, `-p` port, `-U` user, `-d` database, or use the `PGHOST` / `PGPORT` / `PGUSER` environment variables). |
| 89 | + |
| 90 | +* Rebuild all eligible tables in the entire database |
| 91 | +[literal] |
| 92 | +---- |
| 93 | +pg_repack -d ivorysql |
| 94 | +---- |
| 95 | + |
| 96 | +* Rebuild a specified table (the schema.table form is recommended) |
| 97 | +[literal] |
| 98 | +---- |
| 99 | +pg_repack -d ivorysql -t public.big_table |
| 100 | +---- |
| 101 | + |
| 102 | +* Rebuild indexes only |
| 103 | +[literal] |
| 104 | +---- |
| 105 | +pg_repack -d ivorysql -t big_table --only-indexes # rebuild all indexes of this table |
| 106 | +pg_repack -d ivorysql -i public.big_table_idx # rebuild a single index |
| 107 | +---- |
| 108 | + |
| 109 | +* Rebuild ordered by a specified column (online CLUSTER effect) |
| 110 | +[literal] |
| 111 | +---- |
| 112 | +pg_repack -d ivorysql -t big_table -o "created_at DESC" |
| 113 | +---- |
| 114 | + |
| 115 | +* Migrate a table and its indexes to another tablespace |
| 116 | +[literal] |
| 117 | +---- |
| 118 | +pg_repack -d ivorysql -t big_table -s fast_ssd_ts --moveidx |
| 119 | +---- |
| 120 | + |
| 121 | +* Dry-run mode (only shows the actions that would be performed, without actually rebuilding) |
| 122 | +[literal] |
| 123 | +---- |
| 124 | +pg_repack -d ivorysql -t big_table --dry-run |
| 125 | +---- |
0 commit comments