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 1wyutq-003ho3-3C for pgsql-hackers@arkaria.postgresql.org; Tue, 25 Aug 2026 17:25:27 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wyuto-0095ot-1C for pgsql-hackers@arkaria.postgresql.org; Tue, 25 Aug 2026 17:25:24 +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 1wyuto-0095ok-08 for pgsql-hackers@lists.postgresql.org; Tue, 25 Aug 2026 17:25:24 +0000 Received: from mail-ej1-x634.google.com ([2a00:1450:4864:20::634]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wyutl-00000002NTP-1wec for pgsql-hackers@lists.postgresql.org; Tue, 25 Aug 2026 17:25:22 +0000 Received: by mail-ej1-x634.google.com with SMTP id a640c23a62f3a-c167aa9500dso774226566b.3 for ; Tue, 25 Aug 2026 10:25:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec.at; s=google; t=1787678718; x=1788283518; darn=lists.postgresql.org; h=message-id:date:content-transfer-encoding:content-type:mime-version :comments:references:in-reply-to:subject:cc:to:from:from:to:cc :subject:date:message-id:reply-to:content-type; bh=0jxX+OyuYG/vfd2zRXd/ZWKABZP09o2pduJCZCPO02Y=; b=mrLACPIW556ltlmnM0g7KjqwSSP5Dk1rfwTfjeE61Jw7c8inm3rtLUAGUjDHRNIw+t t5KeQFpMdMkNu790sqiFuqpUr5+cZGESVzhJmzgsZrGxEudtxHLMrM4S7eo5kwQH05I1 37SnSsnmmhEb3ELOqs9cK0AqrgD9j1UFmDAGHRMy3fE9SOznMzgUnT21TYPiNqXbkqop incS/KZ1s8YPTbhKaKtaXlhXxY9MTdAgQnPLNjbjykq2GiVItnbbC1trGsNt8lQfbjU0 Xpzzq49As10I5ADtP6na61a/4X2oNf9Gr5T6oXChnK3tF3YDB2BRoOcXQeUH9UMLKvHC JsxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787678718; x=1788283518; h=message-id:date:content-transfer-encoding:content-type:mime-version :comments:references:in-reply-to:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=0jxX+OyuYG/vfd2zRXd/ZWKABZP09o2pduJCZCPO02Y=; b=XqCWEmWthXEOsrCO7RqQN8Yf+N7xh+SqJajNulbQI7zH8eBTCLa7jX6RosWP4+4K36 L/ihqUq0qFLqBy5cRicli6ieKT+s+wE7w3xZrWfrOFDR+IxGumeQm1i1KiE3yCRZvNp2 sT+TfYKeIQB96R3X5u3MXzsYO8ExzCelqfFFxxCO+MN5/StS3AQKTlQ+jQibvkoaGUSR FPVVofkg9eEmJ6W+PKitZhapHDNckPUZ08g090yepbo9j+QzZc4UkCTBa/btbrAVCOhM gZ0z2Tf2+VUr6p25g7k8hxgrsKLs6acQMYwaG7X2AEiCFsI5mimbtFf+MsKxhovRqR3n rZwg== X-Forwarded-Encrypted: i=1; AHgh+Rrs3m8I7bt5n2aJ6zkXhoKY2SlMpXeIDNzUptWg9yRaJBnLZXAGb1TKvsM+9zu9tLj5FH6G13o3C3tGF05S@lists.postgresql.org X-Gm-Message-State: AFuF++lOB2BojccvnXZeQ6uohc7zcepHPBn28V0qToB+fJTrFBcbxTiV BlGVEsRr6hI3caC+kjdSXhYpBWXJuvLitdwLNqYpwqLXW2kUsRHKDFVHkZ4Mm7QLF3QwRvspapM vjuTpl+A= X-Gm-Gg: AR+sD13/AH61jRofixo4BLR756bVKTzw6M2qocf49HEeS/8Dv6yMATfi3SwpHfKyrUs 2tiAk4wVyC5Axhpw29d78zrJT0w8FXg2r7kt/Ve74HQGYtC/yxx9ewZZ1g6g2LZsTq+BHM04n3s RB3pqGWXsK7a76fp2ItiZOu3w7KEihMXwOiHPfqt17X4wDym6rqkrbYI3xOwweD3aywnHXRJf/r nPheJqHgyJsV2lRcZUvwjjdS23cy/eBnpvIwqtbc5gXmhCJiPMl5yQEvRuNC4/+DVg21Absgus/ B/lRABucQaX+lmoP108ImQOR6dm3MeXvzctmO4fv38kcVxyErmOPT5fy1C/px5Rt7kzJ7i5oWqH n5dt6a2CKShOFsC4kuNZA9xTr//ZWPuUG7Pj/UlhRYfA8ZejP7zL3ztqrSzEU0p1Lxl+Q+6SYQf y7tBZ3YKLE3TkQpujCTuaL96LSnl7G9NYZjFWoSVmdCRxn0vKet077+7HYutTKOkHgpyC/TEkNQ JURc3bFDqOT X-Received: by 2002:a17:907:d09:b0:c19:80cf:4c75 with SMTP id a640c23a62f3a-c250bc2cc21mr26389966b.20.1787678718024; Tue, 25 Aug 2026 10:25:18 -0700 (PDT) Received: from localhost (109-81-170-190.rct.o2.cz. [109.81.170.190]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c250a704e55sm52991066b.21.2026.08.25.10.25.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 Aug 2026 10:25:17 -0700 (PDT) From: Antonin Houska To: alvherre@kurilemu.de cc: Andres Freund , pgsql-hackers@lists.postgresql.org, Mihail Nikalayeu Subject: Re: Race conditions in logical decoding In-reply-to: References: Comments: In-reply-to =?us-ascii?Q?=3D=3Futf-8=3FQ=3F=3DC3=3D81lvaro=3F=3D?= Herrera message dated "Fri, 21 Aug 2026 20:16:02 +0200." X-Mailer: MH-E 8.6+git; nmh 1.8; GNU Emacs 28.3 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Date: Tue, 25 Aug 2026 19:25:17 +0200 Message-ID: <36316.1787678717@localhost> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk =C3=81lvaro Herrera wrote: > On 2026-Mar-20, =C3=81lvaro Herrera wrote: >=20 > > Failing other ideas, I think we should just go with 0001. We'd need mo= re > > commentary on why is TransactionIdDidCommit() OK, when we haven't > > scanned PGPROC for that xid, though. >=20 > I spent some more time stepping through the motions here. In the test I > saw, the problem is caused by the check for latestCompletedXid. The > transaction we saw as committed in WAL has not yet been removed from > ProcArray, which is what updates latestCompletedXid. So that makes > TransactionIdIsInProgress() report that yes, the transaction is in > progress, therefore we continue to wait in a loop forever, at least in > synchronous replication. > To recap: the problem was that returned a snapshot with a transaction > recorded as committed, but which was not yet marked as such in CLOG, so > when we did things like HeapTupleSatisfiesMVCC() with the snapshot so > obtained, it would run TransactionIdDidCommit(), get false from it, and > conclude that the transaction "must have aborted or crashed", therefore > marking the tuple as HEAP_XMIN_INVALID. So what we do here is ensure > that TransactionIdDidCommit() will return the correct value before > giving the snapshot back. >=20 >=20 > The other problem with this patch in the back of my mind was that we may > be doing TransactionIdDidCommit() potentially for a lot of transactions. > Instrumenting these code paths I saw that some tests in the suite would > call the transam.c routine several thousand times, and some XIDs would > repeat over and over. This may not sound like much, but we don't > actually know what happens in production systems; and every transam.c > call has the potential to do I/O to get the relevant CLOG page. And > because we do this snapshot building in places like > SnapBuildProcessChange(), it has the potential to do nasty. So I added > a quick and dirty process-local cache: the list of transactions we > tested on the previous cycle. We don't test nor wait for any > transaction that's on that list, since evidently we must have tested it > already and it cannot become uncommitted after that. All in all, we > test for each potentially in-progress transaction just once per backend. >=20 > So, what do you think of the attached? I appreciate it that you performed the tests. I considered the race conditi= on pretty rarely, however it does not imply anything about the cost of the checks: yes they can be quite frequent. I'm just thinking if the 'xids_already_tested' variable name is appropriate. Since you only add XIDs known to be committed, how about something like 'xids_known_committed'? Besides, that, it occurred to me that a sorted array might be appropriate instead of a list, so that bsearch() can be used, but I'm not sure about th= at. > (On second thought, it may be a good idea to plant some of my > explanation above in the new comment in SnapBuildBuildSnapshot. No time > for that right now though.) I think it's worth mentioning at least the synchronous replication problem = you mentioned above, so it's easier to understand why we cannot use TransactionIdIsInProgress(): --=20 Antonin Houska Web: https://www.cybertec-postgresql.com