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

Commite4afd71

Browse files
committed
Cope with inplace update making catcache stale during TOAST fetch.
This extendsad98fb1 to invals ofinplace updates. Trouble requires an inplace update of a catalog havinga TOAST table, so only pg_database was at risk. (The other catalog onwhich core code performs inplace updates, pg_class, has no TOAST table.)Trouble would require something like the inplace-inval.spec test.Consider GRANT ... ON DATABASE fetching a stale row from cache anddiscarding a datfrozenxid update that vac_truncate_clog() has alreadyrelied upon. Back-patch to v12 (all supported versions).Reviewed (in an earlier version) by Robert Haas.Discussion:https://postgr.es/m/20240114201411.d0@rfd.leadboat.comDiscussion:https://postgr.es/m/20240512232923.aa.nmisch@google.com
1 parentfc8c258 commite4afd71

File tree

3 files changed

+64
-3
lines changed

3 files changed

+64
-3
lines changed

‎src/backend/catalog/catalog.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,27 @@ IsCatalogRelationOid(Oid relid)
137137
return (relid< (Oid)FirstUnpinnedObjectId);
138138
}
139139

140+
/*
141+
* IsInplaceUpdateRelation
142+
*True iff core code performs inplace updates on the relation.
143+
*/
144+
bool
145+
IsInplaceUpdateRelation(Relationrelation)
146+
{
147+
returnIsInplaceUpdateOid(RelationGetRelid(relation));
148+
}
149+
150+
/*
151+
* IsInplaceUpdateOid
152+
*Like the above, but takes an OID as argument.
153+
*/
154+
bool
155+
IsInplaceUpdateOid(Oidrelid)
156+
{
157+
return (relid==RelationRelationId||
158+
relid==DatabaseRelationId);
159+
}
160+
140161
/*
141162
* IsToastRelation
142163
*True iff relation is a TOAST support relation (or index).

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

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include"access/sysattr.h"
2121
#include"access/table.h"
2222
#include"access/xact.h"
23+
#include"catalog/catalog.h"
2324
#include"catalog/pg_collation.h"
2425
#include"catalog/pg_operator.h"
2526
#include"catalog/pg_type.h"
@@ -1938,6 +1939,23 @@ ReleaseCatCacheList(CatCList *list)
19381939
}
19391940

19401941

1942+
/*
1943+
* equalTuple
1944+
*Are these tuples memcmp()-equal?
1945+
*/
1946+
staticbool
1947+
equalTuple(HeapTuplea,HeapTupleb)
1948+
{
1949+
uint32alen;
1950+
uint32blen;
1951+
1952+
alen=a->t_len;
1953+
blen=b->t_len;
1954+
return (alen==blen&&
1955+
memcmp((char*)a->t_data,
1956+
(char*)b->t_data,blen)==0);
1957+
}
1958+
19411959
/*
19421960
* CatalogCacheCreateEntry
19431961
*Create a new CatCTup entry, copying the given HeapTuple and other
@@ -1988,14 +2006,34 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, SysScanDesc scandesc,
19882006
*/
19892007
if (HeapTupleHasExternal(ntp))
19902008
{
2009+
boolneed_cmp=IsInplaceUpdateOid(cache->cc_reloid);
2010+
HeapTuplebefore=NULL;
2011+
boolmatches= true;
2012+
2013+
if (need_cmp)
2014+
before=heap_copytuple(ntp);
19912015
dtp=toast_flatten_tuple(ntp,cache->cc_tupdesc);
19922016

19932017
/*
19942018
* The tuple could become stale while we are doing toast table
1995-
* access (since AcceptInvalidationMessages can run then), so we
1996-
* must recheck its visibility afterwards.
2019+
* access (since AcceptInvalidationMessages can run then).
2020+
* equalTuple() detects staleness from inplace updates, while
2021+
* systable_recheck_tuple() detects staleness from normal updates.
2022+
*
2023+
* While this equalTuple() follows the usual rule of reading with
2024+
* a pin and no buffer lock, it warrants suspicion since an
2025+
* inplace update could appear at any moment. It's safe because
2026+
* the inplace update sends an invalidation that can't reorder
2027+
* before the inplace heap change. If the heap change reaches
2028+
* this process just after equalTuple() looks, we've not missed
2029+
* its inval.
19972030
*/
1998-
if (!systable_recheck_tuple(scandesc,ntp))
2031+
if (need_cmp)
2032+
{
2033+
matches=equalTuple(before,ntp);
2034+
heap_freetuple(before);
2035+
}
2036+
if (!matches|| !systable_recheck_tuple(scandesc,ntp))
19992037
{
20002038
heap_freetuple(dtp);
20012039
returnNULL;

‎src/include/catalog/catalog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
externboolIsSystemRelation(Relationrelation);
2222
externboolIsToastRelation(Relationrelation);
2323
externboolIsCatalogRelation(Relationrelation);
24+
externboolIsInplaceUpdateRelation(Relationrelation);
2425

2526
externboolIsSystemClass(Oidrelid,Form_pg_classreltuple);
2627
externboolIsToastClass(Form_pg_classreltuple);
2728

2829
externboolIsCatalogRelationOid(Oidrelid);
30+
externboolIsInplaceUpdateOid(Oidrelid);
2931

3032
externboolIsCatalogNamespace(OidnamespaceId);
3133
externboolIsToastNamespace(OidnamespaceId);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp