Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 29d58fd

Browse files
committed
Transfer state pertaining to pending REINDEX operations to workers.
This will allow the pending patch for parallel CREATE INDEX to work on system catalogs, and to provide the same level of protection against use of user indexes while they are being rebuilt that we have for non-parallel CREATE INDEX. Patch by me, reviewed by Peter Geoghegan. Discussion: http://postgr.es/m/CA+TgmoYN-YQU9JsGQcqFLovZ-C+Xgp1_xhJQad=cunGG-_p5gg@mail.gmail.com Discussion: http://postgr.es/m/CAH2-Wzkv4UNkXYhqQRqk-u9rS7h5c-4cCW+EqQ8K_WSeS43aZg@mail.gmail.com
1 parent 4e54dd2 commit 29d58fd

File tree

4 files changed

+98
-2
lines changed

4 files changed

+98
-2
lines changed

src/backend/access/transam/README.parallel

+3
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ worker. This includes:
122122
values are restored, this incidentally sets SessionUserId and OuterUserId
123123
to the correct values. This final step restores CurrentUserId.
124124

125+
- State related to pending REINDEX operations, which prevents access to
126+
an index that is currently being rebuilt.
127+
125128
To prevent undetected or unprincipled deadlocks when running in parallel mode,
126129
this could should eventually handle heavyweight locks in some way. This is
127130
not implemented yet.

src/backend/access/transam/parallel.c

+17-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "access/session.h"
1919
#include "access/xact.h"
2020
#include "access/xlog.h"
21+
#include "catalog/index.h"
2122
#include "catalog/namespace.h"
2223
#include "commands/async.h"
2324
#include "executor/execParallel.h"
@@ -67,6 +68,7 @@
6768
#define PARALLEL_KEY_TRANSACTION_STATE UINT64CONST(0xFFFFFFFFFFFF0008)
6869
#define PARALLEL_KEY_ENTRYPOINT UINT64CONST(0xFFFFFFFFFFFF0009)
6970
#define PARALLEL_KEY_SESSION_DSM UINT64CONST(0xFFFFFFFFFFFF000A)
71+
#define PARALLEL_KEY_REINDEX_STATE UINT64CONST(0xFFFFFFFFFFFF000B)
7072

7173
/* Fixed-size parallel state. */
7274
typedef struct FixedParallelState
@@ -200,6 +202,7 @@ InitializeParallelDSM(ParallelContext *pcxt)
200202
Size tsnaplen = 0;
201203
Size asnaplen = 0;
202204
Size tstatelen = 0;
205+
Size reindexlen = 0;
203206
Size segsize = 0;
204207
int i;
205208
FixedParallelState *fps;
@@ -249,8 +252,10 @@ InitializeParallelDSM(ParallelContext *pcxt)
249252
tstatelen = EstimateTransactionStateSpace();
250253
shm_toc_estimate_chunk(&pcxt->estimator, tstatelen);
251254
shm_toc_estimate_chunk(&pcxt->estimator, sizeof(dsm_handle));
255+
reindexlen = EstimateReindexStateSpace();
256+
shm_toc_estimate_chunk(&pcxt->estimator, reindexlen);
252257
/* If you add more chunks here, you probably need to add keys. */
253-
shm_toc_estimate_keys(&pcxt->estimator, 7);
258+
shm_toc_estimate_keys(&pcxt->estimator, 8);
254259

255260
/* Estimate space need for error queues. */
256261
StaticAssertStmt(BUFFERALIGN(PARALLEL_ERROR_QUEUE_SIZE) ==
@@ -319,6 +324,7 @@ InitializeParallelDSM(ParallelContext *pcxt)
319324
char *tsnapspace;
320325
char *asnapspace;
321326
char *tstatespace;
327+
char *reindexspace;
322328
char *error_queue_space;
323329
char *session_dsm_handle_space;
324330
char *entrypointstate;
@@ -360,6 +366,11 @@ InitializeParallelDSM(ParallelContext *pcxt)
360366
SerializeTransactionState(tstatelen, tstatespace);
361367
shm_toc_insert(pcxt->toc, PARALLEL_KEY_TRANSACTION_STATE, tstatespace);
362368

369+
/* Serialize reindex state. */
370+
reindexspace = shm_toc_allocate(pcxt->toc, reindexlen);
371+
SerializeReindexState(reindexlen, reindexspace);
372+
shm_toc_insert(pcxt->toc, PARALLEL_KEY_REINDEX_STATE, reindexspace);
373+
363374
/* Allocate space for worker information. */
364375
pcxt->worker = palloc0(sizeof(ParallelWorkerInfo) * pcxt->nworkers);
365376

@@ -972,6 +983,7 @@ ParallelWorkerMain(Datum main_arg)
972983
char *tsnapspace;
973984
char *asnapspace;
974985
char *tstatespace;
986+
char *reindexspace;
975987
StringInfoData msgbuf;
976988
char *session_dsm_handle_space;
977989

@@ -1137,6 +1149,10 @@ ParallelWorkerMain(Datum main_arg)
11371149
/* Set ParallelMasterBackendId so we know how to address temp relations. */
11381150
ParallelMasterBackendId = fps->parallel_master_backend_id;
11391151

1152+
/* Restore reindex state. */
1153+
reindexspace = shm_toc_lookup(toc, PARALLEL_KEY_REINDEX_STATE, false);
1154+
RestoreReindexState(reindexspace);
1155+
11401156
/*
11411157
* We've initialized all of our state now; nothing should change
11421158
* hereafter.

src/backend/catalog/index.c

+74-1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ typedef struct
8686
tups_inserted;
8787
} v_i_state;
8888

89+
/*
90+
* Pointer-free representation of variables used when reindexing system
91+
* catalogs; we use this to propagate those values to parallel workers.
92+
*/
93+
typedef struct
94+
{
95+
Oid currentlyReindexedHeap;
96+
Oid currentlyReindexedIndex;
97+
int numPendingReindexedIndexes;
98+
Oid pendingReindexedIndexes[FLEXIBLE_ARRAY_MEMBER];
99+
} SerializedReindexState;
100+
89101
/* non-export function prototypes */
90102
static bool relationHasPrimaryKey(Relation rel);
91103
static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
@@ -3653,7 +3665,8 @@ reindex_relation(Oid relid, int flags, int options)
36533665
* When we are busy reindexing a system index, this code provides support
36543666
* for preventing catalog lookups from using that index. We also make use
36553667
* of this to catch attempted uses of user indexes during reindexing of
3656-
* those indexes.
3668+
* those indexes. This information is propagated to parallel workers;
3669+
* attempting to change it during a parallel operation is not permitted.
36573670
* ----------------------------------------------------------------
36583671
*/
36593672

@@ -3719,6 +3732,8 @@ SetReindexProcessing(Oid heapOid, Oid indexOid)
37193732
static void
37203733
ResetReindexProcessing(void)
37213734
{
3735+
if (IsInParallelMode())
3736+
elog(ERROR, "cannot modify reindex state during a parallel operation");
37223737
currentlyReindexedHeap = InvalidOid;
37233738
currentlyReindexedIndex = InvalidOid;
37243739
}
@@ -3736,6 +3751,8 @@ SetReindexPending(List *indexes)
37363751
/* Reindexing is not re-entrant. */
37373752
if (pendingReindexedIndexes)
37383753
elog(ERROR, "cannot reindex while reindexing");
3754+
if (IsInParallelMode())
3755+
elog(ERROR, "cannot modify reindex state during a parallel operation");
37393756
pendingReindexedIndexes = list_copy(indexes);
37403757
}
37413758

