Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9e149c8

Browse files
committed
Fix and document lock handling for in-memory replication slot data
While debugging issues on HEAD for the new slot forwarding feature ofPostgres 11, some monitoring of the code surrounding in-memory slot datahas proved that the lock handling may cause inconsistent data to be readby read-only callers of slot functions, particularlypg_get_replication_slots() which fetches data for the system viewpg_replication_slots, or modules looking directly at slot information.The code paths involved in those problems concern logical decodinginitialization (down to 9.4) and WAL reservation for slots (new as of10).A set of comments documenting all the lock handlings, particularly thedependency with LW locks for slots and the in_use flag as well as theinternal mutex lock is added, based on a suggested by Simon Riggs.Some of the fixed code exists down to 9.4 where WAL decoding has beenintroduced, but as those race conditions are really unlikely going tohappen as those concern code paths for slot and decoding creation, justfix the problem on HEAD.Author: Michael PaquierDiscussion:https://postgr.es/m/20180528085747.GA27845@paquier.xyz
1 parent86a2218 commit9e149c8

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

‎src/backend/replication/logical/logical.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,12 @@ CreateInitDecodingContext(char *plugin,
297297

298298
xmin_horizon=GetOldestSafeDecodingTransactionId(!need_full_snapshot);
299299

300+
SpinLockAcquire(&slot->mutex);
300301
slot->effective_catalog_xmin=xmin_horizon;
301302
slot->data.catalog_xmin=xmin_horizon;
302303
if (need_full_snapshot)
303304
slot->effective_xmin=xmin_horizon;
305+
SpinLockRelease(&slot->mutex);
304306

305307
ReplicationSlotsComputeRequiredXmin(true);
306308

@@ -445,13 +447,14 @@ void
445447
DecodingContextFindStartpoint(LogicalDecodingContext*ctx)
446448
{
447449
XLogRecPtrstartptr;
450+
ReplicationSlot*slot=ctx->slot;
448451

449452
/* Initialize from where to start reading WAL. */
450-
startptr=ctx->slot->data.restart_lsn;
453+
startptr=slot->data.restart_lsn;
451454

452455
elog(DEBUG1,"searching for logical decoding starting point, starting at %X/%X",
453-
(uint32) (ctx->slot->data.restart_lsn >>32),
454-
(uint32)ctx->slot->data.restart_lsn);
456+
(uint32) (slot->data.restart_lsn >>32),
457+
(uint32)slot->data.restart_lsn);
455458

456459
/* Wait for a consistent starting point */
457460
for (;;)
@@ -477,7 +480,9 @@ DecodingContextFindStartpoint(LogicalDecodingContext *ctx)
477480
CHECK_FOR_INTERRUPTS();
478481
}
479482

480-
ctx->slot->data.confirmed_flush=ctx->reader->EndRecPtr;
483+
SpinLockAcquire(&slot->mutex);
484+
slot->data.confirmed_flush=ctx->reader->EndRecPtr;
485+
SpinLockRelease(&slot->mutex);
481486
}
482487

483488
/*

‎src/backend/replication/slot.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,9 @@ ReplicationSlotReserveWal(void)
10161016
XLogRecPtrflushptr;
10171017

10181018
/* start at current insert position */
1019+
SpinLockAcquire(&slot->mutex);
10191020
slot->data.restart_lsn=GetXLogInsertRecPtr();
1021+
SpinLockRelease(&slot->mutex);
10201022

10211023
/* make sure we have enough information to start */
10221024
flushptr=LogStandbySnapshot();
@@ -1026,7 +1028,9 @@ ReplicationSlotReserveWal(void)
10261028
}
10271029
else
10281030
{
1031+
SpinLockAcquire(&slot->mutex);
10291032
slot->data.restart_lsn=GetRedoRecPtr();
1033+
SpinLockRelease(&slot->mutex);
10301034
}
10311035

10321036
/* prevent WAL removal as fast as possible */

‎src/include/replication/slot.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ typedef struct ReplicationSlotPersistentData
8686

8787
/*
8888
* Shared memory state of a single replication slot.
89+
*
90+
* The in-memory data of replication slots follows a locking model based
91+
* on two linked concepts:
92+
* - A replication slot's in_use flag is switched when added or discarded using
93+
* the LWLock ReplicationSlotControlLock, which needs to be hold in exclusive
94+
* mode when updating the flag by the backend owning the slot and doing the
95+
* operation, while readers (concurrent backends not owning the slot) need
96+
* to hold it in shared mode when looking at replication slot data.
97+
* - Individual fields are protected by mutex where only the backend owning
98+
* the slot is authorized to update the fields from its own slot. The
99+
* backend owning the slot does not need to take this lock when reading its
100+
* own fields, while concurrent backends not owning this slot should take the
101+
* lock when reading this slot's data.
89102
*/
90103
typedefstructReplicationSlot
91104
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp