diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2010-10-20 12:48:51 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2010-10-20 12:48:51 -0400 |
commit | def30e84c41389225ee9e56cb7c722980bab9746 (patch) | |
tree | c359509f505b88f50ca23915ef237ebfbea0439c /src | |
parent | 17a16663d0c1c70c5c70ba97de6fe2c9c6a3bc07 (diff) | |
download | postgresql-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.c | 18 |
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", |