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

Commitb47ea4f

Browse files
author
Amit Kapila
committed
Fix an undetected deadlock due to apply worker.
The apply worker needs to update the state of the subscription tables to'READY' during the synchronization phase which requires locking thecorresponding subscription. The apply worker also waits for thesubscription tables to reach the 'SYNCDONE' state after holding the lockson the subscription and the wait is done using WaitLatch. The 'SYNCDONE'state is changed by tablesync workers again by locking the correspondingsubscription. Both the state updates use AccessShareLock mode to lock thesubscription, so they can't block each other. However, a backend cansimultaneously try to acquire a lock on the same subscription usingAccessExclusiveLock mode to alter the subscription. Now, the backend'swait on a lock can sneak in between the apply worker and table sync workercausing deadlock.In other words, apply_worker waits for tablesync worker which waits forbackend, and backend waits for apply worker. This is not detected by thedeadlock detector because apply worker uses WaitLatch.The fix is to release existing locks in apply worker before it starts towait for tablesync worker to change the state.Reported-by: Tomas VondraAuthor: Shlok KyalReviewed-by: Amit Kapila, Peter SmithBackpatch-through: 12Discussion:https://postgr.es/m/d291bb50-12c4-e8af-2af2-7bb9bb4d8e3e@enterprisedb.com
1 parent7d5a740 commitb47ea4f

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -457,15 +457,25 @@ process_syncing_tables_for_apply(XLogRecPtr current_lsn)
457457
/* Now safe to release the LWLock */
458458
LWLockRelease(LogicalRepWorkerLock);
459459

460+
if (started_tx)
461+
{
462+
/*
463+
* We must commit the existing transaction to release
464+
* the existing locks before entering a busy loop.
465+
* This is required to avoid any undetected deadlocks
466+
* due to any existing lock as deadlock detector won't
467+
* be able to detect the waits on the latch.
468+
*/
469+
CommitTransactionCommand();
470+
pgstat_report_stat(false);
471+
}
472+
460473
/*
461474
* Enter busy loop and wait for synchronization worker to
462475
* reach expected state (or die trying).
463476
*/
464-
if (!started_tx)
465-
{
466-
StartTransactionCommand();
467-
started_tx= true;
468-
}
477+
StartTransactionCommand();
478+
started_tx= true;
469479

470480
wait_for_relation_state_change(rstate->relid,
471481
SUBREL_STATE_SYNCDONE);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp