aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-10-20 12:48:51 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2010-10-20 12:48:51 -0400
commitdef30e84c41389225ee9e56cb7c722980bab9746 (patch)
treec359509f505b88f50ca23915ef237ebfbea0439c /src
parent17a16663d0c1c70c5c70ba97de6fe2c9c6a3bc07 (diff)
downloadpostgresql-def30e84c41389225ee9e56cb7c722980bab9746.tar.gz
postgresql-def30e84c41389225ee9e56cb7c722980bab9746.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/varsup.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 391724ea0fe..6f423bcf3a3 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -16,6 +16,7 @@
#include "access/clog.h"
#include "access/subtrans.h"
#include "access/transam.h"
+#include "access/xact.h"
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "postmaster/autovacuum.h"
@@ -346,13 +347,22 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
/* Give an immediate warning if past the wrap warn point */
if (TransactionIdFollowsOrEquals(curXid, xidWarnLimit) && !InRecovery)
{
- char *oldest_datname = get_database_name(oldest_datoid);
+ char *oldest_datname;
/*
- * Note: it's possible that get_database_name fails and returns NULL,
- * for example because the database just got dropped. We'll still
- * warn, even though the warning might now be unnecessary.
+ * We can be called when not inside a transaction, for example
+ * during StartupXLOG(). In such a case we cannot do database
+ * access, so we must just report the oldest DB's OID.
+ *
+ * Note: it's also possible that get_database_name fails and returns
+ * NULL, for example because the database just got dropped. We'll
+ * still warn, even though the warning might now be unnecessary.
*/
+ if (IsTransactionState())
+ oldest_datname = get_database_name(oldest_datoid);
+ else
+ oldest_datname = NULL;
+
if (oldest_datname)
ereport(WARNING,
(errmsg("database \"%s\" must be vacuumed within %u transactions",