Skip to content

Commit 999b854

Browse files
authored
Flag for stopping repack when invalid index is found (#336)
* Added a CLI flag for failing immediately on incorrect index By default, we treat incorrect index as a warning. It may lead to index corruption. Corruption happens when repacking is interrupted, then some data written, and then repack is done fully. When --error-on-incorrect-index flag is used, second repack will fail, so no indexes will be corrupted. * Added regression test for --error-on-invalid-index flag * Added --error-on-invalid-index flag info to README
1 parent edf1a9c commit 999b854

File tree

7 files changed

+106
-56
lines changed

7 files changed

+106
-56
lines changed

bin/pg_repack.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ static unsigned int temp_obj_num = 0; /* temporary objects counter */
256256
static bool no_kill_backend = false; /* abandon when timed-out */
257257
static bool no_superuser_check = false;
258258
static SimpleStringList exclude_extension_list = {NULL, NULL}; /* don't repack tables of these extensions */
259+
static bool error_on_invalid_index = false; /* don't repack when invalid index is found */
259260

260261
/* buffer should have at least 11 bytes */
261262
static char *
@@ -285,6 +286,7 @@ static pgut_option options[] =
285286
{ 'b', 'D', "no-kill-backend", &no_kill_backend },
286287
{ 'b', 'k', "no-superuser-check", &no_superuser_check },
287288
{ 'l', 'C', "exclude-extension", &exclude_extension_list },
289+
{ 'b', 'F', "error-on-invalid-index", &error_on_invalid_index },
288290
{ 0 },
289291
};
290292

@@ -1310,7 +1312,8 @@ repack_one_table(repack_table *table, const char *orderby)
13101312
indexparams[1] = moveidx ? tablespace : NULL;
13111313

