Skip to content

Commit ad5eaf3

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 f8db5c7 commit ad5eaf3

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
@@ -1828,7 +1828,19 @@ LogicalConfirmReceivedLocation(XLogRecPtr lsn)
18281828

18291829
SpinLockAcquire(&MyReplicationSlot->mutex);
18301830

1831-
MyReplicationSlot->data.confirmed_flush = lsn;
1831+
/*
1832+
* Prevent moving the confirmed_flush backwards, as this could lead to
1833+
* data duplication issues caused by replicating already replicated
1834+
* changes.
1835+
*
1836+
* This can happen when a client acknowledges an LSN it doesn't have
1837+
* to do anything for, and thus didn't store persistently. After a
1838+
* restart, the client can send the prior LSN that it stored
1839+
* persistently as an acknowledgement, but we need to ignore such an
1840+
* LSN. See similar case handling in CreateDecodingContext.
1841+
*/
1842+
if (lsn > MyReplicationSlot->data.confirmed_flush)
1843+
MyReplicationSlot->data.confirmed_flush = lsn;
18321844

18331845
/* if we're past the location required for bumping xmin, do so */
18341846
if (MyReplicationSlot->candidate_xmin_lsn != InvalidXLogRecPtr &&
@@ -1893,7 +1905,14 @@ LogicalConfirmReceivedLocation(XLogRecPtr lsn)
18931905
else
18941906
{
18951907
SpinLockAcquire(&MyReplicationSlot->mutex);
1896-
MyReplicationSlot->data.confirmed_flush = lsn;
1908+
1909+
/*
1910+
* Prevent moving the confirmed_flush backwards. See comments above
1911+
* for the details.
1912+
*/
1913+
if (lsn > MyReplicationSlot->data.confirmed_flush)
1914+
MyReplicationSlot->data.confirmed_flush = lsn;
1915+
18971916
SpinLockRelease(&MyReplicationSlot->mutex);
18981917
}
18991918
}

0 commit comments

Comments
 (0)