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 1w5hKn-003X60-2s for pgsql-hackers@arkaria.postgresql.org; Thu, 26 Mar 2026 09:49:02 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w5hKk-001u6p-33 for pgsql-hackers@arkaria.postgresql.org; Thu, 26 Mar 2026 09:48: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 1w5hKk-001u6h-20 for pgsql-hackers@lists.postgresql.org; Thu, 26 Mar 2026 09:48:59 +0000 Received: from mail-vs1-xe2c.google.com ([2607:f8b0:4864:20::e2c]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w5hKi-00000001GPg-26L8 for pgsql-hackers@postgresql.org; Thu, 26 Mar 2026 09:48:58 +0000 Received: by mail-vs1-xe2c.google.com with SMTP id ada2fe7eead31-604d532cfc5so446044137.3 for ; Thu, 26 Mar 2026 02:48:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1774518534; cv=none; d=google.com; s=arc-20240605; b=U8VZzukvSmIqA8L9BvUi77EIe2vNFmMNKmkAG+1dmBqbtVG7fFxVKyqmuTc9b6l/0n mWXX0yPipf/gJKjb5NzrY4yp55/XUV+72v8TFDxh/8z7i6uiQ/1I50aKeQ2iqZ6NRHTa lNpUCFNDejnjnf/pjCtf1OJf50SC2sCBqViTat3FgKtGMeauCQggkf/zzIx/vKdtVTHa /GDiJyHotz4qJJC5aY1mdEtHpTfsDYCjhqgagjHSTZcjGIR25162sPlLtqZOdALG4nis J/hvZfUavo7f7sFHysfzA07vjWpK/Gec21VgSlLpHJFzJhjKcoC+5vz7i7KuvI10aRX+ 3Ptw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=L38ZY5vWzcpVcjafsw+PKRaPAso0JQf24pbiVw2K988=; fh=pYVAB8SY09HQ9hvBLxHKsbxq77RmCS+ZsDqgVFsmJEI=; b=KzgFB7tBl63EkbUylGb+GURUObcdjpFn/aSV14RKq84CLe3XsCdwjnoGLyilodDT/i 04iPzouS/utsuQuPdCV+oIhx1XVJPZ4oeVuw1BFb7XEaqaGI/VKxV9DTG0qPxlc+xGNF vUXx+JkgUAkLbGE7jQU4na/NHZK/wgeQa/iQ5NYwlQlijBfSWlo1VpuNStTs9W/8lSkU H36zzMPWxDBNYN36joIWt/lUEVMBWWvtbxH7r9Sb9UH02JzFtQbLsaIhA+EnoTY15AvX WZqNIWxXFOZn1cPF1GeMwNKZTQnTrXrlVef5Nw+IUJ9rrae4+HehbS3uK3w/AKNysLXr HaSw==; 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=1774518534; x=1775123334; darn=postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=L38ZY5vWzcpVcjafsw+PKRaPAso0JQf24pbiVw2K988=; b=cLAUbTKppWoOyTr5RhO0p/ywXL3NY/fPk+ZkTml8T+G6a3RD0TaEpweQIRWc3HvuPY m0WrvE2Aui9s9wxCecyWFIYCZHYto+1jLJDmU0Rr+1iiIv1LnD8lc0XTC5wPoiS2rmuQ gdtpETOm60Fc3AnNQb4QY5e5qK9JJTl+xKEa2sXMssW7p8oOERZQmwppUkRwP/qxiF5S yq4w5bhgPI0sOuIG508LrdYb7IOY/XIC9FNQLEUMNwj9Z26zgjWZ6JKIX/j0Lt6wQpen 8l+sc5HLBq/DTgi5PCH1fqUwLwgFD5pkOTw7YSm7BGJ1y/kUldFObRI/HiAtemfYKEj8 KrBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774518534; x=1775123334; h=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=L38ZY5vWzcpVcjafsw+PKRaPAso0JQf24pbiVw2K988=; b=d+EBbLRTYd6egYrB9wf9Tik7TdeD60y5sMYU1OeL9Z4Pa+G/9yiQl51DbK80vFPCYp EjFKS7ZvFTAgCXQ9UIcQRTHVDP41Xy42lMxrSGsdc+D4eok3qWK23zFqKDwfzv61SKU9 bnhA17maQqn59QD6zgbgZopbAvr70/i+Cuy0oHljSj0tF+y/vQIL2qmxla2Vyl0Q5TI3 79kTDd/gbtJcSFu90RZCy9679ECLTvbREJEc2yBOeD9SWb1a/vvIzgBd0mnERU8lalqe RJEWGzkmDirxa+tCrUdqZMPhmGiw43XdfqsEWLdtJ4Zo3vigpOwQhsNlKe45JEBYYMA0 8kcg== X-Forwarded-Encrypted: i=1; AJvYcCXAwhtkL1u+TcUCb6yyEK2aP7nCD/cxbJpEPzWAJ4TanKIbEB+EiBDK6OQN1W/LD+x5Db3JJlRljlHuiOjM@postgresql.org X-Gm-Message-State: AOJu0Ywz0/5tIIpGNfqcW2AaCglApltIjtYoOs4WkHi+3kNBcsXkLKze j3JIlZIZ9HzdCstdVi7YP6x66C+msheVdnsxuPgMkkIXTNqtt/rmqIupPnWOnK5moFbmbLPJ+Fb WKWNacteUx6X6Lf0bVyuCIjNEww1+5g0= X-Gm-Gg: ATEYQzxfJhNllXzp6jPU/Z4vhEjVq2SrU6jHV2GeujjaqbyYbk5NWKNUWR7e7fbgL0/ RdY6WhaxHNW0vYZKQ6Tney+8EHagF7lnuaGSxQkN+dxyDRfI31RQY3WiS7fbaQ+I4BF34VCKPUb ygINEVKyT1kEEIWgyjjKnhngWa3DxrUsL7rBgfzVkXc5Y/upStKzt0KCwq18DqEJr6+bTVT+EYW VQnXOadPaFCkvLiyyURdBoc91J51AZS2F1CmGWaWAwwqnKb56QQPcrVErReCuxilAE0h44kV81/ Ig6UIQJjLvpylKDDnQ== X-Received: by 2002:a05:6102:604e:b0:604:ea95:d3ac with SMTP id ada2fe7eead31-604ea95db1bmr132120137.27.1774518534376; Thu, 26 Mar 2026 02:48:54 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: SATYANARAYANA NARLAPURAM Date: Thu, 26 Mar 2026 02:48:42 -0700 X-Gm-Features: AQROBzDZk3crfHofe8E7AU5OYUxHXO51eM9YvCJCpNjBQJvclnNTDPlLVX1MaCA Message-ID: Subject: Re: Introduce XID age based replication slot invalidation To: Bharath Rupireddy Cc: Masahiko Sawada , "Hayato Kuroda (Fujitsu)" , John H , PostgreSQL-development Content-Type: multipart/alternative; boundary="000000000000e39160064dea4ab5" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000e39160064dea4ab5 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, Mar 25, 2026 at 12:17=E2=80=AFPM Bharath Rupireddy < bharath.rupireddyforpostgres@gmail.com> wrote: > Hi, > > On Tue, Mar 24, 2026 at 11:50=E2=80=AFPM Masahiko Sawada > wrote: > > > > > Please find the v3 patch for further review. > > > > Thank you for updating the patch. I think the patch is reasonably > > simple and can avoid unnecessary overheads well due to XID-based > > checks. Here are some comments: > > Thank you for reviewing the patch. > > > vacuum_get_cutoff() is also called by VACUUM FULL, CLUSTER, and > > REPACK. I'm not sure that users would expect the slot invalidation > > also in these commands. I think it's better to leave > > vacuum_get_cutoff() a pure cutoff computation function and we can try > > to invalidate slots in heap_vacuum_rel(). It requires additional > > ReadNextTransactionId() but we can live with it, or we can make > > vacuum_get_cutoffs() return the nextXID as well (stored in *cutoffs). > > +1. I chose to perform the slot invalidation in heap_vacuum_rel by > getting the next txn ID and calling vacuum_get_cutoffs again when a > slot gets invalidated. IMHO, this is simple than adding a flag and do > the invalidation selectively in vacuum_get_cutoffs. > > > if (TransactionIdPrecedes(oldestXmin, cutoffXID)) > > + { > > + invalidated =3D > InvalidateObsoleteReplicationSlots(RS_INVAL_XID_AGE, > > + 0, > > + InvalidOid, > > + > InvalidTransactionId, > > + nextXID); > > + } > > > > I think it's better to check the procArray->replication_slot_xmin and > > procArray->replication_slot_catalog_xmin before iterating over each > > slot. Otherwise, we would end up checking every slot even when a long > > running transaction holds the oldestxmin back. > > +1. Changed. > > > + if (!TransactionIdIsNormal(cutoffXID)) > > + cutoffXID =3D FirstNormalTransactionId; > > > > These codes have the same comment but are doing a slightly different > > thing. I guess the latter is missing '-'? > > Fixed the typo. > > I fixed a test error being reported in CI. > > Please find the attached v4 patch for further review. > InvalidateObsoleteReplicationSlots(uint32 possible_causes, XLogSegNo oldestSegno, Oid dboid, - TransactionId snapshotConflictHorizon) + TransactionId snapshotConflictHorizon, TransactionId nextXID) May be add TransactionId nextXID in a new line? Thinking loud, vacuum doesn't run on a hot_standby, that means this GUC is not applicable for hot_standby. Is this intended? Why not call during checkpoint/restorepoint itself like other slot invalidation checks? Thanks, Satya --000000000000e39160064dea4ab5 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


On Wed, Mar 25, 2026= at 12:17=E2=80=AFPM Bharath Rupireddy <bharath.rupireddyforpostgres@gm= ail.com> wrote:
Hi,

On Tue, Mar 24, 2026 at 11:50=E2=80=AFPM Masahiko Sawada <sawada.mshk@gmail.com> = wrote:
>
> > Please find the v3 patch for further review.
>
> Thank you for updating the patch. I think the patch is reasonably
> simple and can avoid unnecessary overheads well due to XID-based
> checks. Here are some comments:

Thank you for reviewing the patch.

> vacuum_get_cutoff() is also called by VACUUM FULL, CLUSTER, and
> REPACK. I'm not sure that users would expect the slot invalidation=
> also in these commands. I think it's better to leave
> vacuum_get_cutoff() a pure cutoff computation function and we can try<= br> > to invalidate slots in heap_vacuum_rel(). It requires additional
> ReadNextTransactionId() but we can live with it, or we can make
> vacuum_get_cutoffs() return the nextXID as well (stored in *cutoffs).<= br>
+1. I chose to perform the slot invalidation in heap_vacuum_rel by
getting the next txn ID and calling vacuum_get_cutoffs again when a
slot gets invalidated. IMHO, this is simple than adding a flag and do
the invalidation selectively in vacuum_get_cutoffs.

>=C2=A0 =C2=A0if (TransactionIdPrecedes(oldestXmin, cutoffXID))
> +=C2=A0 =C2=A0{
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0invalidated =3D InvalidateObsoleteReplicat= ionSlots(RS_INVAL_XID_AGE,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 InvalidOid,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 InvalidTransactionId,<= br> > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 nextXID);
> +=C2=A0 =C2=A0}
>
> I think it's better to check the procArray->replication_slot_xm= in and
> procArray->replication_slot_catalog_xmin before iterating over each=
> slot. Otherwise, we would end up checking every slot even when a long<= br> > running transaction holds the oldestxmin back.

+1. Changed.

> +=C2=A0 =C2=A0if (!TransactionIdIsNormal(cutoffXID))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0cutoffXID =3D FirstNormalTransactionId; >
> These codes have the same comment but are doing a slightly different > thing. I guess the latter is missing '-'?

Fixed the typo.

I fixed a test error being reported in CI.

Please find the attached v4 patch for further review.
=
=C2=A0InvalidateObsoleteReplicationSlots(uint32 possible_cau= ses,
=C2=A0 =C2=A0 XLogSegNo oldestSegno, Oid dboid,
- = =C2=A0 TransactionId snapshotConflictHorizon)
+ =C2=A0 Transac= tionId snapshotConflictHorizon, TransactionId nextXID)

=
May be add=C2=A0TransactionId nextXID in a new line?

Thinking loud, vacuum doesn't=C2=A0 run on a hot_standby, that = means this GUC is not applicable for hot_standby. Is this intended? Why not= call during checkpoint/restorepoint itself like other slot invalidation ch= ecks?=C2=A0

Thanks,
Satya
--000000000000e39160064dea4ab5--