@@ -998,22 +998,32 @@ TransactionIdIsActive(TransactionId xid)
998
998
* This is also used to determine where to truncate pg_subtrans. allDbs
999
999
* must be TRUE for that case, and ignoreVacuum FALSE.
1000
1000
*
1001
- * Note: it's possible for the calculated value to move backwards on repeated
1002
- * calls. The calculated value is conservative, so that anything older is
1003
- * definitely not considered as running by anyone anymore, but the exact
1004
- * value calculated depends on a number of things. For example, if allDbs is
1005
- * TRUE and there are no transactions running in the current database,
1006
- * GetOldestXmin() returns latestCompletedXid. If a transaction begins after
1007
- * that, its xmin will include in-progress transactions in other databases
1008
- * that started earlier, so another call will return an lower value. The
1009
-
BE2E
* return value is also adjusted with vacuum_defer_cleanup_age, so increasing
1010
- * that setting on the fly is an easy way to have GetOldestXmin() move
1011
- * backwards.
1012
- *
1013
1001
* Note: we include all currently running xids in the set of considered xids.
1014
1002
* This ensures that if a just-started xact has not yet set its snapshot,
1015
1003
* when it does set the snapshot it cannot set xmin less than what we compute.
1016
1004
* See notes in src/backend/access/transam/README.
1005
+ *
1006
+ * Note: despite the above, it's possible for the calculated value to move
1007
+ * backwards on repeated calls. The calculated value is conservative, so that
1008
+ * anything older is definitely not considered as running by anyone anymore,
1009
+ * but the exact value calculated depends on a number of things. For example,
1010
+ * if allDbs is FALSE and there are no transactions running in the current
1011
+ * database, GetOldestXmin() returns latestCompletedXid. If a transaction
1012
+ * begins after that, its xmin will include in-progress transactions in other
1013
+ * databases that started earlier, so another call will return a lower value.
1014
+ * Nonetheless it is safe to vacuum a table in the current database with the
1015
+ * first result. There are also replication-related effects: a walsender
1016
+ * process can set its xmin based on transactions that are no longer running
1017
+ * in the master but are still being replayed on the standby, thus possibly
1018
+ * making the GetOldestXmin reading go backwards. In this case there is a
1019
+ * possibility that we lose data that the standby would like to have, but
1020
+ * there is little we can do about that --- data is only protected if the
1021
+ * walsender runs continuously while queries are executed on the standby.
1022
+ * (The Hot Standby code deals with such cases by failing standby queries
1023
+ * that needed to access already-removed data, so there's no integrity bug.)
1024
+ * The return value is also adjusted with vacuum_defer_cleanup_age, so
1025
+ * increasing that setting on the fly is another easy way to make
1026
+ * GetOldestXmin() move backwards, with no consequences for data integrity.
1017
1027
*/
1018
1028
TransactionId
1019
1029
GetOldestXmin (bool allDbs , bool ignoreVacuum )
@@ -1046,7 +1056,7 @@ GetOldestXmin(bool allDbs, bool ignoreVacuum)
1046
1056
1047
1057
if (allDbs ||
1048
1058
proc -> databaseId == MyDatabaseId ||
1049
- proc -> databaseId == 0 ) /* include WalSender */
1059
+ proc -> databaseId == 0 ) /* always include WalSender */
1050
1060
{
1051
1061
/* Fetch xid just once - see GetNewTransactionId */
1052
1062
TransactionId xid = proc -> xid ;
@@ -1092,16 +1102,18 @@ GetOldestXmin(bool allDbs, bool ignoreVacuum)
1092
1102
LWLockRelease (ProcArrayLock );
1093
1103
1094
1104
/*
1095
- * Compute the cutoff XID, being careful not to generate a "permanent"
1096
- * XID. We need do this only on the primary, never on standby .
1105
+ * Compute the cutoff XID by subtracting vacuum_defer_cleanup_age,
1106
+ * being careful not to generate a "permanent" XID .
1097
1107
*
1098
1108
* vacuum_defer_cleanup_age provides some additional "slop" for the
1099
1109
* benefit of hot standby queries on slave servers. This is quick and
1100
1110
* dirty, and perhaps not all that useful unless the master has a
1101
- * predictable transaction rate, but it's what we've got. Note that
1102
- * we are assuming vacuum_defer_cleanup_age isn't large enough to
1103
- * cause wraparound --- so guc.c should limit it to no more than the
1104
- * xidStopLimit threshold in varsup.c.
1111
+ * predictable transaction rate, but it offers some protection when
1112
+ * there's no walsender connection. Note that we are assuming
1113
+ * vacuum_defer_cleanup_age isn't large enough to cause wraparound ---
1114
+ * so guc.c should limit it to no more than the xidStopLimit threshold
1115
+ * in varsup.c. Also note that we intentionally don't apply
1116
+ * vacuum_defer_cleanup_age on standby servers.
1105
1117
*/
1106
1118
result -= vacuum_defer_cleanup_age ;
1107
1119
if (!TransactionIdIsNormal (result ))
0 commit comments