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 1mhbZo-0008D2-F3 for pgsql-hackers@arkaria.postgresql.org; Mon, 01 Nov 2021 17:58:32 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1mhbZn-0002GS-DZ for pgsql-hackers@arkaria.postgresql.org; Mon, 01 Nov 2021 17:58:31 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mhbZm-0002GJ-L7 for pgsql-hackers@lists.postgresql.org; Mon, 01 Nov 2021 17:58:31 +0000 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1mhbZk-0005ZV-2Z for pgsql-hackers@postgresql.org; Mon, 01 Nov 2021 17:58:29 +0000 Received: by mail-pj1-x102a.google.com with SMTP id o6-20020a17090a0a0600b001a64b9a11aeso546477pjo.3 for ; Mon, 01 Nov 2021 10:58:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; h=from:message-id:mime-version:subject:date:in-reply-to:cc:to :references; bh=mK+Goj8AnGC/8Ww6Vr0MckwZeDfep3LW4cmE0lnP74k=; b=kVABTr48bRpTqUePSEpwrNXBgVGqgOASnPSeoCFMGWGXxztoXCcz/6PhS+LeWuynb8 +HVUi8OHrGZUKDpP5bVPvGdQ69ArNl5FH1PxdbVBgFMkMosHRbS2GK6fASSD9BXVLYdB XcFLxcEX6iT4iV7Eydyb+WGZE8C1c74d0PL+dzIXQ4QwRL0vF2THj577knRo+lWq51Cz QrRpPxSmhkIS3E+DhFfV1xvBGF80vZsh5lrl0oBeXCJxiObAhoEQRbdVkFCJiB0DOZ5P RL/HDoIdUd26kmCH75Im7BUOkA0WMDdpwZyYVehACEoZV+0E+78IAdtntyOvvIpEJk7y U60A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:message-id:mime-version:subject:date :in-reply-to:cc:to:references; bh=mK+Goj8AnGC/8Ww6Vr0MckwZeDfep3LW4cmE0lnP74k=; b=38qIB/3drk5jUJsBSJGvoBhvaYWVT+QGMWEgMdCZ6CARcB5U4323+E+FyZiEkFYF+L Y0Hptax9WHI97Ts0m+D1T4hJdFasPe2MC49tfKVP8ixy2OcE0OfuEaK32XgF9kqxtply IYIHAEFPFM85CVK8Ytxn7LZJmXjetQq40QMjNKCInwt1FmEzUbRBy+6RdGN/ksnXPM2k E7x5flGFLxnyoMH6Tg0qoaA3dLrirFS+qjs40pIas8TG6nFrjnCfzFkoOQSJJkheojA3 q53PlLL0y5uDCa81JZykNo3gT8mjbRMATTHmTvCPi00JUCBqlN4ohgsUv3XNQ0mPZtGZ Y33g== X-Gm-Message-State: AOAM531TPlQ8m/pCGibbKm/amDNbqMuAbVbpmuXv/a3xAiAv4Fqel1Xw xLSX2EyL9Mxu3V1YUOdfv6PhUjec04ceiySyXjf9OnSu7ijJreBpVRZcbevXtRad/Dxr3yK+jOr 2mJH2W1YXlhmjJf2p/nYPQEWBWtgr+E1YqK3kd2zHTA9F/ueVbvvp/MzkgAqQ6iqT6DiFr7c3Ed Vb+QeHTXX5TPEGuKp3ZkHzayITJVfVOj/gYtv7 X-Google-Smtp-Source: ABdhPJwEoQJUqFhgDnKlyjwligKxwRc32GRxE+P5IO+p8kRqoOQLpV25kNQt5JZoUoTCsA4rPc9atQ== X-Received: by 2002:a17:90b:4a45:: with SMTP id lb5mr501164pjb.94.1635789506751; Mon, 01 Nov 2021 10:58:26 -0700 (PDT) Received: from laptop280-ma-us.hitronhub.home (24-113-193-150.wavecable.com. [24.113.193.150]) by smtp.gmail.com with ESMTPSA id n29sm16033796pfv.77.2021.11.01.10.58.25 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Nov 2021 10:58:26 -0700 (PDT) From: Mark Dilger Message-Id: Content-Type: multipart/mixed; boundary="Apple-Mail=_8151DED1-3EF4-49C6-A52A-0F73A5CF5A9F" Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.7\)) Subject: Re: Non-superuser subscription owners Date: Mon, 1 Nov 2021 10:58:25 -0700 In-Reply-To: Cc: PostgreSQL-development To: Andrew Dunstan References: <9DFC88D3-1300-4DE8-ACBC-4CEF84399A53@enterprisedb.com> X-Mailer: Apple Mail (2.3608.120.23.2.7) X-CLOUD-SEC-AV-Info: enterprisedb,google_mail,monitor X-CLOUD-SEC-AV-Sent: true X-Gm-Spam: 0 X-Gm-Phishy: 0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_8151DED1-3EF4-49C6-A52A-0F73A5CF5A9F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On Nov 1, 2021, at 7:18 AM, Andrew Dunstan = wrote: >=20 > w.r.t. this: >=20 > + On the subscriber, the subscription owner's privileges are > re-checked for > + each change record when applied, but beware that a change of > ownership for a > + subscription may not be noticed immediately by the replication = workers. > + Changes made on the publisher may be applied on the subscriber as > + the old owner. In such cases, the old owner's privileges will be > the ones > + that matter. Worse still, it may be hard to predict when = replication > + workers will notice the new ownership. Subscriptions created > disabled and > + only enabled after ownership has been changed will not be subject = to > this > + race condition. >=20 >=20 > maybe we should disable the subscription before making such a change = and > then re-enable it? Right. I commented the code that way because there is a clear concern, = but I was uncertain which way around the problem was best. ALTER SUBSCRIPTION..[ENABLE | DISABLE] do not synchronously start or = stop subscription workers. The ALTER command updates the catalog's = subenabled field, but workers only lazily respond to that. Disabling = and enabling the subscription as part of the OWNER TO would not reliably = accomplish anything. The attached patch demonstrates the race condition. It sets up a = publisher and subscriber, and toggles the subscription on and off on the = subscriber node, interleaved with inserts and deletes on the publisher = node. If the ALTER SUBSCRIPTION commands were synchronous, the test = results would be deterministic, with only the inserts performed while = the subscription is enabled being replicated, but because the ALTER = commands are asynchronous, the results are nondeterministic. It is unclear that I can make ALTER SUBSCRIPTION..OWNER TO synchronous = without redesigning the way workers respond to pg_subscription catalog = updates generally. That may be a good project to eventually tackle, but = I don't see that it is more important to close the race condition in an = OWNER TO than for a DISABLE. Thoughts? --Apple-Mail=_8151DED1-3EF4-49C6-A52A-0F73A5CF5A9F Content-Disposition: attachment; filename=alter_subscription_race.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="alter_subscription_race.patch" Content-Transfer-Encoding: 7bit diff --git a/src/test/subscription/t/026_race.pl b/src/test/subscription/t/026_race.pl new file mode 100644 index 0000000000..cbbe6c34e2 --- /dev/null +++ b/src/test/subscription/t/026_race.pl @@ -0,0 +1,86 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +# Test subscriptions owned by non-superusers +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More; + +our $LOOPCOUNT = 100; +plan tests => 2 * $LOOPCOUNT; +my $result; + +# Setup + +my $node_publisher = PostgresNode->new('publisher'); +$node_publisher->init(allows_streaming => 'logical'); +$node_publisher->start; + +my $node_subscriber = PostgresNode->new('subscriber'); +$node_subscriber->init(allows_streaming => 'logical'); +$node_subscriber->start; + +my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; + +$node_publisher->safe_psql('postgres', qq( +CREATE TABLE t (i INTEGER); +ALTER TABLE t REPLICA IDENTITY FULL; +CREATE PUBLICATION pub FOR TABLE t; +)); + +$node_subscriber->safe_psql('postgres', qq( +CREATE TABLE t (i INTEGER); +CREATE SUBSCRIPTION sub CONNECTION '$publisher_connstr' PUBLICATION pub; +CREATE TABLE b (LIKE t); +)); + +# Wait for initial sync of all subscriptions. +my $synced_query = + "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');"; +$node_subscriber->poll_query_until('postgres', $synced_query) + or die "Timed out while waiting for subscriber to synchronize data"; + +# Upon first entry to this loop, the subscription is enabled +foreach my $loop (1..$LOOPCOUNT) +{ + my $even = $loop * 2; + my $odd = ($loop * 2) + 1; + + # The subscription is enabled. This even number is fair game for + # replication. + $node_publisher->safe_psql('postgres', "INSERT INTO t (i) VALUES ($even)"); + + # We may replicate the even number before the subscription is disabled, but + # maybe not. + $node_subscriber->safe_psql('postgres', "ALTER SUBSCRIPTION sub DISABLE"); + + # The subscription is now disabled, but workers on the subscriber side may + # not have gotten the message yet. As such, this odd number may slip + # through. + $node_publisher->safe_psql('postgres', "INSERT INTO t (i) VALUES ($odd)"); + + # See if we can catch any odd numbers in the subscriber's copy of table t + $result = $node_subscriber->safe_psql('postgres', + "SELECT COUNT(*) FROM t WHERE i % 2 = 1"); + is ($result, 0, "No odd numbers in subscriber copy of table t before delete on publisher"); + + # Clear out all values on the publisher side, so that the odd number cannot + # be replicated after we re-enable the subscription. Of course, it may have + # already slipped through, and it is also possible that the even number has + # not replicated yet. + # + # Since the publication only publishes INSERTs, this delete should only have + # effect on the publisher side. + $node_publisher->safe_psql('postgres', "DELETE FROM t WHERE i = $odd"); + + # Enable the subscription for the next loop. Note that at this point, the + # table is empty on the publisher side. + $node_subscriber->safe_psql('postgres', "ALTER SUBSCRIPTION sub ENABLE"); + + # See if we can catch an odd number before the delete is propogated + $result = $node_subscriber->safe_psql('postgres', + "SELECT COUNT(*) FROM t WHERE i % 2 = 1"); + is ($result, 0, "No odd numbers in subscriber copy of table t after delete on publisher"); +} --Apple-Mail=_8151DED1-3EF4-49C6-A52A-0F73A5CF5A9F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 =E2=80=94 Mark Dilger EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company --Apple-Mail=_8151DED1-3EF4-49C6-A52A-0F73A5CF5A9F--