Skip to content

Commit 947789f

Browse files
committed
Avoid using tuple from syscache for update of pg_database.datfrozenxid
pg_database.datfrozenxid gets updated using an in-place update at the end of vacuum or autovacuum. Since 96cdeae, as pg_database has a toast relation, it is possible for a pg_database tuple to have toast values if there is a large set of ACLs in place. In such a case, the in-place update would fail because of the flattening of the toast values done for the catcache entry fetched. Instead of using a copy from the catcache, this changes the logic to fetch the copy of the tuple by directly scanning pg_database. Per the lack of complaints on the matter, no backpatch is done. Note that before 96cdeae, attempting to insert such a tuple to pg_database would cause a "row is too big" error, so the end-of-vacuum problem was not reachable. Author: Ashwin Agrawal, Junfeng Yang Discussion: https://postgr.es/m/DM5PR0501MB38800D9E4605BCA72DD35557CCE10@DM5PR0501MB3880.namprd05.prod.outlook.com
1 parent 0a665bb commit 947789f

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

src/backend/access/heap/heapam.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5710,6 +5710,10 @@ heap_abort_speculative(Relation relation, ItemPointer tid)
57105710
*
57115711
* tuple is an in-memory tuple structure containing the data to be written
57125712
* over the target tuple. Also, tuple->t_self identifies the target tuple.
5713+
*
5714+
* Note that the tuple updated here had better not come directly from the
5715+
* syscache if the relation has a toast relation as this tuple could
5716+
* include toast values that have been expanded, causing a failure here.
57135717
*/
57145718
void
57155719
heap_inplace_update(Relation relation, HeapTuple tuple)

src/backend/commands/vacuum.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,7 @@ vac_update_datfrozenxid(void)
13611361
MultiXactId lastSaneMinMulti;
13621362
bool bogus = false;
13631363
bool dirty = false;
1364+
ScanKeyData key[1];
13641365

13651366
/*
13661367
* Restrict this task to one backend per database. This avoids race
@@ -1479,10 +1480,25 @@ vac_update_datfrozenxid(void)
14791480
/* Now fetch the pg_database tuple we need to update. */
14801481
relation = table_open(DatabaseRelationId, RowExclusiveLock);
14811482

1482-
/* Fetch a copy of the tuple to scribble on */
1483-
tuple = SearchSysCacheCopy1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
1483+
/*
1484+
* Get the pg_database tuple to scribble on. Note that this does not
1485+
* directly rely on the syscache to avoid issues with flattened toast
1486+
* values for the in-place update.
1487+
*/
1488+
ScanKeyInit(&key[0],
1489+
Anum_pg_database_oid,
1490+
BTEqualStrategyNumber, F_OIDEQ,
1491+
ObjectIdGetDatum(MyDatabaseId));
1492+
1493+
scan = systable_beginscan(relation, DatabaseOidIndexId, true,
1494+
NULL, 1, key);
1495+
tuple = systable_getnext(scan);
1496+
tuple = heap_copytuple(tuple);
1497+
systable_endscan(scan);
1498+
14841499
if (!HeapTupleIsValid(tuple))
14851500
elog(ERROR, "could not find tuple for database %u", MyDatabaseId);
1501+
14861502
dbform = (Form_pg_database) GETSTRUCT(tuple);
14871503

14881504
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy