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 1wWVeL-002fH8-1A for pgsql-hackers@arkaria.postgresql.org; Mon, 08 Jun 2026 08:48: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 1wWVeK-001WM9-0l for pgsql-hackers@arkaria.postgresql.org; Mon, 08 Jun 2026 08:48:00 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wWVeJ-001WM1-2I for pgsql-hackers@lists.postgresql.org; Mon, 08 Jun 2026 08:47:59 +0000 Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wWVeH-00000001ez0-1QYd for pgsql-hackers@postgresql.org; Mon, 08 Jun 2026 08:47:58 +0000 Received: by mail-wr1-x42a.google.com with SMTP id ffacd0b85a97d-45efa80e0afso3111726f8f.2 for ; Mon, 08 Jun 2026 01:47:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780908471; x=1781513271; darn=postgresql.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=i3MUbR7v4oxRAsEMduiZoJUDI0wR9nz2UdmQhzxmWQg=; b=K6Xh5ZO+K/il1CY1sz8JKHdPTshCAWU6gieeIXCUzjd+acP4RMTE7PONaY2FlCtGBN qFASGvPepxHos+8VTOKQleClQoovAYYgPQAbBFHIDxX0LCcSoufxmjTHikDb1dDAlfPG LkbMBuk1Cdd/jPHjfapYlr8v/ywNkossTsZQ06y9SYMZaOXgdt9IEGxFSGEBgcSodzaS perk9AvCMJlzhQjGUQxeE5OMikEjQd9Y8umXjalp5HUpETWJ9jcPJ6/hcfa6P8D4vEhz YiXP7SLdvZ3Lw/K4q2VrtK3hYikNRtbJVrl+jwTZ0JsVmP2EPaCFu0zjnJvZN9iU/NT1 FpWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780908471; x=1781513271; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=i3MUbR7v4oxRAsEMduiZoJUDI0wR9nz2UdmQhzxmWQg=; b=Yov8j2KMdptUAANA3IStXHC4oCcCQpFEcUMksCSh0a9YsjrJfc/n6Ol8qgHO7i2CY0 Qps/Y94y9N7XwysIEaWt2L8ZCAKBFlhzn2m97g65SGQX0/3K9JUeeSa3UTt/RsSuinyE NZk7uXYumj7LdmeLXb71TYI/IExGfTNr3tpahgY+2mMDnU8MgLhxgAs0eF+zJLz4iDV4 KciKdkZe/qRxSqo2lX2P8rFGFz1HXA65Wh1ZACQWnglVOnGfsIT31OvvNKKWyZrXKge0 uClJLircY7yuTf4f/0OEgXAiCQlkyCxiiiG86oadWa6J/7hMI/n/vbEuVsViBPzE7Ry6 Yj0g== X-Forwarded-Encrypted: i=1; AFNElJ/mjEcFh66oLsnFsjh/piQFCL1Zwim+FF6/LDppnKClN4TR7rflCpSwPj/CMa5EXlET4+c7oeGbAkZ1oEeo@postgresql.org X-Gm-Message-State: AOJu0Yypv1g3jmUIh/3BtXcct/9yCrmHkRI4Rr11NaIJYM686b5HwxXp Mx96OphUIiDW7cwrrdy7yIF2YZ2jf/kKP1yZIu7h829czekctpskaAns X-Gm-Gg: Acq92OExo+ta3+MANlTxVqLzCiW7an3BY8HtWobywuTwINLWcY+BNOTgbCn59o8NwoN Lz40q2joTaj6/LUs7dUXAql32kA9ZQ8TvtEekiZsWoVhf8MyoBkRXt16wKgOSWj/OgbPncYBKW3 SkYQEym3tioqEKnnqIVTVRAyp4CW6JkFepN+u+mP2f2HF2J50o1lrQcHMuX4Ei3JIUotSPQDXDv BhPeFGGhJYmXkrz0cccBslIUox4HvFD3IHV0UB7qIKZqACelHXh7+zceCT68TLa29/GtoupbKvG OGRq6FpRj+vAqCqv0rHU3Vb7dTKPiMlr/DGGjZj8ui4yX/yss5pi+5qfYgaM51txjRW7WK7aOR1 HJT85NI76mEhXPv2c857hTR7XFIJAqD2Hd+8z/jyA3nDR+//3RWuMXFMnywijRGtvbtZN1uxDif bzT53onodfVo3bh96TzkG5ykVlfJ+EU1aXpJcVamxOYxH4Ic/8BEDiqFzCSxUQ+0BNAaktuSxFu yZuVyW/Ik+B6H47WWlMmBGuFz/BgWP+ X-Received: by 2002:adf:f78b:0:b0:460:1957:1b33 with SMTP id ffacd0b85a97d-460304ec1b8mr16508979f8f.3.1780908470724; Mon, 08 Jun 2026 01:47:50 -0700 (PDT) Received: from bdtpg (ec2-15-237-197-144.eu-west-3.compute.amazonaws.com. [15.237.197.144]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f368e9fsm49398535f8f.37.2026.06.08.01.47.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jun 2026 01:47:50 -0700 (PDT) Date: Mon, 8 Jun 2026 08:47:48 +0000 From: Bertrand Drouvot To: "Hayato Kuroda (Fujitsu)" Cc: Alexander Lakhin , "xunengzhou@gmail.com" , pgsql-hackers Subject: Re: t/035_standby_logical_decoding.pl might fail on attempt to read wrong timeline Message-ID: References: <7daef094-abf3-4672-bc23-3df4763b16a3@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="HitlKQoyB8givWgr" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --HitlKQoyB8givWgr Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, On Mon, Jun 08, 2026 at 04:25:45AM +0000, Hayato Kuroda (Fujitsu) wrote: > Hi Alexander, Bertrand, Xuneng, > > Thanks for seeing the failure. Our team also recognized but could not find the reason. > > > Yeah, it looks like there is a race condition here. I think we should check if > > the insertion timeline has already been set (like the walsummarizer is doing). > > IIUC, the issue can happen if the walsender must read the WAL record generated > after the promotion but the timeline could not be updated. > > However, I think logical_read_xlog_page() is called after the new WAL records > are generated, i.e., am_cascading_walsender has already been false at that time. > So not sure where is the race? I ended up with this conclusion: During promotion, there is a window where RecoveryInProgress() still returns true but old timeline WAL segments have already been removed or recycled by RemoveNonParentXlogFiles() in CleanupAfterArchiveRecovery(). This is because, in StartupXLOG(), WAL segments are cleaned up before SharedRecoveryState transitions to RECOVERY_STATE_DONE. If a walsender performing logical decoding calls logical_read_xlog_page() during this window, it would get the old timeline from GetXLogReplayRecPtr(), then attempt to open a WAL segment on that old timeline which no longer exists. Attached: 0001: To fix this race Fix by checking GetWALInsertionTimeLineIfSet() when RecoveryInProgress() returns true. If InsertTimeLineID is already set (non-zero), the new timeline is established and we use it directly, avoiding attempts to read from segments that may have been removed. 0002: Adding a test in 035_standby_logical_decoding.pl It makes use of a new injection point "promotion-after-wal-segment-cleanup" in StartupXLOG(), right after CleanupAfterArchiveRecovery() removes old timeline WAL segments but before SharedRecoveryState is set to RECOVERY_STATE_DONE. The test fails without the fix in 0001 so it also somehow proves that the diagnostic is right. 0003: Apply the same timeline fix to read_local_xlog_page_guts() Indeed, it could hit the same race as mentioned by Xuneng-San. 0004: Add a test for 0003 Remark: As far as the backpatching down to 16, it looks like 0001 to 0004 could be backpatched as they are down to 17. For 16, we may want to also introduce GetWALInsertionTimeLineIfSet(). I can have a closer look for the backpatch once we agree on how to fix those races on master. Regards, -- Bertrand Drouvot PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com --HitlKQoyB8givWgr Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v1-0001-Fix-race-condition-in-logical-decoding-timeline-s.patch"