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.94.2) (envelope-from ) id 1tDIUm-00HKOP-En for pgsql-hackers@arkaria.postgresql.org; Tue, 19 Nov 2024 07:17:56 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tDIUj-00B8gH-SH for pgsql-hackers@arkaria.postgresql.org; Tue, 19 Nov 2024 07:17:54 +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.94.2) (envelope-from ) id 1tDIUj-00B8g9-FI for pgsql-hackers@lists.postgresql.org; Tue, 19 Nov 2024 07:17:54 +0000 Received: from mail-lj1-x22c.google.com ([2a00:1450:4864:20::22c]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1tDIUh-002hp9-Ui for pgsql-hackers@lists.postgresql.org; Tue, 19 Nov 2024 07:17:53 +0000 Received: by mail-lj1-x22c.google.com with SMTP id 38308e7fff4ca-2fb51e00c05so35305761fa.0 for ; Mon, 18 Nov 2024 23:17:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1732000670; x=1732605470; 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=jg9S3PStPpA39tObNSUTtl8Z3s4lxfFuEtEKVnf+2hs=; b=GJDl1Rhl8MSB0BYbofC9U4BT/GdaIVM8bsDS9AApL8uHIrnhv0fymICn+EjVqBVSDu wKWg1qIRCYGQb+vjTZSCyEWEBvJaA5+PAj2tJGqGk1l9ShPRspBbUMqWuaLA7Ww1y4cF EfvmgUFRiY5XOfvle6MuMmk7gh4n40H7fNuA6mt7h/cRDWkhg3Gbd0doBj6LlQxEmJFS zLsAVHXnuqlS1GIkdtgiv71+KROoFA3pgUg17mem5fjAYoKkX1OiQf1mV1IrUmZfSla4 3FhrPWQ2G9wI6VFMyDBINc4wpQCzIdHuqumfClT4S5I0z2doRRtfSObJqB01uGOrQf8B e+rA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732000670; x=1732605470; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jg9S3PStPpA39tObNSUTtl8Z3s4lxfFuEtEKVnf+2hs=; b=fQzuPxY1WivsNC6VwPgrjqFTdyGUA9KfcUI1KoJpH/D1kUgXZnN75myUBRM6sxGOWW RqwkGK8VRW4HDJ5Amm9eTg3goTVX44YxfmvoiWIotIqAulzRCoJHi7UrI3vYcP15RylB bK54K/ZRylqLWNCUdjPMWzZbC8/f5ddSiPkjEGuc+YaQZekIuc7yKtqQIv9dPRuekkJ8 IpOSn9E/3ZyRf85IV6RRwqNzs1Yn+TmU9/RZYtIgtvt0/Y1QLQRzFS2JfJyEpnwGwaHy M+R+1oWA71nGDr0izeA8japjUPoQQRBo/tmyvJ6s37HL/9GndgJVNecnmum22vJeukTs f48A== X-Forwarded-Encrypted: i=1; AJvYcCUdGSQfZn7gvdhYq+CGVF6YsFIAqCvud3LtAXWMa4hIBy36p8hW5LgYzEq+ZDv550mm6zEdoiOAj2TIn+hC@lists.postgresql.org X-Gm-Message-State: AOJu0YwDmI6lkK12d5xI7vr0Oed/F7GFe56DqzOifX7CY9Hlm/mtOR23 rdwftAT1dEklTnuFPL3POWVh1NvObxboS3cQVGhHi8AZh9X7MCDCVZU00WNywp6wEvW42uuSINZ qLGYVsRuJPujM9moJjcAjQkdzsvA/wvS/qQe0 X-Google-Smtp-Source: AGHT+IFQmTCz6KjBJG3SUE7kDTRcTqZlQV16PnVK/iXniJhrjQ4vApZh7xxeHlOwZo5PdobaQBVYtHzHAw8Bbwg+qlo= X-Received: by 2002:a2e:9a0f:0:b0:2fb:6110:c5df with SMTP id 38308e7fff4ca-2ff606db449mr114089261fa.31.1732000669272; Mon, 18 Nov 2024 23:17:49 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Nisha Moond Date: Tue, 19 Nov 2024 12:47:37 +0530 Message-ID: Subject: Re: Introduce XID age and inactive timeout based replication slot invalidation To: Peter Smith Cc: shveta malik , Bharath Rupireddy , Amit Kapila , Ajin Cherian , Bertrand Drouvot , Masahiko Sawada , Nathan Bossart , 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 Thu, Nov 14, 2024 at 5:29=E2=80=AFAM Peter Smith = wrote: > > Hi Nisha. > > Thanks for the recent patch updates. Here are my review comments for > the latest patch v48-0001. > Thank you for the review. Comments are addressed in v49 version. Below is my response to comments that may require further discussion. > =3D=3D=3D=3D=3D=3D > doc/src/sgml/system-views.sgml > > 2. > > The time since the slot has become inactive. > - NULL if the slot is currently being used. > - Note that for slots on the standby that are being synced from a > + NULL if the slot is currently being used. Onc= e the > + slot is invalidated, this value will remain unchanged until we s= hutdown > + the server. Note that for slots on the standby that are being > synced from a > primary server (whose synced field is > true), the > > Is this change related to the new inactivity timeout feature or are > you just clarifying the existing behaviour of the 'active_since' > field. > Yes, this patch introduces inactive_timeout invalidation and prevents updates to inactive_since for invalid slots. Only a node restart can modify it, so, I believe we should retain these lines in this patch. > Note there is already another thread [1] created to patch/clarify this > same field. So if you are just clarifying existing behavior then IMO > it would be better if you can to try and get your desired changes > included there quickly before that other patch gets pushed. > Thanks for the reference, I have posted my suggestion on the thread. > > ReplicationSlotAcquire: > > 5. > + * > + * An error is raised if error_if_invalid is true and the slot has been > + * invalidated previously. > */ > void > -ReplicationSlotAcquire(const char *name, bool nowait) > +ReplicationSlotAcquire(const char *name, bool nowait, bool error_if_inva= lid) > > This function comment makes it seem like "invalidated previously" > might mean *any* kind of invalidation, but later in the body of the > function we find the logic is really only used for inactive timeout. > > + /* > + * An error is raised if error_if_invalid is true and the slot has been > + * previously invalidated due to inactive timeout. > + */ > > So, I think a better name for that parameter might be > 'error_if_inactive_timeout' > > OTOH, if it really is supposed to erro for *any* kind of invalidation > then there needs to be more ereports. > +1 to the idea. I have created a separate patch v49-0001 adding more ereports for all kinds of invalidations. > ~~~ > SlotInactiveTimeoutCheckAllowed: > > 8. > +/* > + * Is this replication slot allowed for inactive timeout invalidation ch= eck? > + * > + * Inactive timeout invalidation is allowed only when: > + * > + * 1. Inactive timeout is set > + * 2. Slot is inactive > + * 3. Server is in recovery and slot is not being synced from the primar= y > + * > + * Note that the inactive timeout invalidation mechanism is not > + * applicable for slots on the standby server that are being synced > + * from the primary server (i.e., standby slots having 'synced' field 't= rue'). > + * Synced slots are always considered to be inactive because they don't > + * perform logical decoding to produce changes. > + */ > > 8a. > Somehow that first sentence seems strange. Would it be better to write it= like: > > SUGGESTION > Can this replication slot timeout due to inactivity? > I feel the suggestion is not very clear on the purpose of the function, This function doesn't check inactivity or decide slot timeout invalidation. It only pre-checks if the slot qualifies for an inactivity check, which the caller will perform. As I have changed function name too as per commnet#9, I used the following = - "Is inactive timeout invalidation possible for this replication slot?" Thoughts? > ~ > 8c. > Similarly, I think something about that "Note that the inactive > timeout invalidation mechanism is not applicable..." paragraph needs > tweaking because IMO that should also now be saying something about > 'RecoveryInProgress'. > 'RecoveryInProgress' check indicates that the server is a standby, and the mentioned paragraph uses the term "standby" to describe the condition. It seems unnecessary to mention RecoveryInProgress separately. > ~~~ > > InvalidatePossiblyObsoleteSlot: > > 10. > break; > + case RS_INVAL_INACTIVE_TIMEOUT: > + > + /* > + * Check if the slot needs to be invalidated due to > + * replication_slot_inactive_timeout GUC. > + */ > > Since there are no other blank lines anywhere in this switch, the > introduction of this one in v48 looks out of place to me. pgindent automatically added this blank line after 'case RS_INVAL_INACTIVE_TIMEOUT'. > IMO it would > be more readable if a blank line followed each/every of the breaks, > but then that is not a necessary change for this patch so... > Since it's not directly related to the patch, I feel it might be best to leave it as is for now. > ~~~ > > 11. > + /* > + * Invalidation due to inactive timeout implies that > + * no one is using the slot. > + */ > + Assert(s->active_pid =3D=3D 0); > > Given this assertion, does it mean that "(s->active_pid =3D=3D 0)" should > have been another condition done up-front in the function > 'SlotInactiveTimeoutCheckAllowed'? > I don't think it's a good idea to check (s->active_pid =3D=3D 0) upfront, before the timeout-invalidation check. AFAIU, this assertion is meant to ensure active_pid =3D 0 only if the slot is going to be invalidated, i.e., when the following condition is true: TimestampDifferenceExceeds(s->inactive_since, now, replication_slot_inactive_timeout_sec * 1000) Thoughts? Open to others' opinions too. > ~~~ > > 12. > /* > - * If the slot can be acquired, do so and mark it invalidated > - * immediately. Otherwise we'll signal the owning process, below, and > - * retry. > + * If the slot can be acquired, do so and mark it as invalidated. If > + * the slot is already ours, mark it as invalidated. Otherwise, we'll > + * signal the owning process below and retry. > */ > - if (active_pid =3D=3D 0) > + if (active_pid =3D=3D 0 || > + (MyReplicationSlot =3D=3D s && > + active_pid =3D=3D MyProcPid)) > > I wasn't sure how this change belongs to this patch, because the logic > of the previous review comment said for the case of invalidation due > to inactivity that active_id must be 0. e.g. Assert(s->active_pid =3D=3D > 0); > I don't fully understand the purpose of this change yet. I'll look into it further and get back. > ~~~ > > RestoreSlotFromDisk: > > 13. > - slot->inactive_since =3D GetCurrentTimestamp(); > + slot->inactive_since =3D now; > > In v47 this assignment used to call the function > 'ReplicationSlotSetInactiveSince'. I recognise there is a very subtle > difference between direct assignment and the function, because the > function will skip assignment if the slot is already invalidated. > Anyway, if you are *deliberately* not wanting to call > ReplicationSlotSetInactiveSince here then I think this assignment > should be commented to explain the reason why not, otherwise someone > in the future might be tempted to think it was just an oversight and > add the call back in that you don't want. > Added comment saying avoid using ReplicationSlotSetInactiveSince() here as it will skip the invalid slots. ~~~~ -- Thanks, Nisha