提交 9c54cfb4 编写于 作者: T Tom Lane

Fix CLOG truncation code to not do the Wrong Thing when there are already

wrapped-around databases.  The unvacuumed databases might be fine, or
they might not, but things will definitely not be fine if we remove the
wrong CLOG segments.  Per trouble report from Gary Wolfe, 1-Apr-2002.
上级 688781d4
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.221 2002/04/02 01:03:05 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.222 2002/04/02 05:11:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -557,10 +557,15 @@ vac_update_dbstats(Oid dbid, ...@@ -557,10 +557,15 @@ vac_update_dbstats(Oid dbid,
static void static void
vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID) vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
{ {
TransactionId myXID;
Relation relation; Relation relation;
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple tuple; HeapTuple tuple;
int32 age; int32 age;
bool vacuumAlreadyWrapped = false;
bool frozenAlreadyWrapped = false;
myXID = GetCurrentTransactionId();
relation = heap_openr(DatabaseRelationName, AccessShareLock); relation = heap_openr(DatabaseRelationName, AccessShareLock);
...@@ -575,28 +580,55 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID) ...@@ -575,28 +580,55 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
if (!dbform->datallowconn) if (!dbform->datallowconn)
continue; continue;
if (TransactionIdIsNormal(dbform->datvacuumxid) && if (TransactionIdIsNormal(dbform->datvacuumxid))
TransactionIdPrecedes(dbform->datvacuumxid, vacuumXID)) {
vacuumXID = dbform->datvacuumxid; if (TransactionIdPrecedes(myXID, dbform->datvacuumxid))
if (TransactionIdIsNormal(dbform->datfrozenxid) && vacuumAlreadyWrapped = true;
TransactionIdPrecedes(dbform->datfrozenxid, frozenXID)) else if (TransactionIdPrecedes(dbform->datvacuumxid, vacuumXID))
frozenXID = dbform->datfrozenxid; vacuumXID = dbform->datvacuumxid;
}
if (TransactionIdIsNormal(dbform->datfrozenxid))
{
if (TransactionIdPrecedes(myXID, dbform->datfrozenxid))
frozenAlreadyWrapped = true;
else if (TransactionIdPrecedes(dbform->datfrozenxid, frozenXID))
frozenXID = dbform->datfrozenxid;
}
} }
heap_endscan(scan); heap_endscan(scan);
heap_close(relation, AccessShareLock); heap_close(relation, AccessShareLock);
/*
* Do not truncate CLOG if we seem to have suffered wraparound already;
* the computed minimum XID might be bogus.
*/
if (vacuumAlreadyWrapped)
{
elog(WARNING, "Some databases have not been vacuumed in over 2 billion transactions."
"\n\tYou may have already suffered transaction-wraparound data loss.");
return;
}
/* Truncate CLOG to the oldest vacuumxid */ /* Truncate CLOG to the oldest vacuumxid */
TruncateCLOG(vacuumXID); TruncateCLOG(vacuumXID);
/* Give warning about impending wraparound problems */ /* Give warning about impending wraparound problems */
age = (int32) (GetCurrentTransactionId() - frozenXID); if (frozenAlreadyWrapped)
if (age > (int32) ((MaxTransactionId >> 3) * 3)) {
elog(WARNING, "Some databases have not been vacuumed in %d transactions." elog(WARNING, "Some databases have not been vacuumed in over 1 billion transactions."
"\n\tBetter vacuum them within %d transactions," "\n\tBetter vacuum them soon, or you may have a wraparound failure.");
"\n\tor you may have a wraparound failure.", }
age, (int32) (MaxTransactionId >> 1) - age); else
{
age = (int32) (myXID - frozenXID);
if (age > (int32) ((MaxTransactionId >> 3) * 3))
elog(WARNING, "Some databases have not been vacuumed in %d transactions."
"\n\tBetter vacuum them within %d transactions,"
"\n\tor you may have a wraparound failure.",
age, (int32) (MaxTransactionId >> 1) - age);
}
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册