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

Commit8edacab

Browse files
committed
Fix DROP SUBSCRIPTION hang
When ALTER SUBSCRIPTION DISABLE is run in the same transaction beforeDROP SUBSCRIPTION, the latter will hang because workers will still berunning, not having seen the DISABLE committed, and DROP SUBSCRIPTIONwill wait until the workers have vacated the replication origin slots.Previously, DROP SUBSCRIPTION killed the logical replication workersimmediately only if it was going to drop the replication slot, otherwiseit scheduled the worker killing for the end of the transaction, as aresult of7e174fa. This, however,causes the present problem. To fix, kill the workers immediately in allcases. This covers all cases: A subscription that doesn't have areplication slot must be disabled. It was either disabled in the sametransaction, or it was already disabled before the current transaction,but then there shouldn't be any workers left and this won't make adifference.Reported-by: Arseny Sher <a.sher@postgrespro.ru>Discussion:https://www.postgresql.org/message-id/flat/87mv6av84w.fsf%40ars-thinkpad
1 parent68ab9ac commit8edacab

File tree

2 files changed

+63
-7
lines changed

2 files changed

+63
-7
lines changed

‎src/backend/commands/subscriptioncmds.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -909,9 +909,17 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
909909
ReleaseSysCache(tup);
910910

911911
/*
912-
* If we are dropping the replication slot, stop all the subscription
913-
* workers immediately, so that the slot becomes accessible. Otherwise
914-
* just schedule the stopping for the end of the transaction.
912+
* Stop all the subscription workers immediately.
913+
*
914+
* This is necessary if we are dropping the replication slot, so that the
915+
* slot becomes accessible.
916+
*
917+
* It is also necessary if the subscription is disabled and was disabled
918+
* in the same transaction. Then the workers haven't seen the disabling
919+
* yet and will still be running, leading to hangs later when we want to
920+
* drop the replication origin. If the subscription was disabled before
921+
* this transaction, then there shouldn't be any workers left, so this
922+
* won't make a difference.
915923
*
916924
* New workers won't be started because we hold an exclusive lock on the
917925
* subscription till the end of the transaction.
@@ -923,10 +931,7 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
923931
{
924932
LogicalRepWorker*w= (LogicalRepWorker*)lfirst(lc);
925933

926-
if (slotname)
927-
logicalrep_worker_stop(w->subid,w->relid);
928-
else
929-
logicalrep_worker_stop_at_commit(w->subid,w->relid);
934+
logicalrep_worker_stop(w->subid,w->relid);
930935
}
931936
list_free(subworkers);
932937

‎src/test/subscription/t/007_ddl.pl

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Test some logical replication DDL behavior
2+
use strict;
3+
use warnings;
4+
use PostgresNode;
5+
use TestLib;
6+
use Test::Moretests=> 1;
7+
8+
subwait_for_caught_up
9+
{
10+
my ($node,$appname) =@_;
11+
12+
$node->poll_query_until('postgres',
13+
"SELECT pg_current_wal_lsn() <= replay_lsn FROM pg_stat_replication WHERE application_name = '$appname';"
14+
)ordie"Timed out while waiting for subscriber to catch up";
15+
}
16+
17+
my$node_publisher = get_new_node('publisher');
18+
$node_publisher->init(allows_streaming=>'logical');
19+
$node_publisher->start;
20+
21+
my$node_subscriber = get_new_node('subscriber');
22+
$node_subscriber->init(allows_streaming=>'logical');
23+
$node_subscriber->start;
24+
25+
my$ddl ="CREATE TABLE test1 (a int, b text);";
26+
$node_publisher->safe_psql('postgres',$ddl);
27+
$node_subscriber->safe_psql('postgres',$ddl);
28+
29+
my$publisher_connstr =$node_publisher->connstr .' dbname=postgres';
30+
my$appname ='replication_test';
31+
32+
$node_publisher->safe_psql('postgres',
33+
"CREATE PUBLICATION mypub FOR ALL TABLES;");
34+
$node_subscriber->safe_psql('postgres',
35+
"CREATE SUBSCRIPTION mysub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION mypub;"
36+
);
37+
38+
wait_for_caught_up($node_publisher,$appname);
39+
40+
$node_subscriber->safe_psql('postgres',q{
41+
BEGIN;
42+
ALTER SUBSCRIPTION mysub DISABLE;
43+
ALTER SUBSCRIPTION mysub SET (slot_name = NONE);
44+
DROP SUBSCRIPTION mysub;
45+
COMMIT;
46+
});
47+
48+
pass"subscription disable and drop in same transaction did not hang";
49+
50+
$node_subscriber->stop;
51+
$node_publisher->stop;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp