diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index fff0320eca2a17a48182239bdb0c12bc5b4330c9..ed3effab65190bc9eacc60e88c4fa517c054a523 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
  *
  *
  * 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,
 static void
 vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
 {
+	TransactionId myXID;
 	Relation	relation;
 	HeapScanDesc scan;
 	HeapTuple	tuple;
 	int32		age;
+	bool		vacuumAlreadyWrapped = false;
+	bool		frozenAlreadyWrapped = false;
+
+	myXID = GetCurrentTransactionId();
 
 	relation = heap_openr(DatabaseRelationName, AccessShareLock);
 
@@ -575,28 +580,55 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
 		if (!dbform->datallowconn)
 			continue;
 
-		if (TransactionIdIsNormal(dbform->datvacuumxid) &&
-			TransactionIdPrecedes(dbform->datvacuumxid, vacuumXID))
-			vacuumXID = dbform->datvacuumxid;
-		if (TransactionIdIsNormal(dbform->datfrozenxid) &&
-			TransactionIdPrecedes(dbform->datfrozenxid, frozenXID))
-			frozenXID = dbform->datfrozenxid;
+		if (TransactionIdIsNormal(dbform->datvacuumxid))
+		{
+			if (TransactionIdPrecedes(myXID, dbform->datvacuumxid))
+				vacuumAlreadyWrapped = true;
+			else if (TransactionIdPrecedes(dbform->datvacuumxid, vacuumXID))
+				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_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 */
 	TruncateCLOG(vacuumXID);
 
 	/* Give warning about impending wraparound problems */
-	age = (int32) (GetCurrentTransactionId() - 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);
+	if (frozenAlreadyWrapped)
+	{
+		elog(WARNING, "Some databases have not been vacuumed in over 1 billion transactions."
+			 "\n\tBetter vacuum them soon, or you may have a wraparound failure.");
+	}
+	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);
+	}
 }