Avoid special XID snapshotConflictHorizon values.
authorPeter Geoghegan <[email protected]>
Mon, 2 Jan 2023 18:16:51 +0000 (10:16 -0800)
committerPeter Geoghegan <[email protected]>
Mon, 2 Jan 2023 18:16:51 +0000 (10:16 -0800)
Don't allow VACUUM to WAL-log the value FrozenTransactionId as the
snapshotConflictHorizon of freezing or visibility map related WAL
records.

The only special XID value that's an allowable snapshotConflictHorizon
is InvalidTransactionId, which is interpreted as "record definitely
doesn't require a recovery conflict".

Author: Peter Geoghegan <[email protected]>
Discussion: https://postgr.es/m/CAH2-WznuNGSzF8v6OsgjaC5aYsb3cZ6HW6MLm30X0d65cmSH6A@mail.gmail.com

src/backend/access/heap/vacuumlazy.c
src/backend/storage/ipc/standby.c

index 9923994b50efe86b60201727e7438f8654611aef..5d8fd2fb72742e4cf30c72586c6126079fee3ce6 100644 (file)
@@ -1698,7 +1698,8 @@ retry:
                    }
 
                    /* Track newest xmin on page. */
-                   if (TransactionIdFollows(xmin, prunestate->visibility_cutoff_xid))
+                   if (TransactionIdFollows(xmin, prunestate->visibility_cutoff_xid) &&
+                       TransactionIdIsNormal(xmin))
                        prunestate->visibility_cutoff_xid = xmin;
                }
                break;
@@ -1863,7 +1864,7 @@ retry:
         * because visibility_cutoff_xid will be logged by our caller in a
         * moment.
         */
-       Assert(cutoff == FrozenTransactionId ||
+       Assert(!TransactionIdIsValid(cutoff) ||
               cutoff == prunestate->visibility_cutoff_xid);
    }
 #endif
@@ -3293,7 +3294,8 @@ heap_page_is_all_visible(LVRelState *vacrel, Buffer buf,
                    }
 
                    /* Track newest xmin on page. */
-                   if (TransactionIdFollows(xmin, *visibility_cutoff_xid))
+                   if (TransactionIdFollows(xmin, *visibility_cutoff_xid) &&
+                       TransactionIdIsNormal(xmin))
                        *visibility_cutoff_xid = xmin;
 
                    /* Check whether this tuple is already frozen or not */
index f43229dfda610b0f3e0001944567bcc9d09d15b4..ede00fee9350bed62b3142d5a7c98e57b3a29d72 100644 (file)
@@ -493,6 +493,7 @@ ResolveRecoveryConflictWithSnapshot(TransactionId snapshotConflictHorizon,
    if (!TransactionIdIsValid(snapshotConflictHorizon))
        return;
 
+   Assert(TransactionIdIsNormal(snapshotConflictHorizon));
    backends = GetConflictingVirtualXIDs(snapshotConflictHorizon,
                                         locator.dbOid);
    ResolveRecoveryConflictWithVirtualXIDs(backends,