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

Commit272adf4

Browse files
committed
Disallow CREATE/DROP SUBSCRIPTION in transaction block
Disallow CREATE SUBSCRIPTION and DROP SUBSCRIPTION in a transactionblock when the replication slot is to be created or dropped, since thatcannot be rolled back.based on patch by Masahiko Sawada <sawada.mshk@gmail.com>
1 parent3473027 commit272adf4

File tree

7 files changed

+66
-15
lines changed

7 files changed

+66
-15
lines changed

‎doc/src/sgml/ref/create_subscription.sgml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ CREATE SUBSCRIPTION <replaceable class="PARAMETER">subscription_name</replaceabl
5151
subscription at the commit of the transaction where this command is run.
5252
</para>
5353

54+
<para>
55+
<command>CREATE SUBSCRIPTION</command> cannot be executed inside a
56+
transaction block when <literal>CREATE SLOT</literal> is specified.
57+
</para>
58+
5459
<para>
5560
Additional info about subscriptions and logical replication as a whole
5661
can is available at <xref linkend="logical-replication-subscription"> and

‎doc/src/sgml/ref/drop_subscription.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ DROP SUBSCRIPTION [ IF EXISTS ] <replaceable class="parameter">name</replaceable
3838
</para>
3939

4040
<para>
41-
The replication worker associated with the subscription will not stop until
42-
after thetransactionthat issued this command has committed.
41+
<command>DROP SUBSCRIPTION</command> cannot be executed inside a
42+
transactionblock when <literal>DROP SLOT</literal> is specified.
4343
</para>
4444
</refsect1>
4545

‎src/backend/commands/subscriptioncmds.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include"access/heapam.h"
2020
#include"access/htup_details.h"
21+
#include"access/xact.h"
2122

2223
#include"catalog/indexing.h"
2324
#include"catalog/objectaccess.h"
@@ -204,7 +205,7 @@ publicationListToArray(List *publist)
204205
* Create new subscription.
205206
*/
206207
ObjectAddress
207-
CreateSubscription(CreateSubscriptionStmt*stmt)
208+
CreateSubscription(CreateSubscriptionStmt*stmt,boolisTopLevel)
208209
{
209210
Relationrel;
210211
ObjectAddressmyself;
@@ -221,6 +222,23 @@ CreateSubscription(CreateSubscriptionStmt *stmt)
221222
boolcreate_slot;
222223
List*publications;
223224

225+
/*
226+
* Parse and check options.
227+
* Connection and publication should not be specified here.
228+
*/
229+
parse_subscription_options(stmt->options,NULL,NULL,
230+
&enabled_given,&enabled,
231+
&create_slot,&slotname);
232+
233+
/*
234+
* Since creating a replication slot is not transactional, rolling back
235+
* the transaction leaves the created replication slot. So we cannot run
236+
* CREATE SUBSCRIPTION inside a transaction block if creating a
237+
* replication slot.
238+
*/
239+
if (create_slot)
240+
PreventTransactionChain(isTopLevel,"CREATE SUBSCRIPTION ... CREATE SLOT");
241+
224242
if (!superuser())
225243
ereport(ERROR,
226244
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
@@ -239,13 +257,6 @@ CreateSubscription(CreateSubscriptionStmt *stmt)
239257
stmt->subname)));
240258
}
241259

242-
/*
243-
* Parse and check options.
244-
* Connection and publication should not be specified here.
245-
*/
246-
parse_subscription_options(stmt->options,NULL,NULL,
247-
&enabled_given,&enabled,
248-
&create_slot,&slotname);
249260
if (slotname==NULL)
250261
slotname=stmt->subname;
251262

