aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/vacuum.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/vacuum.c')
-rw-r--r--src/backend/commands/vacuum.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index d0ccf310cc4..c818d8f9667 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.300 2005/02/15 03:50:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.301 2005/02/20 02:21:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,6 +32,7 @@
#include "catalog/namespace.h"
#include "catalog/pg_database.h"
#include "catalog/pg_index.h"
+#include "commands/dbcommands.h"
#include "commands/vacuum.h"
#include "executor/executor.h"
#include "miscadmin.h"
@@ -761,8 +762,13 @@ vac_update_dbstats(Oid dbid,
*
* Scan pg_database to determine the system-wide oldest datvacuumxid,
* and use it to truncate the transaction commit log (pg_clog).
- * Also generate a warning if the system-wide oldest datfrozenxid
- * seems to be in danger of wrapping around.
+ * Also update the XID wrap limit point maintained by varsup.c.
+ *
+ * We also generate a warning if the system-wide oldest datfrozenxid
+ * seems to be in danger of wrapping around. This is a long-in-advance
+ * warning; if we start getting uncomfortably close, GetNewTransactionId
+ * will generate more-annoying warnings, and ultimately refuse to issue
+ * any more new XIDs.
*
* The passed XIDs are simply the ones I just wrote into my pg_database
* entry. They're used to initialize the "min" calculations.
@@ -778,10 +784,17 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
HeapScanDesc scan;
HeapTuple tuple;
int32 age;
+ NameData oldest_datname;
bool vacuumAlreadyWrapped = false;
bool frozenAlreadyWrapped = false;
+ /* init oldest_datname to sync with my frozenXID */
+ namestrcpy(&oldest_datname, get_database_name(MyDatabaseId));
+ /*
+ * Note: the "already wrapped" cases should now be impossible due to the
+ * defenses in GetNewTransactionId, but we keep them anyway.
+ */
relation = heap_openr(DatabaseRelationName, AccessShareLock);
scan = heap_beginscan(relation, SnapshotNow, 0, NULL);
@@ -807,7 +820,10 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
if (TransactionIdPrecedes(myXID, dbform->datfrozenxid))
frozenAlreadyWrapped = true;
else if (TransactionIdPrecedes(dbform->datfrozenxid, frozenXID))
+ {
frozenXID = dbform->datfrozenxid;
+ namecpy(&oldest_datname, &dbform->datname);
+ }
}
}
@@ -830,24 +846,30 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
/* Truncate CLOG to the oldest vacuumxid */
TruncateCLOG(vacuumXID);
- /* Give warning about impending wraparound problems */
+ /*
+ * Do not update varsup.c if we seem to have suffered wraparound
+ * already; the computed XID might be bogus.
+ */
if (frozenAlreadyWrapped)
{
ereport(WARNING,
(errmsg("some databases have not been vacuumed in over 1 billion transactions"),
errhint("Better vacuum them soon, or you may have a wraparound failure.")));
+ return;
}
- else
- {
- age = (int32) (myXID - frozenXID);
- if (age > (int32) ((MaxTransactionId >> 3) * 3))
- ereport(WARNING,
- (errmsg("some databases have not been vacuumed in %d transactions",
- age),
- errhint("Better vacuum them within %d transactions, "
- "or you may have a wraparound failure.",
- (int32) (MaxTransactionId >> 1) - age)));
- }
+
+ /* Update the wrap limit for GetNewTransactionId */
+ SetTransactionIdLimit(frozenXID, &oldest_datname);
+
+ /* Give warning about impending wraparound problems */
+ age = (int32) (myXID - frozenXID);
+ if (age > (int32) ((MaxTransactionId >> 3) * 3))
+ ereport(WARNING,
+ (errmsg("database \"%s\" must be vacuumed within %u transactions",
+ NameStr(oldest_datname),
+ (MaxTransactionId >> 1) - age),
+ errhint("To avoid a database shutdown, execute a full-database VACUUM in \"%s\".",
+ NameStr(oldest_datname))));
}