]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Prevent tuples to be marked as dead in subtransactions on standbys
authorMichael Paquier <michael@paquier.xyz>
Tue, 12 Dec 2023 16:05:29 +0000 (17:05 +0100)
committerMichael Paquier <michael@paquier.xyz>
Tue, 12 Dec 2023 16:05:29 +0000 (17:05 +0100)
Dead tuples are ignored and are not marked as dead during recovery, as
it can lead to MVCC issues on a standby because its xmin may not match
with the primary.  This information is tracked by a field called
"xactStartedInRecovery" in the transaction state data, switched on when
starting a transaction in recovery.

Unfortunately, this information was not correctly tracked when starting
a subtransaction, because the transaction state used for the
subtransaction did not update "xactStartedInRecovery" based on the state
of its parent.  This would cause index scans done in subtransactions to
return inconsistent data, depending on how the xmin of the primary
and/or the standby evolved.

This is broken since the introduction of hot standby in efc16ea52067, so
backpatch all the way down.

Author: Fei Changhong
Reviewed-by: Kyotaro Horiguchi
Discussion: https://postgr.es/m/tencent_C4D907A5093C071A029712E73B43C6512706@qq.com
Backpatch-through: 12

src/backend/access/transam/xact.c

index e0c7ad11caaa8c8b147bd1e42e9ee706be15cf06..7a3d9b4b01269474a906b42f3ec11613d5f2539b 100644 (file)
@@ -5265,6 +5265,7 @@ PushTransaction(void)
        s->blockState = TBLOCK_SUBBEGIN;
        GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
        s->prevXactReadOnly = XactReadOnly;
+       s->startedInRecovery = p->startedInRecovery;
        s->parallelModeLevel = 0;
        s->topXidLogged = false;