@@ -3746,6 +3763,8 @@ SetReindexPending(List *indexes)
37463763
static void
37473764
RemoveReindexPending(Oid indexOid)
37483765
{
3766+
if (IsInParallelMode())
3767+
elog(ERROR, "cannot modify reindex state during a parallel operation");
37493768
pendingReindexedIndexes = list_delete_oid(pendingReindexedIndexes,
37503769
indexOid);
37513770
}
@@ -3757,5 +3776,59 @@ RemoveReindexPending(Oid indexOid)
37573776
static void
37583777
ResetReindexPending(void)
37593778
{
3779+
if (IsInParallelMode())
3780+
elog(ERROR, "cannot modify reindex state during a parallel operation");
37603781
pendingReindexedIndexes = NIL;
37613782
}
3783+
3784+
/*
3785+
* EstimateReindexStateSpace
3786+
* Estimate space needed to pass reindex state to parallel workers.
3787+
*/
3788+
extern Size
3789+
EstimateReindexStateSpace(void)
3790+
{
3791+
return offsetof(SerializedReindexState, pendingReindexedIndexes)
3792+
+ mul_size(sizeof(Oid), list_length(pendingReindexedIndexes));
3793+
}
3794+
3795+
/*
3796+
* SerializeReindexState
3797+
* Serialize reindex state for parallel workers.
3798+
*/
3799+
extern void
3800+
SerializeReindexState(Size maxsize, char *start_address)
3801+
{
3802+
SerializedReindexState *sistate = (SerializedReindexState *) start_address;
3803+
int c = 0;
3804+
ListCell *lc;
3805+
3806+
sistate->currentlyReindexedHeap = currentlyReindexedHeap;
3807+
sistate->currentlyReindexedIndex = currentlyReindexedIndex;
3808+
sistate->numPendingReindexedIndexes = list_length(pendingReindexedIndexes);
3809+
foreach(lc, pendingReindexedIndexes)
3810+
sistate->pendingReindexedIndexes[c++] = lfirst_oid(lc);
3811+
}
3812+
3813+
/*
3814+
* RestoreReindexState
3815+
* Restore reindex state in a parallel worker.
3816+
*/
3817+
extern void
3818+
RestoreReindexState(void *reindexstate)
3819+
{
3820+
SerializedReindexState *sistate = (SerializedReindexState *) reindexstate;
3821+
int c = 0;
3822+
MemoryContext oldcontext;
3823+
3824+
currentlyReindexedHeap = sistate->currentlyReindexedHeap;
3825+
currentlyReindexedIndex = sistate->currentlyReindexedIndex;
3826+
3827+
Assert(pendingReindexedIndexes == NIL);
3828+
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
3829+
for (c = 0; c < sistate->numPendingReindexedIndexes; ++c)
3830+
pendingReindexedIndexes =
3831+
lappend_oid(pendingReindexedIndexes,
3832+
sistate->pendingReindexedIndexes[c]);
3833+
MemoryContextSwitchTo(oldcontext);
3834+
}

src/include/catalog/index.h

+4
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,8 @@ extern bool ReindexIsProcessingHeap(Oid heapOid);
134134
extern bool ReindexIsProcessingIndex(Oid indexOid);
135135
extern Oid IndexGetRelation(Oid indexId, bool missing_ok);
136136

137+
extern Size EstimateReindexStateSpace(void);
138+
extern void SerializeReindexState(Size maxsize, char *start_address);
139+
extern void RestoreReindexState(void *reindexstate);
140+
137141
#endif /* INDEX_H */

0 commit comments

Comments
 (0)