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 1wPxEH-001AXt-2c for pgsql-hackers@arkaria.postgresql.org; Thu, 21 May 2026 06:50:01 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wPxEE-009O8Y-1J for pgsql-hackers@arkaria.postgresql.org; Thu, 21 May 2026 06:49:59 +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 1wPxEE-009O8Q-0G for pgsql-hackers@lists.postgresql.org; Thu, 21 May 2026 06:49:59 +0000 Received: from mail-yx1-xb133.google.com ([2607:f8b0:4864:20::b133]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wPxED-00000000gzm-06gR for pgsql-hackers@lists.postgresql.org; Thu, 21 May 2026 06:49:58 +0000 Received: by mail-yx1-xb133.google.com with SMTP id 956f58d0204a3-65eb226b1ceso173844d50.0 for ; Wed, 20 May 2026 23:49:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1779346195; cv=none; d=google.com; s=arc-20240605; b=bzzlAT76B5CzrBMRekeNQX8g4wkbiEKkzl+rl4T7eUrA21L7VKQSoBmfImpVzAiWNi 7x8g/5f7NGSmCExm4B6vMju76bVvVtxB0p9qdMNQ44xUKm8+oR39n8tYS5yKmrnNj8OU InTFxibu+LJ7VXunRqPNaCFmikacgQJf9/dZl4jBtsArHUueFGiM7G/fePn7HS/OX3yF WfdDa8At7tUyLQzv8GXjB/IRh/0xvuYRbvYvNrp53RrJ6Qt8jhE+xgY36N4GQREKnbkX yEXOhPPAwV8ilGW65bsyCezWpgmLPkuOZUlODC42UR41AovPg2NOFNqjFbdKGms8CI2e Q8iA== 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=R4p91EjHp/Svz6Xfb/smddHvqkqMqpHSJggq9UfZoK0=; fh=6QItb0hSRnTAOEXA6SPECN30b82WGkt4Vc5vyUCHm0s=; b=IbqiNmLVQWtUydTyePw+j3phosrhu2unGBbLP9umYpZjhhPOXZoq1vPqqF+pbHFlaq c0U7hTyIJ5vMoKCYjjXbKCjDFmgptQrAX/ECYvfIi4dYolBNyUpvsgeRYJhi3UaTveEq OG+KbJEf5TeX0gfjAqslK7cnjOBTx/Ztaj6tqaUdWxr+ClqhAQpigvgblGKd9E99gHKn Q4aGZWFjUNSdnUeoPlSKmAPmGkso39QeiwmwjFoo6sQjpJSfHLwSp9aGTEUoez7P31I3 pxx5kGrUHoRy4WlKOXXOCeZVnjnWbLP9hpoek+ti05NNQP1jDlmpcIJu982X0vHBCxgI Gwyg==; darn=lists.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=1779346195; x=1779950995; darn=lists.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=R4p91EjHp/Svz6Xfb/smddHvqkqMqpHSJggq9UfZoK0=; b=i4E49SkH2kLt0+57BUdIDWmxlEe9u1K8xIIjoffTpDHSQhWM/5vQ4qb9Cdu4iKj0Sg wwy+CPLYPSH1UixYLhFn3DZD7yBSEvqUXl0Hjzry+M0IwB+YpO4PqNTFciMDKUcjbm3Z PXsybxPRBT39xoBwspHT6748qh9upg/RjOxTYMkVg3VPiiaeUxigqxv+TLoSpjnhll16 AGCWEvPpuB0qdGUKTtCnkkcq5SQzApSFoRnuslC7o3Sn3T0o5oOPIlztQrbvAOBkRxTp UNHoTmZVI/J36tbNlIkP/euTCg+kRsorbZMpAYR1Uq+nB3w9kexkEB30DL5j+hU7oWJA 7sgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779346195; x=1779950995; 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=R4p91EjHp/Svz6Xfb/smddHvqkqMqpHSJggq9UfZoK0=; b=Ljt0B7+NHZsuG0h5M/IX/Okq1wkN2CjgBzGSVLu4LRZ8Hboqc+xUyjEw598ca53A0x FftX2WLlWOsT6PqJ1ch9kWCoYTVJP8OOAfYrQelvyGfRbLOlffcm6bHleLz/0E6miOtj TWgMXgsVy0GAg9/K9uSTcXINmt6jie1sDF/0P7POD7pN4C9kbJEqklA2M3OV6R9tzLVn kdowbbIPCwJrHV8arLbuJbiK1QTUYXwUQMb9YoodaqdHUsmsZzNx3FLp+5gtBZIXoLdM dY0KNf2/WTaEUkgRLhcGsqSzMHs/mB9FyfksP04zri/JL+Vm1teLZgNLFYkxd/EDRBcd VHqQ== X-Forwarded-Encrypted: i=1; AFNElJ/+ZOnLworn1IufvJnMezj/JnU3WGFnGxFa4QVeKe1rQ/yuYP6S6CksSaRRXYuJeG1ifnhXBAmicINwvyvF@lists.postgresql.org X-Gm-Message-State: AOJu0YwLa2ChB0ZzZfKxVWMm1xcSCeAWRjViGeCpepnnwCczklFc8PSZ pl98DUavgqHYPKM4l8el+QgAATCSymgZvonFrHXKXfh8W7ErVkLVUPgUI47gjHDFEC//lxnjMuB Ah7GBoiPyRYncjB7Spx393tzOSke62JA= X-Gm-Gg: Acq92OH5umceW4hzaZnofEyJaSzu0cPFD1Q/VH0OadWlzFK3UR3oOvphh2vyc1+tq0Z cYqUD8KeLMHOU89ywNmR90MwIrrDmhUtOxUVGcKx1aiqiNR/UqsVzvYLS8E37df5KYf3niJW3C/ 1ryatDQsasil/iGkYXHpcDQu7Q7o5iueoSimrbi5XiJCKdhnk1BYqHhD0W1yEAohfK4DHF/HXFb RkYQhmvgNVEg3o0WgqKCr5YuT1Iku46WRqcuQltTrI+do0vJYQaydTc82/zXBUOtDdLb9y5RzL2 U7eCMP/aD85s4J3tT+3q X-Received: by 2002:a05:690e:4090:b0:654:5d65:9fe1 with SMTP id 956f58d0204a3-65eadfea061mr1222858d50.8.1779346195067; Wed, 20 May 2026 23:49:55 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: vignesh C Date: Thu, 21 May 2026 12:19:42 +0530 X-Gm-Features: AVHnY4KSycHK4tIx6nOVWy63EVJGBS0zl_2-xD5g1D_FhiZem9GmDHC7ag8DAI8 Message-ID: Subject: Re: [PATCH] Release replication slot on error in SQL-callable slot functions To: Fujii Masao Cc: SATYANARAYANA NARLAPURAM , PostgreSQL Hackers 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 On Mon, 11 May 2026 at 08:31, Fujii Masao wrote: > > On Sun, May 10, 2026 at 5:45=E2=80=AFAM SATYANARAYANA NARLAPURAM > wrote: > > > > Hi Hackers, > > > > SQL-callable replication slot functions acquire a slot (setting > > the process-global MyReplicationSlot) but can then ERROR before reachin= g > > ReplicationSlotRelease(). If such an error is caught by a PL/pgSQL > > EXCEPTION block (which uses a subtransaction), MyReplicationSlot remain= s > > set because there is no subtransaction-level cleanup hook for replicati= on > > slots. > > > > Any subsequent slot operation in the same session then hits > > Assert(MyReplicationSlot =3D=3D NULL) and crashes the backend on assert > > enabled builds. In release builds the stale MyReplicationSlot is silent= ly overwritten, > > permanently orphaning the old slot as "active." The orphaned slot block= s any other > > session from acquiring it, vacuum and WAL deletion. > > > > Repro: > > > > SELECT pg_create_logical_replication_slot('adv_test', 'test_decoding'); > > > > DO $$ BEGIN > > PERFORM pg_replication_slot_advance('adv_test', '0/1'::pg_lsn); > > EXCEPTION WHEN others THEN > > RAISE NOTICE 'caught: %', SQLERRM; > > END $$; > > > > SELECT count(*) FROM pg_logical_slot_get_changes('adv_test', NULL, NULL= ); > > > > 2026-05-09 19:45:06.619 UTC [1096805] STATEMENT: SELECT pg_create_logi= cal_replication_slot('adv_test', 'test_decoding'); > > TRAP: failed Assert("MyReplicationSlot =3D=3D NULL"), File: "slot.c", L= ine: 638, PID: 1096805 > > > > > > Attached a patch to address this by wrapping error-prone paths in PG_TR= Y/PG_CATCH blocks > > and call ReplicationSlotRelease(). > > Thanks for the report and the patch! > > I think wrapping the slot-processing code with PG_TRY()/PG_CATCH() seems > a good direction for addressing the issue you reported. > > > + PG_CATCH(); > + { > + ReplicationSlotRelease(); > > When create_logical_replication_slot() is called with temporary =3D true, > the created logical replication slot has RS_TEMPORARY persistency. Such a= slot > is not dropped by ReplicationSlotRelease(), whereas an RS_EPHEMERAL slot = is > dropped via ReplicationSlotDropAcquired(). > > So even with the v1 patch, a temporary logical replication slot can remai= n > unexpectedly if pg_create_logical_replication_slot() throws an error. > In this case, should create_logical_replication_slot() explicitly drop th= e slot > with ReplicationSlotDropAcquired(), or temporarily change the slot persis= tency > to RS_EPHEMERAL before calling ReplicationSlotRelease()? > > > Does a newly created logical replication slot created by > pg_copy_logical_replication_slot() have the same issue? Additionally pg_logical_slot_get_changes also has the same issue, it can be reproduced by the following: SELECT pg_create_logical_replication_slot('test_slot_1', 'test_decoding'); DO $$ BEGIN -- This will ERROR if the slot_get changes fails for the slot. PERFORM 1 FROM pg_logical_slot_get_changes('test_slot_1', NULL, NULL, 'nonexistent-option', 'val'); EXCEPTION WHEN others THEN RAISE NOTICE 'caught: %', SQLERRM; END $$; SELECT count(*) FROM pg_logical_slot_get_changes('test_slot_1', NULL, NULL)= ; TRAP: failed Assert("MyReplicationSlot =3D=3D NULL"), File: "slot.c", Line: 638, PID: 80308 postgres: vignesh postgres [local] SELECT(ExceptionalCondition+0xba) [0x642e7b2ebae1] postgres: vignesh postgres [local] SELECT(ReplicationSlotAcquire+0x6e) [0x642e7b00d732] Regards, Vignesh