Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wbnIV-002qez-2p for pgsql-hackers@arkaria.postgresql.org; Mon, 22 Jun 2026 22:39:20 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wbnIT-008Sq4-2V for pgsql-hackers@arkaria.postgresql.org; Mon, 22 Jun 2026 22:39:17 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wbnIT-008Spw-1P for pgsql-hackers@lists.postgresql.org; Mon, 22 Jun 2026 22:39:17 +0000 Received: from mail-oi1-x236.google.com ([2607:f8b0:4864:20::236]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wbnIQ-00000001pIE-3TeF for pgsql-hackers@postgresql.org; Mon, 22 Jun 2026 22:39:16 +0000 Received: by mail-oi1-x236.google.com with SMTP id 5614622812f47-48662d16d08so1839682b6e.2 for ; Mon, 22 Jun 2026 15:39:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1782167952; cv=none; d=google.com; s=arc-20240605; b=X9yL29BXp2ZR5QCGNQx3fnZuzpOVHjGdaJm+Tl9mnFcsJR0fJlAr4aODiipBe1gr2B qB7pzPCw9/SsDLMdodrPjgzK1RpIbMNMZnma9kvI1ZNL3e9WrMDS3rP+h+ShloGMUL19 HHSdZIXmo/3QMzB/NiKdnxQpbu2Cn/D17hESL+Bu+VDopvMk+nERfC0Dk/hsGQOB6eXs 2cCmkkQe0Rh83lmV5nuP088xNJnsNbyNxYnfPfeFPzEJJhksibw4quM/cD4p8/6Q1/Ah cbnnhM3tn69ILSGdTAnb5SE5qVuMFN8zUn1mwh8IRf5qLPSsuK9rdVePAAWf7DIwcVFF RYjg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=l4bZiuCyT5uiIfHEoUBUKZYMXN/0Iu9KbUWAOCtGZ1U=; fh=HhgakOA0yKbxYWhvhbicT9qdKs1aMrEgKivevi/HRog=; b=k2x3YJncxGpb95THUUPGuMGa6PeTiA8V/vamJwxKe78gpRMWxb54zg45b3ByGUxsI7 t5ClYlfDashaXyJD+hevn51sykM2/hnLXwgQSnQswx8UgZE3oqSQDEwPL4IgSTJfEHyI ZuYuMS30f+BYzeAPMzDbqnpXql19qI1kf1DlrYLzxtnGit/GqFhJV7ALI5X5WgBe+8On QFdM+WCyD5CPWjjGclVRE/XxKQzg6Cup6hIih/HqY4ae7l7RuRF3zv6cFmaS13WZfsLp 9zdS8FluRHXzU5ZyuzAvq278AQvgJvN4GQVn0S7nXvQGVef574IpjMTlzLaKvw7Ox2LC FN4Q==; darn=postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782167952; x=1782772752; darn=postgresql.org; 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=l4bZiuCyT5uiIfHEoUBUKZYMXN/0Iu9KbUWAOCtGZ1U=; b=BPDu6sUhmjn8a373K5Ot58MyVXZfQl4Pcvdh96+LFOg1Gn/4jbNBilAF+s/TeuEbYW TkCcKTS2D7ugLHNVyJhpsAGqERyGE2a9kCqz7WUAjYOjIbPLQr+0N/9Df66CltEH8VRJ mdjebK8/iPa2wWp0yiTaM5UD5DJgbFB0Smj23gCcDkZjdR76NbrphJ2Pwm14tfXH7d0h SGTpt1cMxsvIuYMW5hMeNpAEIW5tB++AghISuXV2+CCiIGq9MhxhJrbgfETnckh2LhOt vmVT5wVX/HN89Y+Xc5hNTrtWNKnaD4kX/9GIb2Lgr58C6BDRcVKnHwnFxfXa28305NTP Sz6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782167952; x=1782772752; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=l4bZiuCyT5uiIfHEoUBUKZYMXN/0Iu9KbUWAOCtGZ1U=; b=KiKoOMX/NUHxtD4lhN3u77b7OWh3tO9TXnxApFPZYvxPWqII6xhINLVqEK4iBibscS RtTN0L8msnrOM1KUREOUuXKGOce7ompfLL0TqH3zD3gdRpR3oeHmOFXH6QpQT6dh2DS/ /BpFdJSOBaPcYZBkMuoxB0d4geTaM9v+y6NsL5Lf98Q5zWYhWy/n1qIZybZKq6bvQUT+ D/4A+OOs72UvhGGPyHh5VkGZB9thm63lUzIkbkpWtzsS8fqivuJje6ofkJ2ldH81XIun bVzcQOrQaytwx4AX/aN44qT9ivrhAFQWlmOhiE5MxhSzprmUT3bKwSAzzAGKlviMd50e wgog== X-Gm-Message-State: AOJu0YxOadyw6BAgVj5c8oe+YrIC0mwdV7Va45gX4GJtQD6Go7Q39aXn OxnnzR6M7iUlnOQKYRmVs9FklxHMwBDMf6Qi/5txyFmdnxzBNgYgKdpKwPlemO0dXxA0fn5McNi c5abNvurLNPZGYEbcyVs5lvr83sWMxfA= X-Gm-Gg: AfdE7ckuYDmJeWqCnppYcjMhSbmbgPqUJjuH5wbD3hFedeVweoRq5r3GvuO3r1/l/hy RVqsXsYU6kEsONoaD5ujioqh9JV5r6CQds2LwVHc0/UgTcDcOabpsuEtfcs1WiZDfChZ1GUGGJV rzkdIS6nXYthVE2l8w//HfxxzZK+5gDRW8AtOECiwo7ZH5IEJAOXTVpKckDWO2LSe+JVbyoAcfV suc7T82ZJRnZNZb8Zd9zCluNK4FQS/eQQ37vr1OoxvVx3dwzOBFTs1RqPfcC8N8guYfmBa791It T/0E6w== X-Received: by 2002:a05:6808:144a:b0:489:751e:9712 with SMTP id 5614622812f47-489751e9881mr12084612b6e.19.1782167952444; Mon, 22 Jun 2026 15:39:12 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Bharath Rupireddy Date: Mon, 22 Jun 2026 15:39:00 -0700 X-Gm-Features: AVVi8CeI9pOiRqAKUF5dl7bHYJwkkSVDf4sxaVRrZPP5pm6B2UvsaAHb8pH6DhA Message-ID: Subject: Re: Add a hook for handling logical decoding messages on subscribers. To: Masahiko Sawada Cc: PostgreSQL-development 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, On Fri, Jun 19, 2026 at 3:34=E2=80=AFPM Masahiko Sawada wrote: > > Hi all, > > Commit ac4645c015 allows pgoutput to send logical decoding messages, > but it's limited to applications that use the pgoutput plugin -- the > built-in logical replication doesn't use it. I'd like to propose > introducing a hook to the logical replication message handling so that > extensions can plug in their own handling routine. This feature can be > used for extensions to implement DDL replication, function > replication, or trigger user-specific routines on the subscriber side. Thanks for working on this! > I've attached the PoC patch; it adds a hook function, and adds a new > 'message' subscription option that allows the user to request the > publisher to send logical decoding messages. Therefore, users need to > enable the 'message' option and set up the hook function at server > startup in order to receive the messages and trigger the hook > function. I understand the intent of the proposal, but I'd like to get the bigger picture first. Do we have any external modules that actually implement DDL replication (or any of the listed use-cases) with a similar hook? Or any existing discussion? I could be missing something because I haven't looked at all the DDL replication related threads. Another thing I'm curious about - why a hook? Is the plan to implement DDL replication as an external module rather than in core? If DDL replication eventually gets into core, I'd expect it to be apply-side logic executing the decoded DDL messages directly, not something going through a hook. Why not a hook at apply_dispatch to give external modules more freedom with the pgoutput plugin? > I I went with a hook function in the patch. While it lets you chain > the multiple hook functions, providing the registration API might be > better, or other types of registry can also be considered. It's hard to tell how many external modules would make use of this hook (rather, how many external modules implementing this hook one would allow to be installed in a production database requiring chaining), but my first thought is that a registration-based API along the lines of RegisterXactCallback would be cleaner and work better. > Feedback is very welcome. A few comments on the patch: 1/ + bool message; /* True if the subscription wants to receive + * logical messages */ } Subscription; Nit: I'd call these logical decoding messages or generic logical messages - something to match the docs and pg_logical_emit_message. 2/ +void +test_logical_message_handler(LogicalRepMessageData *msg) +{ + ereport(LOG, + (errmsg("received message: LSN %X/%08X, prefix: %s, message: %s", + LSN_FORMAT_ARGS(msg->lsn), + msg->prefix, + msg->message))); +} Why not have the test extension do a simple DDL/function/event-trigger based replication? It doesn't need to be a full-blown implementation, but to show the usefulness of this hook, it's better to have one demonstrating the listed use-cases. 3/ + if (subinfo->submessage) + appendPQExpBufferStr(query, ", message =3D true"); Why a subscription-level option? Why not leave the decision of whether or not to act on the message to the external module implementers? 4/ + /* + * Logical messages are handled only the (parallel) apply workers + */ + if (am_tablesync_worker() || am_sequencesync_worker()) + return; Why these restrictions? Why not leave the decision to external module implementers? Isn't this limiting - what if someone wants to use this hook for the schema sync during the initial table sync phase? 5/ With this change, pg_logical_emit_message does affect the logical replication apply if the subscriber has defined this hook. I think it's worth mentioning in the docs for pg_logical_emit_message. -- Bharath Rupireddy Amazon Web Services: https://aws.amazon.com