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 1vj0q4-003kGc-0P for pgsql-hackers@arkaria.postgresql.org; Thu, 22 Jan 2026 19:59:32 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vj0q2-00EY7C-10 for pgsql-hackers@arkaria.postgresql.org; Thu, 22 Jan 2026 19:59:30 +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 1vj0q1-00EY74-29 for pgsql-hackers@lists.postgresql.org; Thu, 22 Jan 2026 19:59:30 +0000 Received: from fout-a2-smtp.messagingengine.com ([103.168.172.145]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vj0pz-001p5y-0k for pgsql-hackers@lists.postgresql.org; Thu, 22 Jan 2026 19:59:29 +0000 Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailfout.phl.internal (Postfix) with ESMTP id 485EEEC0847; Thu, 22 Jan 2026 14:59:27 -0500 (EST) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-06.internal (MEProxy); Thu, 22 Jan 2026 14:59:27 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kurilemu.de; h= cc:cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to; s=fm1; t=1769111967; x= 1769198367; bh=dn6HORwvgW1MV7ufj1rrBAfjH9uusw8mLa4r8Qagu1Y=; b=U r/LXbAbhCGWVNufgmpdTcOkKYokUwrLLtCAvc3qg12JKKUjNQ60P6ip3AJToLlTh RVusPf10GA56i/FOOFcmo8Yav/P8l0OariJEFGdmZgu9kfFDr5d0Wty8UVCq6r+F z4friX51GQLqFQEPOJzDlrFgWlhaSZ0fZJi8awa1WnF99vApbaN2VZ0wCjOa2xJn 8qwCOSN0NthUo/nUJUSH8J83ei6Pa102LFmtIRTVEK4PysXFwMOeIDs9b+WWdN1o QHaePvOp2CfLmPIv/f2/7OsiWuQH9KHO2l7bM2d0817nhJx3N4ZhAGIb4MQc43Kz aF3gvMgOAXxhm++tpn/AA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm2; t=1769111967; x=1769198367; bh=d n6HORwvgW1MV7ufj1rrBAfjH9uusw8mLa4r8Qagu1Y=; b=eML1DSHU4JQTBnZgC jjbicLOfr+vTgTKZIsNv9oDfWdqcaQMfaMerbJ5W1Y5NCs9rJp8lZvpwc/nb1QmW 4JcDE3SS2GJRah6bFGOgF59yFc1f94zL9Z1j1TbF3+9W53WXUmL5mtJiXBObt+y8 h71sw2gTw1KjSBj7UW8xeNgOS1+C6r6N6qjdJFa6YQ82UInAp1X0TK5fPoO7vnck tiVOudv+7hd9FGqf/0/EKBeJ+DuH/KIqThnhMQ+c4jC3EgmrE+Mz/pUuKHKWitzC 0sgyUJCmCrVmXBC5J55be/wFVK3ADvr2dnOcHPL+Q3WDPWsAgY+RBNQUvvUry3SO Fn1xg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddugeejtdeiucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepfffhvfevuffkgggtugfgjgesthekredttddtjeenucfhrhhomheplmhlvhgrrhho ucfjvghrrhgvrhgruceorghlvhhhvghrrhgvsehkuhhrihhlvghmuhdruggvqeenucggtf frrghtthgvrhhnpeefjedvueeihffhudfhhfejgefgteehledtiedtteevjeduudffheev keevieelteenucffohhmrghinheptgihsggvrhhtvggtqdhpohhsthhgrhgvshhqlhdrtg homhdpvghnthgvrhhprhhishgvuggsrdgtohhmnecuvehluhhsthgvrhfuihiivgeptden ucfrrghrrghmpehmrghilhhfrhhomheprghlvhhhvghrrhgvsehkuhhrihhlvghmuhdrug gvpdhnsggprhgtphhtthhopedvpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopegr hhestgihsggvrhhtvggtrdgrthdprhgtphhtthhopehpghhsqhhlqdhhrggtkhgvrhhsse hlihhsthhsrdhpohhsthhgrhgvshhqlhdrohhrgh X-ME-Proxy: Feedback-ID: ie3de48e3:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 22 Jan 2026 14:59:26 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kurilemu.de; s=schmee; t=1769111961; bh=PavEanBOPdAbP+tMEIstRF05Od0FEbbAlbh4kd5XwFM=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=mxZ9tDwAE0uY75CbUQNXqnr8K3H1maQ49N2zmJSjOjYTdaAzGDGwcEBK37Uh2yMns eY53OPQtziYPQMKLjq6bZ3OrjDaCITg8cMO2mz0zfyzIzHqE8ekfSScmjXUM+vG8kU IkOeYDj/qNPpmfuiTUH9hHCt2F9P8FQTUmLCDmTev8j5SkxMfjDNNsV+dShI9Rir4u FTz+P+G8GYOA1iu5Vn8U5opDIFxO8nB6lr7Jigc0VGSzWZaTwQHlNLgOi03F7meHkn Jb++Z1ULDPurtn6FKx5Jy45JpWj4i795O15+gLgyz05JouQKpzJPUl5TyQ/vHssRMc FOAoz3QoxR60g== Received: by schmee.kurilemu.internal (Postfix, from userid 1000) id B039964; Thu, 22 Jan 2026 20:59:21 +0100 (CET) Date: Thu, 22 Jan 2026 20:59:21 +0100 From: =?utf-8?Q?=C3=81lvaro?= Herrera To: Antonin Houska Cc: pgsql-hackers@lists.postgresql.org Subject: Re: Race conditions in logical decoding Message-ID: <202601221950.c5lwdnye3idv@alvherre.pgsql> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <62335.1768897833@localhost> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 2026-Jan-20, Antonin Houska wrote: > Antonin Houska wrote: > > > I'm not sure yet how to fix the problem. I tried to call XactLockTableWait() > > from SnapBuildAddCommittedTxn() (like it happens in SnapBuildWaitSnapshot()), > > but it made at least one regression test (subscription/t/010_truncate.pl) > > stuck - probably a deadlock. I can spend more time on it, but maybe someone > > can come up with a good idea sooner than me. > > Attached here is what I consider a possible fix - simply wait for the CLOG > update before building a new snapshot. > > Unfortunately I have no idea right now how to test it using the isolation > tester. With the fix, the additional waiting makes the current test > block. (And if a step is added that unblock the session, it will not reliably > catch failure to wait.) > > -- > Antonin Houska > Web: https://www.cybertec-postgresql.com > > @@ -400,6 +400,47 @@ SnapBuildBuildSnapshot(SnapBuild *builder) > snapshot->xmin = builder->xmin; > snapshot->xmax = builder->xmax; > > + /* > + * Although it's very unlikely, it's possible that a commit WAL record was > + * decoded but CLOG is not aware of the commit yet. Should the CLOG update > + * be delayed even more, visibility checks that use this snapshot could > + * work incorrectly. Therefore we check the CLOG status here. > + */ > + while (true) > + { > + bool found = false; > + > + for (int i = 0; i < builder->committed.xcnt; i++) > + { > + /* > + * XXX Is it worth remembering the XIDs that appear to be > + * committed per CLOG and skipping them in the next iteration of > + * the outer loop? Not sure it's worth the effort - a single > + * iteration is enough in most cases. > + */ > + if (unlikely(!TransactionIdDidCommit(builder->committed.xip[i]))) > + { > + found = true; > + > + /* > + * Wait a bit before going to the next iteration of the outer > + * loop. The race conditions we address here is pretty rare, > + * so we shouldn't need to wait too long. > + */ > + (void) WaitLatch(MyLatch, > + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, > + 10L, > + WAIT_EVENT_SNAPBUILD_CLOG); > + ResetLatch(MyLatch); > + > + break; > + } > + } > + > + if (!found) > + break; > + } I think this algorithm is strange -- if you do have to wait more than once for one transaction, it would lead to doing the TransactionIdDidCommit again times for _all_ transactions by starting the inner loop from scratch, which sounds really wasteful. Why not nest the for() loops the other way around? Something like this perhaps, for (int i = 0; i < builder->committed.xcnt; i++) { for (;;) { if (TransactionIdDidCommit(builder->committed.xip[i])) break; else { (void) WaitLatch(MyLatch, WL_LATCH_SET, WL_TIMEOUT, WL_EXIT_ON_PM_DEATH, 10L, WAIT_EVENT_SNAPBUILD_CLOG); ResetLatch(MyLatch); } CHECK_FOR_INTERRUPTS(); } } This way you wait repeatedly for one transaction until it is marked committed; and once it does, you don't test it again. I also wondered if it would make sense to get rid of the memcpy, given that we're doing so much work per xid anyway it won't make any visible difference (I believe), and do the copy per XID there, like if (TransactionIdDidCommit(builder->committed.xip[i])) { snapshot->xip[i] = builder->committed.xip[i]; break; } else ... -- Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/ "Sallah, I said NO camels! That's FIVE camels; can't you count?" (Indiana Jones)