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 1wRjX2-002dj3-0a for pgsql-hackers@arkaria.postgresql.org; Tue, 26 May 2026 04:36:44 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wRjWy-002nlX-2o for pgsql-hackers@arkaria.postgresql.org; Tue, 26 May 2026 04:36:41 +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 1wRjWy-002nlO-1H for pgsql-hackers@lists.postgresql.org; Tue, 26 May 2026 04:36:41 +0000 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wRjWx-00000001SgJ-0zZj for pgsql-hackers@lists.postgresql.org; Tue, 26 May 2026 04:36:41 +0000 Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-2bccb978bd9so63211375ad.0 for ; Mon, 25 May 2026 21:36:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1779770196; cv=none; d=google.com; s=arc-20240605; b=DD+K3YXaDJKgEyWUIlsV5pbksVUiqETydMOiUvQwXb6PrZRNOZYfV63QzqCiv3clwG KUKLEAmOx7pDf18r2YHK3IGcF49FwTHeEw2SnYNmHbkV8dfqykZw/526fxKQbaW8SZfj vx9Ejqxt1bVdk6nMfBgWxpJRMie953Svde58kwwn7KRYBYCFrFs8XajXe4quqFwJHkpa GD3bMW6SVCAc0/b5et2zbesmk0VGuKtjjr1iNMnpKqlRiBatsOgpvhJxNv+TxeI/FyOW 57FIlTiXO5zc0Y/qU/xh7YJdByEGJGtNomXL9NDsA6XKo4wVPN63/oNk5JADqxB8NANG qPnA== 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=KNz0GnLcdxlUO8/xVeHiAxUYzJxZnvTH9piP9/XKAOc=; fh=ia7hDlTUKvIxKfnLTwusZPMlpP6nLmqBLqj/esuokMg=; b=gQU1oLFYhekwh1Zdf8+e5YJI4hjik79A2M+11JIsemVQdIb3FcSXekW45hdIxxBSY0 Q7iAkZx361U15vNQGaGG6cPz9o1Si7ecD0VDqEFy79K3s0okqCzDYJi/RwwUXgpRv6Xi z8xIHGtPYKZ/MvabojLuSDPayfH3hah/giqUNaK7WSBMo7YiZ5xxxVk3aFwc28LTdzPS OZNf+SOl3ii15VrpFfwEZb+tBVh5RtR0s1IO1Ops8JI57K3UV0RRztvI/q4pfVBUa8oJ aJjKYxFyPYGWr1RqwYUEh/AaNru2+51Kkio47DTBuGi/Yf09D96VWbHH3AWgRObcS1IG nffA==; 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=1779770196; x=1780374996; 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=KNz0GnLcdxlUO8/xVeHiAxUYzJxZnvTH9piP9/XKAOc=; b=sALTWE2sJ4wBKVRL71LXca85hQlEt31xZEEQsnNqkj5K/HdyIUQZAtL//GPfa9EXIU BgLJw5DhoqD0xeMTBWxZkhiaHyrinL4fs1tJvnQRalBmMO3wfWZF+/kEpUk7OonyKfVE EXZvQ/MllRQOoeb/MZ+7Y0SC/ZGSV2yBd3Wddy83ckLF7BxaUcwnS2MtbVlx7aNPST0m V0ckNqGk4ZQOKZQVznCQQxAi2p8kjYulbX8kP7hJj16c7E2ElHxZoN7ZpagQiLbFxZHl 7BBCxcE8Mpqq/An1wMJsUjxn7qsnzZwZMIop7BbWZeWkIZYy1mpxgpdhJJ6K8suiDRrT /JNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779770196; x=1780374996; 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=KNz0GnLcdxlUO8/xVeHiAxUYzJxZnvTH9piP9/XKAOc=; b=cAsY4eduYxd9qfFmIZx7G8eaz+Cqz7nLBduh/HmDC5C8tlNZ+l2FHOb7e7Umc6COSp B73XDlRtIdA/oOSmn1fRpFjSa2w914p+YIqRQJEZsC+2SkXCfCvOErpA0xR6z4BiE1xB u6DSSfzzVlHi936JhyowOpo0njjfzM/Miau9aVMP8UcsTb7Dvhop7wZkvwxDZFK5yyzd YPZu9DeWDR8YXGsP9vU1eKfMVbFF3L6wsLqGND1FbsFGpVBRXWVg1NMat+XmXbgaHNhd bs1KhsIyOLZ06/L6nLVGXogVxuEyQchPcz1rUp0kbmwkdbCIkLyzz33JOA1xTDtn9c6q lkPA== X-Forwarded-Encrypted: i=1; AFNElJ8NHZf4JKD7varIlzqcjAbAWv0ClOdPCRbCwVhOk9hEF+ruJfPHQeQxVuj4DVvr8N5mWP4nj62WQKTC2ULM@lists.postgresql.org X-Gm-Message-State: AOJu0YzJax6G6gNLNGhMGi9yg27Cw3KunHsLd58tvfFztBpePe/CQ7n/ ma5rsKhX6dSkm4zk5b2ajQ8W8hA0xGpv18IDva/TlrDMMDewyb3swGicCNelZZJc1Xp9rXGHnuv Zq0wv+lw5gRRd5QVtlxxEHA6WyFB66ug= X-Gm-Gg: Acq92OFqwtpR0QfjzmuD1Tz5gcDCXSDumO3v93ftJ8mGDBpKH6SBlcuW/3JC8YsAphP OI7tmQXul+MUozYXIrjY+i7rM3jDgChYQXGTJW+HC27DR1AXJWUXvbcMPCmA/a690giYrIROIlf Wcts9eSbaTfNKuQJPQjydLhMfowFfnnL60bjmdcq19J+Wx0y5miJM8neBZQcHhXn1xt3v+20nMs twCxdv4Lk7fAB3aYTD/nkUaEy/CtKFyutxnS+yLoE6LfgLnZhgelgfZ7s66977Gcw4tnhVs/vh5 FohVHrKf9VcRIW39wmS2laJcP31kZGZH/TKqT/F1hkfmggApJzxr X-Received: by 2002:a17:903:38c3:b0:2ba:a7f4:15b0 with SMTP id d9443c01a7336-2beb08a91a1mr162114935ad.19.1779770196495; Mon, 25 May 2026 21:36:36 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: shveta malik Date: Tue, 26 May 2026 10:06:24 +0530 X-Gm-Features: AVHnY4Kt_gaayXh9UV3WXjzhLUjthYrZa9-gN5Jztn1E1fDVapbPXoF431qbgm4 Message-ID: Subject: Re: [PATCH] Release replication slot on error in SQL-callable slot functions To: SATYANARAYANA NARLAPURAM Cc: vignesh C , Fujii Masao , PostgreSQL Hackers , shveta malik 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 Tue, May 26, 2026 at 12:31=E2=80=AFAM SATYANARAYANA NARLAPURAM wrote: > > Hi, > > On Mon, May 25, 2026 at 2:58=E2=80=AFAM shveta malik wrote: >> >> On Mon, May 25, 2026 at 12:42=E2=80=AFPM SATYANARAYANA NARLAPURAM >> wrote: >> > >> > Hi >> > >> > On Fri, May 22, 2026 at 2:16=E2=80=AFAM shveta malik wrote: >> >> >> >> Thanks for reporting the issue. I could reproduce the same issue with >> >> all these as well: >> >> >> >> pg_logical_slot_peek_changes >> >> pg_logical_slot_get_binary_changes >> >> pg_logical_slot_peek_binary_changes >> > >> > >> > Please find the attached v2 patch that addressed these three cases as = well. >> > >> >> Thank You for addressuing these cases. A few comments: >> >> 1) >> >> +-- Test 2: session remains usable after the error (MyReplicationSlot cl= eared) >> >> It shoudl be part of 'Test 1' itself and thus should not be named as 'Te= st 2' >> >> 2) >> -------- >> +-- Test 4: copy_replication_slot with max_replication_slots exceeded. >> +-- We reduce max_replication_slots artificially by filling all remainin= g slots. >> +-- Instead, trigger an error by copying to an already-existing name. >> +DO $$ >> +BEGIN >> + PERFORM pg_copy_logical_replication_slot('regression_slot_t3', >> 'regression_slot_t3'); >> +EXCEPTION WHEN OTHERS THEN >> + RAISE NOTICE 'caught: %', SQLERRM; >> +END; >> +$$; >> +-- The original slot must still exist and be usable >> +SELECT count(*) =3D 1 AS orig_slot_ok FROM pg_replication_slots >> + WHERE slot_name =3D 'regression_slot_t3'; >> ----------- >> >> I don't think we can hit the Assert with above test (at-least I could >> not). Since creation of slot itself will fail as the slot with >> same-name already exists, MyReplicationSlot will never be set and thus >> Assert will not be hit. A better testcase will be below which fails >> during LoadOutputPlugin() after slot-creation and MyReplicationSlot is >> set already. >> >> SELECT pg_create_logical_replication_slot('src_slot', 'test_decoding'); >> >> DO $$ >> BEGIN >> PERFORM pg_copy_logical_replication_slot('src_slot', 'dst_slot', >> false, 'nonexistent_plugin'); >> EXCEPTION WHEN others THEN >> RAISE NOTICE 'caught: %', SQLERRM; >> END $$; >> >> SELECT count(*) FROM pg_logical_slot_get_changes('src_slot', NULL, NULL)= ; >> >> 3) >> So overall these are the problematic APIs: >> >> pg_create_logical_replication_slot >> pg_replication_slot_advance >> pg_copy_logical_replication_slot >> pg_logical_slot_peek_binary_changes >> pg_logical_slot_peek_changes >> pg_logical_slot_get_changes >> pg_logical_slot_get_binary_changes >> >> First 3 are are mutually exclusive fixes fow which we have added >> testcases. Last 4 are addressed by fixing common function >> pg_logical_slot_get_changes_guts(). I think we should add a test case >> for at-least any one of these APIs to cover >> pg_logical_slot_get_changes_guts(). > > > Thanks for reviewing. Please review the attached v3 patch. > A few trivial things: 1) pg_replication_slot_advance: + PG_TRY(); + { + /* Acquire the slot so we "own" it */ + ReplicationSlotAcquire(NameStr(*slotname), true, true); + /* A slot whose restart_lsn has never been reserved cannot be advanced */ + if (!XLogRecPtrIsValid(MyReplicationSlot->data.restart_lsn)) We can have a blank line after ReplicationSlotAcquire for better readabilit= y. 2) +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_t3', 'test_decoding', true); +SELECT count(*) =3D 1 AS slot_exists FROM pg_replication_slots + WHERE slot_name =3D 'regression_slot_t3'; The intent is not clear why are we checking existence of regression_slot_t3? I think we can skip it (or else add a comment if really needed). The success of previous pg_create_logical_replication_slot is enough to confirm that session is healthy to run other slot related queries. 3) +SELECT pg_drop_replication_slot('regression_slot_phy'); + +-- cleanup +SELECT pg_drop_replication_slot('regression_slot_t3'); We can move drop of 'regression_slot_phy' too under '-- cleanup' ~~ I have no further comments other than the trivial things mentioned above. thanks Shveta