wait_replication_slot_xmin.patch
application/octet-stream
Filename: wait_replication_slot_xmin.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/commands/indexcmds.c | 19 | 0 |
| src/backend/storage/ipc/procarray.c | 12 | 0 |
| src/include/storage/procarray.h | 1 | 0 |
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 0b3b8e98b8..cf3e1d449c 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -424,6 +424,8 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress)
int n_old_snapshots;
int i;
VirtualTransactionId *old_snapshots;
+ TransactionId replication_slot_xmin = InvalidTransactionId;
+ TransactionId replication_slot_catalog_xmin = InvalidTransactionId;
old_snapshots = GetCurrentVirtualXIDs(limitXmin, true, false,
PROC_IS_AUTOVACUUM | PROC_IN_VACUUM
@@ -483,6 +485,23 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress)
if (progress)
pgstat_progress_update_param(PROGRESS_WAITFOR_DONE, i + 1);
}
+
+ do
+ {
+ /*
+ * Wait for the oldest replication slot xmin to exceed limitXmin to prevent
+ * standby being unable to access old version data through the newly built
+ * index.
+ * It is necessary to wait only if replication_slot_xmin is "normal".
+ */
+ CHECK_FOR_INTERRUPTS();
+ GetReplicationSlotXmin(&replication_slot_xmin, &replication_slot_catalog_xmin);
+ if (!TransactionIdIsNormal(replication_slot_xmin))
+ break;
+ if (!NormalTransactionIdPrecedes(replication_slot_xmin, limitXmin))
+ break;
+ pg_usleep(1000000);
+ } while (true);
}
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 80ab026bf5..e314b54fe3 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -2503,6 +2503,18 @@ GetSnapshotData(Snapshot snapshot)
return snapshot;
}
+/*
+ * Get replication_slot_xmin and replication_slot_catalog_xmin from ProcArrayStruct
+ */
+void
+GetReplicationSlotXmin(TransactionId* xmin, TransactionId* catalog_xmin)
+{
+ LWLockAcquire(ProcArrayLock, LW_SHARED);
+ *xmin = procArray->replication_slot_xmin;
+ *catalog_xmin = procArray->replication_slot_catalog_xmin;
+ LWLockRelease(ProcArrayLock);
+}
+
/*
* ProcArrayInstallImportedXmin -- install imported xmin into MyProc->xmin
*
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index d8cae3ce1c..f985aae96d 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -45,6 +45,7 @@ extern int GetMaxSnapshotXidCount(void);
extern int GetMaxSnapshotSubxidCount(void);
extern Snapshot GetSnapshotData(Snapshot snapshot);
+extern void GetReplicationSlotXmin(TransactionId* xmin, TransactionId* catalog_xmin);
extern bool ProcArrayInstallImportedXmin(TransactionId xmin,
VirtualTransactionId *sourcevxid);