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 1pIlJo-0007vC-Ih for pgsql-hackers@arkaria.postgresql.org; Fri, 20 Jan 2023 06:56:08 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1pIlJm-0003tz-4o for pgsql-hackers@arkaria.postgresql.org; Fri, 20 Jan 2023 06:56:06 +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 1pIlJl-0003tq-JB for pgsql-hackers@lists.postgresql.org; Fri, 20 Jan 2023 06:56:05 +0000 Received: from mail-lf1-x133.google.com ([2a00:1450:4864:20::133]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1pIlJf-00044K-SA for pgsql-hackers@postgresql.org; Fri, 20 Jan 2023 06:56:04 +0000 Received: by mail-lf1-x133.google.com with SMTP id d30so6695822lfv.8 for ; Thu, 19 Jan 2023 22:55:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=Pb21qbnrqbQkElIFsMBwJ5w2bQPo4mB8J4B89EBDAfM=; b=pNFYona2syYuxtb283/ripisMMm71pulnFX6ZHuMwIGqWpOcDCQnvi5RwCQ7xhtD2z m/eDtcahelLvCd4OtHjnjm6s0WYaM11LrsBInr8En+NyIsv8TlDmwqMMDvl9/7Jk2CsP VmW41fXSZu9j3IDO44gsmJ9bk+p11fJ0lxlaWoLiFbzCXe38KSj+n/mUXGLhXqMTM8mG xfk4wGjTGCaf4dYVqf9hP+kyJ9xj8S5OgxmaXZXOCeFhEf2UK+H9JjxVEVLYHDITFulL vAWbBXxv4qBNQTDY5mkcssRu+bE5DErXvoDJEu3L4bqQKuNn2pKkqcUmS22grfwCP0Q3 awFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Pb21qbnrqbQkElIFsMBwJ5w2bQPo4mB8J4B89EBDAfM=; b=crg2NZOcGmWnBG8qr2u1hJmEFes6wBSJGZZE9kNBIprwvpRzmEdpOfObUvabz/JiSm ii+aao2MQ/f+xLu3mEVJDwlAxs6I3e1jyfvcOzo6ImzxkihBluT89QpKBKFzgF1DCW0a 8PcjM0UHaUWNMou8kE1pAIkOq3QTGZP5Z9YBt1UnMRZxlSk874BnQTd6IxPjbr4lE58s Hf/WJyOtydrpyG0E//pSvwMrznuY0eCr3tUn4opBzLPX+0ZmkgbLlJZA+kDuT8FQO1pP NGf3AZ4PAkRww0MH5kXV5rDz9ga/aYyoll/J5PZbm5MuKw+n6Jkusk2o19MGxAomtqJl Xd7A== X-Gm-Message-State: AFqh2koJV1BTM+5B7hwUObaIDkseGgVRXPcxqzkydIJAttZ2inXfrTvZ XvOfD+j96fF5auCI+8ebRUEkAkyFC3/W4pIOfF+suhFMHgA= X-Google-Smtp-Source: AMrXdXt2qUnzSaAZKoxDIUnWZckEETfQIKKBUpPPTejFcNDyb93QmdX2f6Hm6+oKD43X00dCk+6VDEAAb4ZTTJLF3pw= X-Received: by 2002:ac2:5dcd:0:b0:4b4:cc67:97d5 with SMTP id x13-20020ac25dcd000000b004b4cc6797d5mr1189304lfq.488.1674197757173; Thu, 19 Jan 2023 22:55:57 -0800 (PST) MIME-Version: 1.0 References: <20230112.120338.534662300633460797.horikyota.ntt@gmail.com> In-Reply-To: From: Peter Smith Date: Fri, 20 Jan 2023 17:55:39 +1100 Message-ID: Subject: Re: Time delayed LR (WAS Re: logical replication restrictions) To: "Takamichi Osumi (Fujitsu)" Cc: vignesh C , Kyotaro Horiguchi , "Hayato Kuroda (Fujitsu)" , "shveta.malik@gmail.com" , "dilipbalaut@gmail.com" , "amit.kapila16@gmail.com" , "euler@eulerto.com" , "m.melihmutlu@gmail.com" , "andres@anarazel.de" , "marcos@f10.com.br" , "pgsql-hackers@postgresql.org" Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Osumi-san, here are my review comments for the latest patch v17-0001. =3D=3D=3D=3D=3D=3D Commit Message 1. Prohibit the combination of this feature and parallel streaming mode. SUGGESTION (using the same wording as in the code comments) The combination of parallel streaming mode and min_apply_delay is not allow= ed. =3D=3D=3D=3D=3D=3D doc/src/sgml/ref/create_subscription.sgml 2. + + By default, the subscriber applies changes as soon as possible. = This + parameter allows the user to delay the application of changes by= a + specified amount of time. If the value is specified without unit= s, it + is taken as milliseconds. The default is zero (no delay). + Looking at this again, it seemed a bit strange to repeat "specified" twice in 2 sentences. Maybe change one of them. I=E2=80=99ve also suggested using the word "interval" because I don=E2=80= =99t think docs yet mentioned anywhere (except in the example) that using intervals is possible. SUGGESTION (for the 2nd sentence) This parameter allows the user to delay the application of changes by a given time interval. ~~~ 3. + + Any delay occurs only on WAL records for transaction begins afte= r all + initial table synchronization has finished. The delay is calcula= ted + between the WAL timestamp as written on the publisher and the cu= rrent + time on the subscriber. Any overhead of time spent in logical decoding + and in transferring the transaction may reduce the actual wait t= ime. + It is also possible that the overhead already execeeds the reque= sted + min_apply_delay value, in which case no addit= ional + wait is necessary. If the system clocks on publisher and subscri= ber + are not synchronized, this may lead to apply changes earlier tha= n + expected, but this is not a major issue because this parameter i= s + typically much larger than the time deviations between servers. = Note + that if this parameter is set to a long delay, the replication w= ill + stop if the replication slot falls behind the current LSN by more than + max_slot_wal_keep_size. + 3a. Typo "execeeds" (I think Vignesh reported this already) ~ 3b. SUGGESTION (for the 2nd sentence) BEFORE The delay is calculated between the WAL timestamp... AFTER The delay is calculated as the difference between the WAL timestamp... ~~~ 4. + + + Delaying the replication can mean there is a much longer time between making + a change on the publisher, and that change being committed on the subscriber. + v + See . + + IMO maybe there is a better way to express the 2nd sentence: BEFORE This can have a big impact on synchronous replication. AFTER This can impact the performance of synchronous replication. =3D=3D=3D=3D=3D=3D src/backend/commands/subscriptioncmds.c 5. parse_subscription_options @@ -324,6 +328,43 @@ parse_subscription_options(ParseState *pstate, List *stmt_options, opts->specified_opts |=3D SUBOPT_LSN; opts->lsn =3D lsn; } + else if (IsSet(supported_opts, SUBOPT_MIN_APPLY_DELAY) && + strcmp(defel->defname, "min_apply_delay") =3D=3D 0) + { + char *val, + *tmp; + Interval *interval; + int64 ms; IMO 'delay_ms' (or similar) would be a friendlier variable name than just '= ms' ~~~ 6. @@ -404,6 +445,20 @@ parse_subscription_options(ParseState *pstate, List *stmt_options, "slot_name =3D NONE", "create_slot =3D false"))); } } + + /* + * The combination of parallel streaming mode and min_apply_delay is not + * allowed. + */ + if (IsSet(supported_opts, SUBOPT_MIN_APPLY_DELAY) && + opts->min_apply_delay > 0) + { + if (opts->streaming =3D=3D LOGICALREP_STREAM_PARALLEL) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("%s and %s are mutually exclusive options", + "min_apply_delay > 0", "streaming =3D parallel")); + } This could be expressed as a single condition using &&, maybe also with the brackets eliminated. (Unless you feel the current code is more readable) ~~~ 7. + if (opts.min_apply_delay > 0) + if ((IsSet(opts.specified_opts, SUBOPT_STREAMING) && opts.streaming =3D=3D LOGICALREP_STREAM_PARALLEL) || + (!IsSet(opts.specified_opts, SUBOPT_STREAMING) && sub->stream =3D=3D LOGICALREP_STREAM_PARALLEL)) + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot enable %s for subscription in %s mode", + "min_apply_delay", "streaming =3D parallel")); These nested ifs could instead be a single "if" with && condition. (Unless you feel the current code is more readable) =3D=3D=3D=3D=3D=3D src/backend/replication/logical/worker.c 8. maybe_delay_apply + * Hence, it's not appropriate to apply a delay at the time. + */ +static void +maybe_delay_apply(TimestampTz finish_ts) That last sentence "Hence,... delay at the time" does not sound correct. Is there a typo or missing words here? Maybe it meant to say "... at the STREAM START time."? ~~~ 9. + /* This might change wal_receiver_status_interval */ + if (ConfigReloadPending) + { + ConfigReloadPending =3D false; + ProcessConfigFile(PGC_SIGHUP); + } I was unsure why did you make a special mention of 'wal_receiver_status_interval' here. I mean, Aren't there also other GUCs that might change and affect something here so was there some special reason only this one was mentioned? =3D=3D=3D=3D=3D=3D src/test/subscription/t/032_apply_delay.pl 10. + +# Compare inserted time on the publisher with applied time on the subscrib= er to +# confirm the latter is applied after expected time. +sub check_apply_delay_time Maybe the comment could also mention that the time is automatically stored in the table column 'c'. ~~~ 11. +# Confirm the suspended record doesn't get applied expectedly by the ALTER +# DISABLE command. +$result =3D $node_subscriber->safe_psql('postgres', + "SELECT count(a) FROM test_tab WHERE a =3D 0;"); +is($result, qq(0), "check if the delayed transaction doesn't get applied expectedly"); The use of "doesn't get applied expectedly" (in 2 places here) seemed strange. Maybe it's better to say like SUGGESTION # Confirm disabling the subscription by ALTER DISABLE did not cause the delayed transaction to be applied. $result =3D $node_subscriber->safe_psql('postgres', "SELECT count(a) FROM test_tab WHERE a =3D 0;"); is($result, qq(0), "check the delayed transaction was not applied"); ------ Kind Regards, Peter Smith. Fujitsu Australia