Skip to content

Commit def30e8

Browse files
committed
Don't try to fetch database name when SetTransactionIdLimit() is executed
outside a transaction. This repairs brain fade in my patch of 2009-08-30: the reason we had been storing oldest-database name, not OID, in ShmemVariableCache was of course to avoid having to do a catalog lookup at times when it might be unsafe. This error explains why Aleksandr Dushein is having trouble getting out of an XID wraparound state in bug #5718, though not how he got into that state in the first place. I suspect pg_upgrade is at fault there.
1 parent 17a1666 commit def30e8

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

src/backend/access/transam/varsup.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "access/clog.h"
1717
#include "access/subtrans.h"
1818
#include "access/transam.h"
19+
#include "access/xact.h"
1920
#include "commands/dbcommands.h"
2021
#include "miscadmin.h"
2122
#include "postmaster/autovacuum.h"
@@ -346,13 +347,22 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
346347
/* Give an immediate warning if past the wrap warn point */
347348
if (TransactionIdFollowsOrEquals(curXid, xidWarnLimit) && !InRecovery)
348349
{
349-
char *oldest_datname = get_database_name(oldest_datoid);
350+
char *oldest_datname;
350351

351352
/*
352-
* Note: it's possible that get_database_name fails and returns NULL,
353-
* for example because the database just got dropped. We'll still
354-
* warn, even though the warning might now be unnecessary.
353+
* We can be called when not inside a transaction, for example
354+
* during StartupXLOG(). In such a case we cannot do database
355+
* access, so we must just report the oldest DB's OID.
356+
*
357+
* Note: it's also possible that get_database_name fails and returns
358+
* NULL, for example because the database just got dropped. We'll
359+
* still warn, even though the warning might now be unnecessary.
355360
*/
361+
if (IsTransactionState())
362+
oldest_datname = get_database_name(oldest_datoid);
363+
else
364+
oldest_datname = NULL;
365+
356366
if (oldest_datname)
357367
ereport(WARNING,
358368
(errmsg("database \"%s\" must be vacuumed within %u transactions",

0 commit comments

Comments
 (0)