Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitadd85ea

Browse files
committed
Fix table lock levels for REINDEX INDEX CONCURRENTLY
REINDEX CONCURRENTLY locks tables with ShareUpdateExclusiveLock ratherthan the ShareLock used by a plain REINDEX. However,RangeVarCallbackForReindexIndex() was not updated for that and stillused the ShareLock only. This would lead to lock upgrades later,leading to possible deadlocks.Reported-by: Andres Freund <andres@anarazel.de>Reviewed-by: Andres Freund <andres@anarazel.de>Reviewed-by: Michael Paquier <michael@paquier.xyz>Discussion:https://www.postgresql.org/message-id/flat/20190430151735.wi52sxjvxsjvaxxt%40alap3.anarazel.de
1 parent8efe710 commitadd85ea

File tree

1 file changed

+33
-12
lines changed

1 file changed

+33
-12
lines changed

‎src/backend/commands/indexcmds.c

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ static bool ReindexRelationConcurrently(Oid relationOid, int options);
9191
staticvoidReindexPartitionedIndex(RelationparentIdx);
9292
staticvoidupdate_relispartition(OidrelationId,boolnewval);
9393

94+
/*
95+
* callback argument type for RangeVarCallbackForReindexIndex()
96+
*/
97+
structReindexIndexCallbackState
98+
{
99+
boolconcurrent;/* flag from statement */
100+
Oidlocked_table_oid;/* tracks previously locked table */
101+
};
102+
94103
/*
95104
* CheckIndexCompatible
96105
*Determine whether an existing index definition is compatible with a
@@ -2303,8 +2312,8 @@ ChooseIndexColumnNames(List *indexElems)
23032312
void
23042313
ReindexIndex(RangeVar*indexRelation,intoptions,boolconcurrent)
23052314
{
2315+
structReindexIndexCallbackStatestate;
23062316
OidindOid;
2307-
OidheapOid=InvalidOid;
23082317
Relationirel;
23092318
charpersistence;
23102319

@@ -2313,11 +2322,13 @@ ReindexIndex(RangeVar *indexRelation, int options, bool concurrent)
23132322
* obtain lock on table first, to avoid deadlock hazard. The lock level
23142323
* used here must match the index lock obtained in reindex_index().
23152324
*/
2325+
state.concurrent=concurrent;
2326+
state.locked_table_oid=InvalidOid;
23162327
indOid=RangeVarGetRelidExtended(indexRelation,
23172328
concurrent ?ShareUpdateExclusiveLock :AccessExclusiveLock,
23182329
0,
23192330
RangeVarCallbackForReindexIndex,
2320-
(void*)&heapOid);
2331+
&state);
23212332

23222333
/*
23232334
* Obtain the current persistence of the existing index. We already hold
@@ -2350,7 +2361,15 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
23502361
OidrelId,OidoldRelId,void*arg)
23512362
{
23522363
charrelkind;
2353-
Oid*heapOid= (Oid*)arg;
2364+
structReindexIndexCallbackState*state=arg;
2365+
LOCKMODEtable_lockmode;
2366+
2367+
/*
2368+
* Lock level here should match table lock in reindex_index() for
2369+
* non-concurrent case and table locks used by index_concurrently_*() for
2370+
* concurrent case.
2371+
*/
2372+
table_lockmode=state->concurrent ?ShareUpdateExclusiveLock :ShareLock;
23542373

23552374
/*
23562375
* If we previously locked some other index's heap, and the name we're
@@ -2359,9 +2378,8 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
23592378
*/
23602379
if (relId!=oldRelId&&OidIsValid(oldRelId))
23612380
{
2362-
/* lock level here should match reindex_index() heap lock */
2363-
UnlockRelationOid(*heapOid,ShareLock);
2364-
*heapOid=InvalidOid;
2381+
UnlockRelationOid(state->locked_table_oid,table_lockmode);
2382+
state->locked_table_oid=InvalidOid;
23652383
}
23662384

23672385
/* If the relation does not exist, there's nothing more to do. */
@@ -2389,14 +2407,17 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
23892407
/* Lock heap before index to avoid deadlock. */
23902408
if (relId!=oldRelId)
23912409
{
2410+
Oidtable_oid=IndexGetRelation(relId, true);
2411+
23922412
/*
2393-
* Lock level here should match reindex_index() heap lock. If the OID
2394-
* isn't valid, it means the index as concurrently dropped, which is
2395-
* not a problem for us; just return normally.
2413+
* If the OID isn't valid, it means the index was concurrently
2414+
* dropped, which is not a problem for us; just return normally.
23962415
*/
2397-
*heapOid=IndexGetRelation(relId, true);
2398-
if (OidIsValid(*heapOid))
2399-
LockRelationOid(*heapOid,ShareLock);
2416+
if (OidIsValid(table_oid))
2417+
{
2418+
LockRelationOid(table_oid,table_lockmode);
2419+
state->locked_table_oid=table_oid;
2420+
}
24002421
}
24012422
}
24022423

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp