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 1ocloY-0000vs-Qi for pgsql-hackers@arkaria.postgresql.org; Mon, 26 Sep 2022 10:58:18 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1ocloX-0007WL-HH for pgsql-hackers@arkaria.postgresql.org; Mon, 26 Sep 2022 10:58:17 +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 1ocloX-0007WB-6a for pgsql-hackers@lists.postgresql.org; Mon, 26 Sep 2022 10:58:17 +0000 Received: from mail-yw1-x1132.google.com ([2607:f8b0:4864:20::1132]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1ocloV-0006A6-9H for pgsql-hackers@lists.postgresql.org; Mon, 26 Sep 2022 10:58:16 +0000 Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-3457bc84d53so64988977b3.0 for ; Mon, 26 Sep 2022 03:58:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date; bh=8TrYZjDEAD7elI7hQXbVjkWkBNmxTGg6Hq3ByYTUIrM=; b=KiMHo9P0c6IV/IPpzRE19H4H4V9ofot4eo6b1TCL0XttulTq3l0h0ipzIqpcuaLYdB Jw2izb9IxXAvfNGqDFUlZr0DEyBnVUTUreYVS5oY1Y1Wzox8rDTeyylWyhehgZiU7MSP hLFdO84BVDQl1eEtp1qiU5nUViableCaoeYW+Tl2NkACWYtgu1LnIkn4ITVzHn0ulZBP ypiMjdMNBlYTLqDiUSFhDfKARMcLotpurvGevXCKhkC5V5q2KzBdkcobuqeZJ06NvZrc iBe8ae+YfJjU/hoF2crstw2EbpG1f/OPxO+K2KNP4xPAp2+pPAFgeFZ1uIv1AaZ8pODa SDSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date; bh=8TrYZjDEAD7elI7hQXbVjkWkBNmxTGg6Hq3ByYTUIrM=; b=bEQMAPLNtKh0Z0VsNvVoGncDRORy3mZS5snjc2PZevInOsmPajSYJS5pCtfjxDZzAW oB7Nr9EDn4Oe12sx1Jek2n/FgjXCtMytWmtuYZDfQN7FWrKsm3RhwtwT0NJG27wVu5YZ PQkQPMRGzlVRhLaadMXryh18wVrHHEn0G0YQ2KkMq1MPAFQjT8YHBuoHe+mrR+liMJkB a1CLowErVG69YnbJu0zfv+W1Ev9qzW6tDiuOOnIGX9pg395FUHWWrHM5Uc6MNabBm4mo UpQhJ+Khletc5sHoFXwo2sLJwVLU1SglmL16ejhZIaJmQajj4xbw+lXXNmOvnGs4xR2H S1XA== X-Gm-Message-State: ACrzQf133mPcylWi1KE1KuuUEx3Stcp+tymKkRHGbRjQZk/tPhJ0TaAz DLXDF9R4+hHKcu1M6cu10jLvH52UtY5wOD7w0CA= X-Google-Smtp-Source: AMsMyM4fZh1Cga+RAveS7cHyTKtm0VRshb3DnJoBQp86BEmviuEojoMXqLHYdYBn5nvqJXq+YpzbuRMb/fIxsiP4y6g= X-Received: by 2002:a0d:cc8f:0:b0:349:8a5:74e9 with SMTP id o137-20020a0dcc8f000000b0034908a574e9mr20926796ywd.84.1664189893594; Mon, 26 Sep 2022 03:58:13 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Amit Kapila Date: Mon, 26 Sep 2022 16:28:01 +0530 Message-ID: Subject: Re: Perform streaming logical transactions by background workers and parallel apply To: "wangw.fnst@fujitsu.com" Cc: Peter Smith , "houzj.fnst@fujitsu.com" , Dilip Kumar , Masahiko Sawada , "shiy.fnst@fujitsu.com" , 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, Sep 26, 2022 at 8:41 AM wangw.fnst@fujitsu.com wrote: > > On Thur, Sep 22, 2022 at 18:12 PM Amit Kapila wrote: > > > 3. > > ApplyWorkerMain() > > { > > ... > > ... > > + > > + if (server_version >= 160000 && > > + MySubscription->stream == SUBSTREAM_PARALLEL) > > + options.proto.logical.streaming = pstrdup("parallel"); > > > > After deciding here whether the parallel streaming mode is enabled or > > not, we recheck the same thing in apply_handle_stream_abort() and > > parallel_apply_can_start(). In parallel_apply_can_start(), we do it > > via two different checks. How about storing this information say in > > structure MyLogicalRepWorker in ApplyWorkerMain() and then use it at > > other places? > > Improved as suggested. > Added a new flag "in_parallel_apply" to structure MyLogicalRepWorker. > Can we name the variable in_parallel_apply as parallel_apply and set it in logicalrep_worker_launch() instead of in ParallelApplyWorkerMain()? Few other comments: ================== 1. + if (is_subworker && + nparallelapplyworkers >= max_parallel_apply_workers_per_subscription) + { + LWLockRelease(LogicalRepWorkerLock); + + ereport(DEBUG1, + (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED), + errmsg("out of parallel apply workers"), + errhint("You might need to increase max_parallel_apply_workers_per_subscription."))); I think it is better to keep the level of this as LOG. Similar messages at other places use WARNING or LOG. Here, I prefer LOG because the system can still proceed without blocking anything. 2. +/* Reset replication origin tracking. */ +void +parallel_apply_replorigin_reset(void) +{ + bool started_tx = false; + + /* This function might be called inside or outside of transaction. */ + if (!IsTransactionState()) + { + StartTransactionCommand(); + started_tx = true; + } Why do we need a transaction in this function? 3. Few suggestions to improve in the patch: diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index 1623c9e2fa..d9c519dfab 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -1264,6 +1264,10 @@ apply_handle_stream_prepare(StringInfo s) case TRANS_LEADER_SEND_TO_PARALLEL: Assert(winfo); + /* + * The origin can be active only in one process. See + * apply_handle_stream_commit. + */ parallel_apply_replorigin_reset(); /* Send STREAM PREPARE message to the parallel apply worker. */ @@ -1623,12 +1627,7 @@ apply_handle_stream_abort(StringInfo s) (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg_internal("STREAM ABORT message without STREAM STOP"))); - /* - * Check whether the publisher sends abort_lsn and abort_time. - * - * Note that the parallel apply worker is only started when the publisher - * sends abort_lsn and abort_time. - */ + /* We receive abort information only when we can apply in parallel. */ if (MyLogicalRepWorker->in_parallel_apply) read_abort_info = true; @@ -1656,7 +1655,13 @@ apply_handle_stream_abort(StringInfo s) Assert(winfo); if (subxid == xid) + { + /* + * The origin can be active only in one process. See + * apply_handle_stream_commit. + */ parallel_apply_replorigin_reset(); + } /* Send STREAM ABORT message to the parallel apply worker. */ parallel_apply_send_data(winfo, s->len, s->data); @@ -1858,6 +1863,12 @@ apply_handle_stream_commit(StringInfo s) case TRANS_LEADER_SEND_TO_PARALLEL: Assert(winfo); + /* + * We need to reset the replication origin before sending the commit + * message and set it up again after confirming that parallel worker + * has processed the message. This is required because origin can be + * active only in one process at-a-time. + */ parallel_apply_replorigin_reset(); /* Send STREAM COMMIT message to the parallel apply worker. */ diff --git a/src/include/replication/worker_internal.h b/src/include/replication/worker_internal.h index 4cbfb43492..2bd9664f86 100644 --- a/src/include/replication/worker_internal.h +++ b/src/include/replication/worker_internal.h @@ -70,11 +70,7 @@ typedef struct LogicalRepWorker */ pid_t apply_leader_pid; - /* - * Indicates whether to use parallel apply workers. - * - * Determined based on streaming parameter and publisher version. - */ + /* Indicates whether apply can be performed parallelly. */ bool in_parallel_apply; -- With Regards, Amit Kapila.