Skip to content

Commit 7f84b0e

Browse files
committed
Handle interrupts within a transaction context in REINDEX CONCURRENTLY
Phases 2 (building the new index) and 3 (validating the new index) checked for interrupts outside a transaction context, having as consequence to not release session-level locks taken on the parent relation and the old and new indexes processed. This could for example be triggered with statement_timeout and a bad timing, and would issue confusing error messages when shutting down the session still holding the locks (note that an assertion failure would be triggered first), on top of more issues with concurrent sessions trying to take a lock that would interfere with the SHARE UPDATE EXCLUSIVE locks hold here. This moves all the interruption checks inside a transaction context. Note that I have manually tested all interruptions to make sure that invalid indexes can be cleaned up properly. Partition indexes still have issues on their own with some missing dependency handling, which will be dealt with in a follow-up patch. Reported-by: Justin Pryzby Author: Michael Paquier Discussion: https://postgr.es/m/20191013025145.GC4475@telsasoft.com Backpatch-through: 12
1 parent 56a459b commit 7f84b0e

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

src/backend/commands/indexcmds.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3058,11 +3058,16 @@ ReindexRelationConcurrently(Oid relationOid, int options)
30583058
Oid newIndexId = lfirst_oid(lc2);
30593059
Oid heapId;
30603060

3061-
CHECK_FOR_INTERRUPTS();
3062-
30633061
/* Start new transaction for this index's concurrent build */
30643062
StartTransactionCommand();
30653063

3064+
/*
3065+
* Check for user-requested abort. This is inside a transaction so as
3066+
* xact.c does not issue a useless WARNING, and ensures that
3067+
* session-level locks are cleaned up on abort.
3068+
*/
3069+
CHECK_FOR_INTERRUPTS();
3070+
30663071
/* Set ActiveSnapshot since functions in the indexes may need it */
30673072
PushActiveSnapshot(GetTransactionSnapshot());
30683073

@@ -3102,10 +3107,15 @@ ReindexRelationConcurrently(Oid relationOid, int options)
31023107
TransactionId limitXmin;
31033108
Snapshot snapshot;
31043109

3105-
CHECK_FOR_INTERRUPTS();
3106-
31073110
StartTransactionCommand();
31083111

3112+
/*
3113+
* Check for user-requested abort. This is inside a transaction so as
3114+
* xact.c does not issue a useless WARNING, and ensures that
3115+
* session-level locks are cleaned up on abort.
3116+
*/
3117+
CHECK_FOR_INTERRUPTS();
3118+
31093119
heapId = IndexGetRelation(newIndexId, false);
31103120

31113121
/*
@@ -3167,6 +3177,11 @@ ReindexRelationConcurrently(Oid relationOid, int options)
31673177
Oid newIndexId = lfirst_oid(lc2);
31683178
Oid heapId;
31693179

3180+
/*
3181+
* Check for user-requested abort. This is inside a transaction so as
3182+
* xact.c does not issue a useless WARNING, and ensures that
3183+
* session-level locks are cleaned up on abort.
3184+
*/
31703185
CHECK_FOR_INTERRUPTS();
31713186

31723187
heapId = IndexGetRelation(oldIndexId, false);
@@ -3222,7 +3237,13 @@ ReindexRelationConcurrently(Oid relationOid, int options)
32223237
Oid oldIndexId = lfirst_oid(lc);
32233238
Oid heapId;
32243239

3240+
/*
3241+
* Check for user-requested abort. This is inside a transaction so as
3242+
* xact.c does not issue a useless WARNING, and ensures that
3243+
* session-level locks are cleaned up on abort.
3244+
*/
32253245
CHECK_FOR_INTERRUPTS();
3246+
32263247
heapId = IndexGetRelation(oldIndexId, false);
32273248
index_concurrently_set_dead(heapId, oldIndexId);
32283249
}

0 commit comments

Comments
 (0)