13121314
/* First, just display a warning message for any invalid indexes
1313-
* which may be on the table (mostly to match the behavior of 1.1.8).
1315+
* which may be on the table (mostly to match the behavior of 1.1.8),
1316+
* if --error-on-invalid-index is not set
13141317
*/
13151318
indexres = execute(
13161319
"SELECT pg_get_indexdef(indexrelid)"
@@ -1321,7 +1324,12 @@ repack_one_table(repack_table *table, const char *orderby)
13211324
{
13221325
const char *indexdef;
13231326
indexdef = getstr(indexres, j, 0);
1324-
elog(WARNING, "skipping invalid index: %s", indexdef);
1327+
if (error_on_invalid_index) {
1328+
elog(WARNING, "Invalid index: %s", indexdef);
1329+
goto cleanup;
1330+
} else {
1331+
elog(WARNING, "skipping invalid index: %s", indexdef);
1332+
}
13251333
}
13261334

13271335
indexres = execute(

doc/pg_repack.rst

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -106,37 +106,38 @@ Usage
106106
The following options can be specified in ``OPTIONS``.
107107

108108
Options:
109-
-a, --all repack all databases
110-
-t, --table=TABLE repack specific table only
111-
-I, --parent-table=TABLE repack specific parent table and its inheritors
112-
-c, --schema=SCHEMA repack tables in specific schema only
113-
-s, --tablespace=TBLSPC move repacked tables to a new tablespace
114-
-S, --moveidx move repacked indexes to *TBLSPC* too
115-
-o, --order-by=COLUMNS order by columns instead of cluster keys
116-
-n, --no-order do vacuum full instead of cluster
117-
-N, --dry-run print what would have been repacked and exit
118-
-j, --jobs=NUM Use this many parallel jobs for each table
119-
-i, --index=INDEX move only the specified index
120-
-x, --only-indexes move only indexes of the specified table
121-
-T, --wait-timeout=SECS timeout to cancel other backends on conflict
122-
-D, --no-kill-backend don't kill other backends when timed out
123-
-Z, --no-analyze don't analyze at end
124-
-k, --no-superuser-check skip superuser checks in client
125-
-C, --exclude-extension don't repack tables which belong to specific extension
109+
-a, --all repack all databases
110+
-t, --table=TABLE repack specific table only
111+
-I, --parent-table=TABLE repack specific parent table and its inheritors
112+
-c, --schema=SCHEMA repack tables in specific schema only
113+
-s, --tablespace=TBLSPC move repacked tables to a new tablespace
114+
-S, --moveidx move repacked indexes to *TBLSPC* too
115+
-o, --order-by=COLUMNS order by columns instead of cluster keys
116+
-n, --no-order do vacuum full instead of cluster
117+
-N, --dry-run print what would have been repacked and exit
118+
-j, --jobs=NUM Use this many parallel jobs for each table
119+
-i, --index=INDEX move only the specified index
120+
-x, --only-indexes move only indexes of the specified table
121+
-T, --wait-timeout=SECS timeout to cancel other backends on conflict
122+
-D, --no-kill-backend don't kill other backends when timed out
123+
-Z, --no-analyze don't analyze at end
124+
-k, --no-superuser-check skip superuser checks in client
125+
-C, --exclude-extension don't repack tables which belong to specific extension
126+
-F, --error-on-invalid-index don't repack when invalid index is found
126127

127128
Connection options:
128-
-d, --dbname=DBNAME database to connect
129-
-h, --host=HOSTNAME database server host or socket directory
130-
-p, --port=PORT database server port
131-
-U, --username=USERNAME user name to connect as
132-
-w, --no-password never prompt for password
133-
-W, --password force password prompt
129+
-d, --dbname=DBNAME database to connect
130+
-h, --host=HOSTNAME database server host or socket directory
131+
-p, --port=PORT database server port
132+
-U, --username=USERNAME user name to connect as
133+
-w, --no-password never prompt for password
134+
-W, --password force password prompt
134135

135136
Generic options:
136-
-e, --echo echo queries
137-
-E, --elevel=LEVEL set output message level
138-
--help show this help, then exit
139-
--version output version information, then exit
137+
-e, --echo echo queries
138+
-E, --elevel=LEVEL set output message level
139+
--help show this help, then exit
140+
--version output version information, then exit
140141

141142

142143
Reorg Options

doc/pg_repack_jp.rst

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -194,36 +194,38 @@ pg_repackもしくはpg_reorgの古いバージョンからのアップグレー
194194
The following options can be specified in ``OPTIONS``.
195195
196196
Options:
197-
-a, --all repack all databases
198-
-t, --table=TABLE repack specific table only
199-
-I, --parent-table=TABLE repack specific parent table and its inheritors
200-
-c, --schema=SCHEMA repack tables in specific schema only
201-
-s, --tablespace=TBLSPC move repacked tables to a new tablespace
202-
-S, --moveidx move repacked indexes to *TBLSPC* too
203-
-o, --order-by=COLUMNS order by columns instead of cluster keys
204-
-n, --no-order do vacuum full instead of cluster
205-
-N, --dry-run print what would have been repacked and exit
206-
-j, --jobs=NUM Use this many parallel jobs for each table
207-
-i, --index=INDEX move only the specified index
208-
-x, --only-indexes move only indexes of the specified table
209-
-T, --wait-timeout=SECS timeout to cancel other backends on conflict
210-
-D, --no-kill-backend don't kill other backends when timed out
211-
-Z, --no-analyze don't analyze at end
212-
-k, --no-superuser-check skip superuser checks in client
197+
-a, --all repack all databases
198+
-t, --table=TABLE repack specific table only
199+
-I, --parent-table=TABLE repack specific parent table and its inheritors
200+
-c, --schema=SCHEMA repack tables in specific schema only
201+
-s, --tablespace=TBLSPC move repacked tables to a new tablespace
202+
-S, --moveidx move repacked indexes to *TBLSPC* too
203+
-o, --order-by=COLUMNS order by columns instead of cluster keys
204+
-n, --no-order do vacuum full instead of cluster
205+
-N, --dry-run print what would have been repacked and exit
206+
-j, --jobs=NUM Use this many parallel jobs for each table
207+
-i, --index=INDEX move only the specified index
208+
-x, --only-indexes move only indexes of the specified table
209+
-T, --wait-timeout=SECS timeout to cancel other backends on conflict
210+
-D, --no-kill-backend don't kill other backends when timed out
211+
-Z, --no-analyze don't analyze at end
212+
-k, --no-superuser-check skip superuser checks in client
213+
-C, --exclude-extension don't repack tables which belong to specific extension
214+
-F, --error-on-invalid-index don't repack when invalid index is found
213215
214216
Connection options:
215-
-d, --dbname=DBNAME database to connect
216-
-h, --host=HOSTNAME database server host or socket directory
217-
-p, --port=PORT database server port
218-
-U, --username=USERNAME user name to connect as
219-
-w, --no-password never prompt for password
220-
-W, --password force password prompt
217+
-d, --dbname=DBNAME database to connect
218+
-h, --host=HOSTNAME database server host or socket directory
219+
-p, --port=PORT database server port
220+
-U, --username=USERNAME user name to connect as
221+
-w, --no-password never prompt for password
222+
-W, --password force password prompt
221223
222224
Generic options:
223-
-e, --echo echo queries
224-
-E, --elevel=LEVEL set output message level
225-
--help show this help, then exit
226-
--version output version information, then exit
225+
-e, --echo echo queries
226+
-E, --elevel=LEVEL set output message level
227+
--help show this help, then exit
228+
--version output version information, then exit
227229
228230
利用方法
229231
---------

regress/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ INTVERSION := $(shell echo $$(($$(echo $(VERSION).0 | sed 's/\([[:digit:]]\{1,\}
1717
# Test suite
1818
#
1919

20-
REGRESS := init-extension repack-setup repack-run after-schema repack-check nosuper tablespace get_order_by
20+
REGRESS := init-extension repack-setup repack-run error-on-invalid-idx after-schema repack-check nosuper tablespace get_order_by
2121

2222
USE_PGXS = 1 # use pgxs if not in contrib directory
2323
PGXS := $(shell $(PG_CONFIG) --pgxs)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--
2+
-- do repack
3+
--
4+
\! pg_repack --dbname=contrib_regression --table=tbl_cluster --error-on-invalid-index
5+
INFO: repacking table "public.tbl_cluster"
6+
\! pg_repack --dbname=contrib_regression --table=tbl_badindex --error-on-invalid-index
7+
INFO: repacking table "public.tbl_badindex"
8+
WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n)
9+
\! pg_repack --dbname=contrib_regression --error-on-invalid-index
10+
INFO: repacking table "public.tbl_badindex"
11+
WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n)
12+
INFO: repacking table "public.tbl_cluster"
13+
INFO: repacking table "public.tbl_gistkey"
14+
INFO: repacking table "public.tbl_idxopts"
15+
INFO: repacking table "public.tbl_only_pkey"
16+
INFO: repacking table "public.tbl_order"
17+
INFO: repacking table "public.tbl_storage_plain"
18+
INFO: repacking table "public.tbl_with_dropped_column"
19+
INFO: repacking table "public.tbl_with_dropped_toast"
20+
INFO: repacking table "public.tbl_with_mod_column_storage"
21+
INFO: repacking table "public.tbl_with_toast"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--
2+
-- do repack
3+
--
4+
\! pg_repack --dbname=contrib_regression --table=tbl_cluster --error-on-invalid-index
5+
INFO: repacking table "public.tbl_cluster"
6+
\! pg_repack --dbname=contrib_regression --table=tbl_badindex --error-on-invalid-index
7+
INFO: repacking table "public.tbl_badindex"
8+
WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n)
9+
\! pg_repack --dbname=contrib_regression --error-on-invalid-index
10+
INFO: repacking table "public.tbl_badindex"
11+
WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
--
2+
-- do repack
3+
--
4+
5+
\! pg_repack --dbname=contrib_regression --table=tbl_cluster --error-on-invalid-index
6+
\! pg_repack --dbname=contrib_regression --table=tbl_badindex --error-on-invalid-index
7+
\! pg_repack --dbname=contrib_regression --error-on-invalid-index

0 commit comments

Comments
 (0)