Skip to content

Commit 8be9317

Browse files
committed
Use heap_inplace_update() to unset pg_database.dathasloginevt
Doing this instead of regular updates serves two purposes. First, that avoids possible waiting on the row-level lock. Second, that avoids dealing with TOAST. It's known that changes made by heap_inplace_update() may be lost due to concurrent normal updates. However, we are OK with that. The subsequent connections will still have a chance to set "dathasloginevt" to false. Reported-by: Alexander Lakhin Discussion: https://postgr.es/m/e2a0248e-5f32-af0c-9832-a90d303c2c61%40gmail.com
1 parent 428e2de commit 8be9317

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

src/backend/commands/event_trigger.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*/
1414
#include "postgres.h"
1515

16+
#include "access/heapam.h"
1617
#include "access/htup_details.h"
1718
#include "access/table.h"
1819
#include "access/xact.h"
@@ -943,18 +944,45 @@ EventTriggerOnLogin(void)
943944
Relation pg_db = table_open(DatabaseRelationId, RowExclusiveLock);
944945
HeapTuple tuple;
945946
Form_pg_database db;
947+
ScanKeyData key[1];
948+
SysScanDesc scan;
946949

947-
tuple = SearchSysCacheCopy1(DATABASEOID,
948-
ObjectIdGetDatum(MyDatabaseId));
950+
/*
951+
* Get the pg_database tuple to scribble on. Note that this does
952+
* not directly rely on the syscache to avoid issues with
953+
* flattened toast values for the in-place update.
954+
*/
955+
ScanKeyInit(&key[0],
956+
Anum_pg_database_oid,
957+
BTEqualStrategyNumber, F_OIDEQ,
958+
ObjectIdGetDatum(MyDatabaseId));
959+
960+
scan = systable_beginscan(pg_db, DatabaseOidIndexId, true,
961+
NULL, 1, key);
962+
tuple = systable_getnext(scan);
963+
tuple = heap_copytuple(tuple);
964+
systable_endscan(scan);
949965

950966
if (!HeapTupleIsValid(tuple))
951-
elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
967+
elog(ERROR, "could not find tuple for database %u", MyDatabaseId);
952968

953969
db = (Form_pg_database) GETSTRUCT(tuple);
954970
if (db->dathasloginevt)
955971
{
956972
db->dathasloginevt = false;
957-
CatalogTupleUpdate(pg_db, &tuple->t_self, tuple);
973+
974+
/*
975+
* Do an "in place" update of the pg_database tuple. Doing
976+
* this instead of regular updates serves two purposes. First,
977+
* that avoids possible waiting on the row-level lock. Second,
978+
* that avoids dealing with TOAST.
979+
*
980+
* It's known that changes made by heap_inplace_update() may
981+
* be lost due to concurrent normal updates. However, we are
982+
* OK with that. The subsequent connections will still have a
983+
* chance to set "dathasloginevt" to false.
984+
*/
985+
heap_inplace_update(pg_db, tuple);
958986
}
959987
table_close(pg_db, RowExclusiveLock);
960988
heap_freetuple(tuple);

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