summaryrefslogtreecommitdiff
path: root/src/backend/replication/logical/worker.c
diff options
context:
space:
mode:
authorAmit Kapila <akapila@postgresql.org>2021-05-21 07:54:27 +0530
committerAmit Kapila <akapila@postgresql.org>2021-05-21 07:54:27 +0530
commit6d0eb38557155855539cd007f04736dc3b2ba16f (patch)
tree36ed3c8e60373f219023bc0e1398a5eff8f9bcae /src/backend/replication/logical/worker.c
parentf21fadafaf0fb5ea4c9622d915972651273d62ce (diff)
Fix deadlock for multiple replicating truncates of the same table.
While applying the truncate change, the logical apply worker acquires RowExclusiveLock on the relation being truncated. This allowed truncate on the relation at a time by two apply workers which lead to a deadlock. The reason was that one of the workers after updating the pg_class tuple tries to acquire SHARE lock on the relation and started to wait for the second worker which has acquired RowExclusiveLock on the relation. And when the second worker tries to update the pg_class tuple, it starts to wait for the first worker which leads to a deadlock. Fix it by acquiring AccessExclusiveLock on the relation before applying the truncate change as we do for normal truncate operation. Author: Peter Smith, test case by Haiying Tang Reviewed-by: Dilip Kumar, Amit Kapila Backpatch-through: 11 Discussion: https://postgr.es/m/CAHut+PsNm43p0jM+idTvWwiGZPcP0hGrHMPK9TOAkc+a4UpUqw@mail.gmail.com
Diffstat (limited to 'src/backend/replication/logical/worker.c')
-rw-r--r--src/backend/replication/logical/worker.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index 1432554d5a7..60bf7f7ee9c 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -1818,6 +1818,7 @@ apply_handle_truncate(StringInfo s)
List *relids = NIL;
List *relids_logged = NIL;
ListCell *lc;
+ LOCKMODE lockmode = AccessExclusiveLock;
if (handle_streamed_transaction(LOGICAL_REP_MSG_TRUNCATE, s))
return;
@@ -1831,14 +1832,14 @@ apply_handle_truncate(StringInfo s)
LogicalRepRelId relid = lfirst_oid(lc);
LogicalRepRelMapEntry *rel;
- rel = logicalrep_rel_open(relid, RowExclusiveLock);
+ rel = logicalrep_rel_open(relid, lockmode);
if (!should_apply_changes_for_rel(rel))
{
/*
* The relation can't become interesting in the middle of the
* transaction so it's safe to unlock it.
*/
- logicalrep_rel_close(rel, RowExclusiveLock);
+ logicalrep_rel_close(rel, lockmode);
continue;
}
@@ -1856,7 +1857,7 @@ apply_handle_truncate(StringInfo s)
{
ListCell *child;
List *children = find_all_inheritors(rel->localreloid,
- RowExclusiveLock,
+ lockmode,
NULL);
foreach(child, children)
@@ -1876,7 +1877,7 @@ apply_handle_truncate(StringInfo s)
*/
if (RELATION_IS_OTHER_TEMP(childrel))
{
- table_close(childrel, RowExclusiveLock);
+ table_close(childrel, lockmode);
continue;
}