aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2023-12-12 17:05:29 +0100
committerMichael Paquier <michael@paquier.xyz>2023-12-12 17:05:29 +0100
commitf5d8f59cae3e0befda51a97cc3715fa6caf7105d (patch)
tree62177ca44ea9e6a18a5f144573216e4656b6c106
parent419b6cb885a5fcb215ce86dcda441bd7dbfac202 (diff)
downloadpostgresql-f5d8f59cae3e0befda51a97cc3715fa6caf7105d.tar.gz
postgresql-f5d8f59cae3e0befda51a97cc3715fa6caf7105d.zip
Prevent tuples to be marked as dead in subtransactions on standbys
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
-rw-r--r--src/backend/access/transam/xact.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index e0c7ad11caa..7a3d9b4b012 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -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;