Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mwi5O-0005hh-Dj for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Dec 2021 09:57:34 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1mwi5N-0005ol-3Z for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Dec 2021 09:57:33 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mwi5M-0005ob-NV for pgsql-hackers@lists.postgresql.org; Mon, 13 Dec 2021 09:57:32 +0000 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1mwi5K-0005Ye-E4 for pgsql-hackers@lists.postgresql.org; Mon, 13 Dec 2021 09:57:32 +0000 Received: by mail-wr1-x429.google.com with SMTP id u17so26031723wrt.3 for ; Mon, 13 Dec 2021 01:57:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=qdigZy1ezHl3qzMA3lkZgoq3BdzVQnNZCxmQxK8DwrA=; b=KIGaIKZRW8oZkLPljRCb1uHABPOhbSOoq+bs9RLmOl1fvv8JlVxJeZ372ekGQubn6k NKcDPCFuu3nfK4Des+Wok1N05Ij/JzJMq43D/mCLtHL/KE+3En/2IhhNSZ8BszP5scRm c4Xa3XfRSydGj3c2iU19i/iQ8fyjOuMGtNjM9ZGmiEMKa5ZoxMwstYe2ePQt0Vl56Ca3 dtz4jsG4BoHBAN9bIGtvj/r6MAseCPspMlrC0OFeJNfqY9Ex7cWQfQ2CcgT2F/XRA4lg Uaf1M6WSDu/94AbrikeysJxl3+kzaHkF3U5NESP+BdpZYvCIOj3BNTXyyv7oM7EImEsj Qz1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=qdigZy1ezHl3qzMA3lkZgoq3BdzVQnNZCxmQxK8DwrA=; b=ewrvjAioXcwUcnN3jLp85GVa2Udu/OUIGZcekjGYa4urASXmPD1XEfYGWfAEAhQCh3 40q3UUwA/VB/fyY8AMo+Ppd1XpFcIRQBpKGsqdbbCbmXPnzH4tryaN4QGIngDlKIsR6e GiiNfhYLY/6dwwDGXASF7KIgpiG0gbMq/P9b77p6tOJnVJsD6cVILF1tQKG1P9KLNqJv 9earZ9qK45ymhNZaGkcLoaN90EuU5iNczt0nefGazqdgDHIYELK+JMHSVpMlFphhIa9F c38Nusj89zjg3rbA9Glgh9bLeseUC7cKWjiT8Cc/230XTAF4vDCgMVslrRenlftUZVe+ hFMA== X-Gm-Message-State: AOAM531nYDXs+jrIg+r3pizFWyDiZbv+1/YAsGxoOS44QKjjeZeoD9lr FCwuTeeC6g/DfQaVvao7dqxvFVhk5W+JmwHQu2s= X-Google-Smtp-Source: ABdhPJzUeptjVRefvNOB4fvKrjVpbvZmn4Ys6Lusw8UDO5fEhon/zx6Jf2IhS6tG+egRbxRpfTUVKV+rblTsSeIjTCY= X-Received: by 2002:adf:f151:: with SMTP id y17mr30999340wro.153.1639389449354; Mon, 13 Dec 2021 01:57:29 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: vignesh C Date: Mon, 13 Dec 2021 15:27:17 +0530 Message-ID: Subject: Re: Optionally automatically disable logical replication subscriptions on error To: "osumi.takamichi@fujitsu.com" Cc: Greg Nancarrow , Amit Kapila , Masahiko Sawada , Mark Dilger , "Smith, Peter" , PostgreSQL Hackers Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Mon, Dec 6, 2021 at 4:22 PM osumi.takamichi@fujitsu.com wrote: > > On Monday, December 6, 2021 1:16 PM Greg Nancarrow wrote: > > On Sat, Dec 4, 2021 at 12:20 AM osumi.takamichi@fujitsu.com > > wrote: > > > > > > Hi, I've made a new patch v11 that incorporated suggestions described > > above. > > > > > > > Some review comments for the v11 patch: > Thank you for your reviews ! > > > doc/src/sgml/ref/create_subscription.sgml > > (1) Possible wording improvement? > > > > BEFORE: > > + Specifies whether the subscription should be automatically disabled > > + if replicating data from the publisher triggers errors. The default > > + is false. > > AFTER: > > + Specifies whether the subscription should be automatically disabled > > + if any errors are detected by subscription workers during data > > + replication from the publisher. The default is false. > Fixed. > > > src/backend/replication/logical/worker.c > > (2) WorkerErrorRecovery comments > > Instead of: > > > > + * As a preparation for disabling the subscription, emit the error, > > + * handle the transaction and clean up the memory context of > > + * error. ErrorContext is reset by FlushErrorState. > > > > why not just say: > > > > + Worker error recovery processing, in preparation for disabling the > > + subscription. > > > > And then comment the function's code lines: > > > > e.g. > > > > /* Emit the error */ > > ... > > /* Abort any active transaction */ > > ... > > /* Reset the ErrorContext */ > > ... > Agreed. Fixed. > > > (3) DisableSubscriptionOnError return > > > > The "if (!subform->subdisableonerr)" block should probably first: > > heap_freetuple(tup); > > > > (regardless of the fact the only current caller will proc_exit anyway) > Fixed. > > > (4) did_error flag > > > > I think perhaps the previously-used flag name "disable_subscription" > > is better, or maybe "error_recovery_done". > > Also, I think it would look better if it was set AFTER > > WorkerErrorRecovery() was called. > Adopted error_recovery_done > and changed its places accordingly. > > > (5) DisableSubscriptionOnError LOG message > > > > This version of the patch removes the LOG message: > > > > + ereport(LOG, > > + errmsg("logical replication subscription \"%s\" will be disabled due > > to error: %s", > > + MySubscription->name, edata->message)); > > > > Perhaps a similar error message could be logged prior to EmitErrorReport()? > > > > e.g. > > "logical replication subscription \"%s\" will be disabled due to an error" > Added. > > I've attached the new version v12. Thanks for the updated patch, few comments: 1) This is not required as it is not used in the caller. +++ b/src/backend/replication/logical/launcher.c @@ -132,6 +132,7 @@ get_subscription_list(void) sub->dbid = subform->subdbid; sub->owner = subform->subowner; sub->enabled = subform->subenabled; + sub->disableonerr = subform->subdisableonerr; sub->name = pstrdup(NameStr(subform->subname)); /* We don't fill fields we are not interested in. */ 2) Should this be changed: + subdisableonerr bool + + + If true, the subscription will be disabled when subscription + worker detects any errors + + To: + subdisableonerr bool + + + If true, the subscription will be disabled when subscription's + worker detects any errors + + 3) The last line can be slightly adjusted to keep within 80 chars: + Specifies whether the subscription should be automatically disabled + if any errors are detected by subscription workers during data + replication from the publisher. The default is false. 4) Similarly this too can be handled: --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1259,7 +1259,7 @@ REVOKE ALL ON pg_replication_origin_status FROM public; -- All columns of pg_subscription except subconninfo are publicly readable. REVOKE ALL ON pg_subscription FROM public; GRANT SELECT (oid, subdbid, subname, subowner, subenabled, subbinary, - substream, subtwophasestate, subslotname, subsynccommit, subpublications) + substream, subtwophasestate, subdisableonerr, subslotname, subsynccommit, subpublications) ON pg_subscription TO public; 5) Since disabling subscription code is common in and else, can we move it below: + if (MySubscription->disableonerr) + { + WorkerErrorRecovery(); + error_recovery_done = true; + } + else + { + /* + * Some work in error recovery work is done. Switch to the old + * memory context and rethrow. + */ + MemoryContextSwitchTo(ecxt); + PG_RE_THROW(); + } + } + else + { + /* + * Don't miss any error, even when it's not reported to stats + * collector. + */ + if (MySubscription->disableonerr) + { + WorkerErrorRecovery(); + error_recovery_done = true; + } + else + /* Simply rethrow because of no recovery work */ + PG_RE_THROW(); + } 6) Can we move LockSharedObject below the if condition. + subform = (Form_pg_subscription) GETSTRUCT(tup); + LockSharedObject(SubscriptionRelationId, subform->oid, 0, AccessExclusiveLock); + + /* + * We would not be here unless this subscription's disableonerr field was + * true when our worker began applying changes, but check whether that + * field has changed in the interim. + */ + if (!subform->subdisableonerr) + { + /* + * Disabling the subscription has been done already. No need of + * additional work. + */ + heap_freetuple(tup); + table_close(rel, RowExclusiveLock); + CommitTransactionCommand(); + return; + } + Regards, Vignesh