@@ -424,7 +435,7 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
424435
* Drop a subscription
425436
*/
426437
void
427-
DropSubscription(DropSubscriptionStmt*stmt)
438+
DropSubscription(DropSubscriptionStmt*stmt,boolisTopLevel)
428439
{
429440
Relationrel;
430441
ObjectAddressmyself;
@@ -441,6 +452,15 @@ DropSubscription(DropSubscriptionStmt *stmt)
441452
WalReceiverConn*wrconn=NULL;
442453
StringInfoDatacmd;
443454

455+
/*
456+
* Since dropping a replication slot is not transactional, the replication
457+
* slot stays dropped even if the transaction rolls back. So we cannot
458+
* run DROP SUBSCRIPTION inside a transaction block if dropping the
459+
* replication slot.
460+
*/
461+
if (stmt->drop_slot)
462+
PreventTransactionChain(isTopLevel,"DROP SUBSCRIPTION ... DROP SLOT");
463+
444464
rel=heap_open(SubscriptionRelationId,RowExclusiveLock);
445465

446466
tup=SearchSysCache2(SUBSCRIPTIONNAME,MyDatabaseId,

‎src/backend/tcop/utility.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,15 +1609,16 @@ ProcessUtilitySlow(ParseState *pstate,
16091609
break;
16101610

16111611
caseT_CreateSubscriptionStmt:
1612-
address=CreateSubscription((CreateSubscriptionStmt*)parsetree);
1612+
address=CreateSubscription((CreateSubscriptionStmt*)parsetree,
1613+
isTopLevel);
16131614
break;
16141615

16151616
caseT_AlterSubscriptionStmt:
16161617
address=AlterSubscription((AlterSubscriptionStmt*)parsetree);
16171618
break;
16181619

16191620
caseT_DropSubscriptionStmt:
1620-
DropSubscription((DropSubscriptionStmt*)parsetree);
1621+
DropSubscription((DropSubscriptionStmt*)parsetree,isTopLevel);
16211622
/* no commands stashed for DROP */
16221623
commandCollected= true;
16231624
break;

‎src/include/commands/subscriptioncmds.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818
#include"catalog/objectaddress.h"
1919
#include"nodes/parsenodes.h"
2020

21-
externObjectAddressCreateSubscription(CreateSubscriptionStmt*stmt);
21+
externObjectAddressCreateSubscription(CreateSubscriptionStmt*stmt,
22+
boolisTopLevel);
2223
externObjectAddressAlterSubscription(AlterSubscriptionStmt*stmt);
23-
externvoidDropSubscription(DropSubscriptionStmt*stmt);
24+
externvoidDropSubscription(DropSubscriptionStmt*stmt,boolisTopLevel);
2425

2526
externObjectAddressAlterSubscriptionOwner(constchar*name,OidnewOwnerId);
2627
externvoidAlterSubscriptionOwner_oid(Oidsubid,OidnewOwnerId);

‎src/test/regress/expected/subscription.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ ERROR: syntax error at or near "PUBLICATION"
1414
LINE 1: CREATE SUBSCRIPTION testsub PUBLICATION foo;
1515
^
1616
set client_min_messages to error;
17+
-- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block
18+
BEGIN;
19+
CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub WITH (CREATE SLOT);
20+
ERROR: CREATE SUBSCRIPTION ... CREATE SLOT cannot run inside a transaction block
21+
COMMIT;
1722
CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub;
1823
ERROR: invalid connection string syntax: missing "=" after "testconn" in connection info string
1924

@@ -69,6 +74,13 @@ ALTER SUBSCRIPTION testsub RENAME TO testsub_foo;
6974
testsub_foo | regress_subscription_user | f | {testpub,testpub1}
7075
(1 row)
7176

77+
-- fail - cannot do DROP SUBSCRIPTION DROP SLOT inside transaction block
78+
BEGIN;
79+
DROP SUBSCRIPTION testsub DROP SLOT;
80+
ERROR: DROP SUBSCRIPTION ... DROP SLOT cannot run inside a transaction block
81+
COMMIT;
82+
BEGIN;
7283
DROP SUBSCRIPTION testsub_foo NODROP SLOT;
84+
COMMIT;
7385
RESET SESSION AUTHORIZATION;
7486
DROP ROLE regress_subscription_user;

‎src/test/regress/sql/subscription.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ CREATE SUBSCRIPTION testsub CONNECTION 'foo';
1212
CREATE SUBSCRIPTION testsub PUBLICATION foo;
1313

1414
set client_min_messages to error;
15+
-- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block
16+
BEGIN;
17+
CREATE SUBSCRIPTION testsub CONNECTION'testconn' PUBLICATION testpub WITH (CREATE SLOT);
18+
COMMIT;
19+
1520
CREATE SUBSCRIPTION testsub CONNECTION'testconn' PUBLICATION testpub;
1621
CREATE SUBSCRIPTION testsub CONNECTION'dbname=doesnotexist' PUBLICATION testpub WITH (DISABLED, NOCREATE SLOT);
1722
reset client_min_messages;
@@ -42,7 +47,14 @@ ALTER SUBSCRIPTION testsub RENAME TO testsub_foo;
4247

4348
\dRs
4449

50+
-- fail - cannot do DROP SUBSCRIPTION DROP SLOT inside transaction block
51+
BEGIN;
52+
DROP SUBSCRIPTION testsub DROP SLOT;
53+
COMMIT;
54+
55+
BEGIN;
4556
DROP SUBSCRIPTION testsub_foo NODROP SLOT;
57+
COMMIT;
4658

4759
RESET SESSION AUTHORIZATION;
4860
DROP ROLE regress_subscription_user;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp