Skip to content

Commit 5bbdfa8

Browse files
committed
Fix waits of REINDEX CONCURRENTLY for indexes with predicates or expressions
As introduced by f9900df, a REINDEX CONCURRENTLY job done for an index with predicates or expressions would set PROC_IN_SAFE_IC in its MyProc->statusFlags, causing it to be ignored by other concurrent operations. Such concurrent index rebuilds should never be ignored, as a predicate or an expression could call a user-defined function that accesses a different table than the table where the index is rebuilt. A test that uses injection points is added, backpatched down to 17. Michail has proposed a different test, but I have added something simpler with more coverage. Oversight in f9900df. Author: Michail Nikolaev Discussion: https://postgr.es/m/CANtu0oj9A3kZVduFTG0vrmGnKB+DCHgEpzOp0qAyOgmks84j0w@mail.gmail.com Backpatch-through: 14
1 parent dd8bea8 commit 5bbdfa8

File tree

5 files changed

+92
-3
lines changed

5 files changed

+92
-3
lines changed

src/backend/commands/indexcmds.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include "utils/builtins.h"
6262
#include "utils/fmgroids.h"
6363
#include "utils/guc.h"
64+
#include "utils/injection_point.h"
6465
#include "utils/inval.h"
6566
#include "utils/lsyscache.h"
6667
#include "utils/memutils.h"
@@ -3782,8 +3783,16 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
37823783
RestrictSearchPath();
37833784

37843785
/* determine safety of this index for set_indexsafe_procflags */
3785-
idx->safe = (indexRel->rd_indexprs == NIL &&
3786-
indexRel->rd_indpred == NIL);
3786+
idx->safe = (RelationGetIndexExpressions(indexRel) == NIL &&
3787+
RelationGetIndexPredicate(indexRel) == NIL);
3788+
3789+
#ifdef USE_INJECTION_POINTS
3790+
if (idx->safe)
3791+
INJECTION_POINT("reindex-conc-index-safe");
3792+
else
3793+
INJECTION_POINT("reindex-conc-index-not-safe");
3794+
#endif
3795+
37873796
idx->tableId = RelationGetRelid(heapRel);
37883797
idx->amId = indexRel->rd_rel->relam;
37893798

src/test/modules/injection_points/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ EXTENSION = injection_points
1010
DATA = injection_points--1.0.sql
1111
PGFILEDESC = "injection_points - facility for injection points"
1212

13-
REGRESS = injection_points
13+
REGRESS = injection_points reindex_conc
1414
REGRESS_OPTS = --dlpath=$(top_builddir)/src/test/regress
1515

1616
ISOLATION = inplace
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
-- Tests for REINDEX CONCURRENTLY
2+
CREATE EXTENSION injection_points;
3+
-- Check safety of indexes with predicates and expressions.
4+
SELECT injection_points_set_local();
5+
injection_points_set_local
6+
----------------------------
7+
8+
(1 row)
9+
10+
SELECT injection_points_attach('reindex-conc-index-safe', 'notice');
11+
injection_points_attach
12+
-------------------------
13+
14+
(1 row)
15+
16+
SELECT injection_points_attach('reindex-conc-index-not-safe', 'notice');
17+
injection_points_attach
18+
-------------------------
19+
20+
(1 row)
21+
22+
CREATE SCHEMA reindex_inj;
23+
CREATE TABLE reindex_inj.tbl(i int primary key, updated_at timestamp);
24+
CREATE UNIQUE INDEX ind_simple ON reindex_inj.tbl(i);
25+
CREATE UNIQUE INDEX ind_expr ON reindex_inj.tbl(ABS(i));
26+
CREATE UNIQUE INDEX ind_pred ON reindex_inj.tbl(i) WHERE mod(i, 2) = 0;
27+
CREATE UNIQUE INDEX ind_expr_pred ON reindex_inj.tbl(abs(i)) WHERE mod(i, 2) = 0;
28+
REINDEX INDEX CONCURRENTLY reindex_inj.ind_simple;
29+
NOTICE: notice triggered for injection point reindex-conc-index-safe
30+
REINDEX INDEX CONCURRENTLY reindex_inj.ind_expr;
31+
NOTICE: notice triggered for injection point reindex-conc-index-not-safe
32+
REINDEX INDEX CONCURRENTLY reindex_inj.ind_pred;
33+
NOTICE: notice triggered for injection point reindex-conc-index-not-safe
34+
REINDEX INDEX CONCURRENTLY reindex_inj.ind_expr_pred;
35+
NOTICE: notice triggered for injection point reindex-conc-index-not-safe
36+
-- Cleanup
37+
SELECT injection_points_detach('reindex-conc-index-safe');
38+
injection_points_detach
39+
-------------------------
40+
41+
(1 row)
42+
43+
SELECT injection_points_detach('reindex-conc-index-not-safe');
44+
injection_points_detach
45+
-------------------------
46+
47+
(1 row)
48+
49+
DROP TABLE reindex_inj.tbl;
50+
DROP SCHEMA reindex_inj;
51+
DROP EXTENSION injection_points;

src/test/modules/injection_points/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ tests += {
3434
'regress': {
3535
'sql': [
3636
'injection_points',
37+
'reindex_conc',
3738
],
3839
'regress_args': ['--dlpath', meson.build_root() / 'src/test/regress'],
3940
# The injection points are cluster-wide, so disable installcheck
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-- Tests for REINDEX CONCURRENTLY
2+
CREATE EXTENSION injection_points;
3+
4+
-- Check safety of indexes with predicates and expressions.
5+
SELECT injection_points_set_local();
6+
SELECT injection_points_attach('reindex-conc-index-safe', 'notice');
7+
SELECT injection_points_attach('reindex-conc-index-not-safe', 'notice');
8+
9+
CREATE SCHEMA reindex_inj;
10+
CREATE TABLE reindex_inj.tbl(i int primary key, updated_at timestamp);
11+
12+
CREATE UNIQUE INDEX ind_simple ON reindex_inj.tbl(i);
13+
CREATE UNIQUE INDEX ind_expr ON reindex_inj.tbl(ABS(i));
14+
CREATE UNIQUE INDEX ind_pred ON reindex_inj.tbl(i) WHERE mod(i, 2) = 0;
15+
CREATE UNIQUE INDEX ind_expr_pred ON reindex_inj.tbl(abs(i)) WHERE mod(i, 2) = 0;
16+
17+
REINDEX INDEX CONCURRENTLY reindex_inj.ind_simple;
18+
REINDEX INDEX CONCURRENTLY reindex_inj.ind_expr;
19+
REINDEX INDEX CONCURRENTLY reindex_inj.ind_pred;
20+
REINDEX INDEX CONCURRENTLY reindex_inj.ind_expr_pred;
21+
22+
-- Cleanup
23+
SELECT injection_points_detach('reindex-conc-index-safe');
24+
SELECT injection_points_detach('reindex-conc-index-not-safe');
25+
DROP TABLE reindex_inj.tbl;
26+
DROP SCHEMA reindex_inj;
27+
28+
DROP EXTENSION injection_points;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy