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

Commite2d64f8

Browse files
committed
Avoid potential deadlock in InitCatCachePhase2().
Opening a catcache's index could require reading from that cache's owncatalog, which of course would acquire AccessShareLock on the catalog.So the original coding here risks locking index before heap, which coulddeadlock against another backend trying to get exclusive locks in thenormal order. Because InitCatCachePhase2 is only called when a backendhas to start up without a relcache init file, the deadlock was seldom seenin the field. (And by the same token, there's no need to worry about anyperformance disadvantage; so not much point in trying to distinguishexactly which catalogs have the risk.)Bug report, diagnosis, and patch by Nikhil Sontakke. Additional commentaryby me. Back-patch to all supported branches.
1 parent151e463 commite2d64f8

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

‎src/backend/utils/cache/catcache.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#ifdefCATCACHE_STATS
2525
#include"storage/ipc.h"/* for on_proc_exit */
2626
#endif
27+
#include"storage/lmgr.h"
2728
#include"utils/builtins.h"
2829
#include"utils/fmgroids.h"
2930
#include"utils/memutils.h"
@@ -1009,8 +1010,16 @@ InitCatCachePhase2(CatCache *cache, bool touch_index)
10091010
{
10101011
Relationidesc;
10111012

1013+
/*
1014+
* We must lock the underlying catalog before opening the index to
1015+
* avoid deadlock, since index_open could possibly result in reading
1016+
* this same catalog, and if anyone else is exclusive-locking this
1017+
* catalog and index they'll be doing it in that order.
1018+
*/
1019+
LockRelationOid(cache->cc_reloid,AccessShareLock);
10121020
idesc=index_open(cache->cc_indexoid,AccessShareLock);
10131021
index_close(idesc,AccessShareLock);
1022+
UnlockRelationOid(cache->cc_reloid,AccessShareLock);
10141023
}
10151024
}
10161025

‎src/backend/utils/cache/relcache.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,6 +1541,12 @@ RelationClose(Relation relation)
15411541
*We assume that at the time we are called, we have at least AccessShareLock
15421542
*on the target index. (Note: in the calls from RelationClearRelation,
15431543
*this is legitimate because we know the rel has positive refcount.)
1544+
*
1545+
*If the target index is an index on pg_class or pg_index, we'd better have
1546+
*previously gotten at least AccessShareLock on its underlying catalog,
1547+
*else we are at risk of deadlock against someone trying to exclusive-lock
1548+
*the heap and index in that order. This is ensured in current usage by
1549+
*only applying this to indexes being opened or having positive refcount.
15441550
*/
15451551
staticvoid
15461552
RelationReloadClassinfo(Relationrelation)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp