Skip to content

Commit 7318f24

Browse files
author
Amit Kapila
committed
Don't retreat slot's confirmed_flush LSN.
Prevent moving the confirmed_flush backwards, as this could lead to data duplication issues caused by replicating already replicated changes. This can happen when a client acknowledges an LSN it doesn't have to do anything for, and thus didn't store persistently. After a restart, the client can send the prior LSN that it stored persistently as an acknowledgement, but we need to ignore such an LSN to avoid retreating confirm_flush LSN. Diagnosed-by: Zhijie Hou <houzj.fnst@fujitsu.com> Author: shveta malik <shveta.malik@gmail.com> Reviewed-by: Amit Kapila <amit.kapila16@gmail.com> Reviewed-by: Dilip Kumar <dilipbalaut@gmail.com> Tested-by: Nisha Moond <nisha.moond412@gmail.com> Backpatch-through: 13 Discussion: https://postgr.es/m/CAJpy0uDZ29P=BYB1JDWMCh-6wXaNqMwG1u1mB4=10Ly0x7HhwQ@mail.gmail.com Discussion: https://postgr.es/m/OS0PR01MB57164AB5716AF2E477D53F6F9489A@OS0PR01MB5716.jpnprd01.prod.outlook.com
1 parent 5355a24 commit 7318f24

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

src/backend/replication/logical/logical.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,7 +1847,19 @@ LogicalConfirmReceivedLocation(XLogRecPtr lsn)
18471847

18481848
SpinLockAcquire(&MyReplicationSlot->mutex);
18491849

1850-
MyReplicationSlot->data.confirmed_flush = lsn;
1850+
/*
1851+
* Prevent moving the confirmed_flush backwards, as this could lead to
1852+
* data duplication issues caused by replicating already replicated
1853+
* changes.
1854+
*
1855+
* This can happen when a client acknowledges an LSN it doesn't have
1856+
* to do anything for, and thus didn't store persistently. After a
1857+
* restart, the client can send the prior LSN that it stored
1858+
* persistently as an acknowledgement, but we need to ignore such an
1859+
* LSN. See similar case handling in CreateDecodingContext.
1860+
*/
1861+
if (lsn > MyReplicationSlot->data.confirmed_flush)
1862+
MyReplicationSlot->data.confirmed_flush = lsn;
18511863

18521864
/* if we're past the location required for bumping xmin, do so */
18531865
if (MyReplicationSlot->candidate_xmin_lsn != InvalidXLogRecPtr &&
@@ -1912,7 +1924,14 @@ LogicalConfirmReceivedLocation(XLogRecPtr lsn)
19121924
else
19131925
{
19141926
SpinLockAcquire(&MyReplicationSlot->mutex);
1915-
MyReplicationSlot->data.confirmed_flush = lsn;
1927+
1928+
/*
1929+
* Prevent moving the confirmed_flush backwards. See comments above
1930+
* for the details.
1931+
*/
1932+
if (lsn > MyReplicationSlot->data.confirmed_flush)
1933+
MyReplicationSlot->data.confirmed_flush = lsn;
1934+
19161935
SpinLockRelease(&MyReplicationSlot->mutex);
19171936
}
19181937
}

0 commit comments

Comments
 (0)