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.98.2) (envelope-from ) id 1x77ci-000000006lI-3Bzp for pgsql-hackers@arkaria.postgresql.org; Thu, 17 Sep 2026 08:37:41 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1x77ci-00000003403-0DHy for pgsql-hackers@arkaria.postgresql.org; Thu, 17 Sep 2026 08:37:40 +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.98.2) (envelope-from ) id 1x77ch-000000033zu-3B3n for pgsql-hackers@lists.postgresql.org; Thu, 17 Sep 2026 08:37:39 +0000 Received: from mail-wm2-x10.google.com ([2a00:1450:4864:31::10]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1x77cf-000000006Hq-3tjL for pgsql-hackers@lists.postgresql.org; Thu, 17 Sep 2026 08:37:38 +0000 Received: by mail-wm2-x10.google.com with SMTP id 5b1f17b1804b1-49b912d37b6so2580695e9.0 for ; Thu, 17 Sep 2026 01:37:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec.at; s=google; t=1789634256; x=1790239056; darn=lists.postgresql.org; h=message-id:date:content-id: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=MbP/FelcJ+KEkZof0be/lvH7WCUxKG4jHWykXkNHxNQ=; b=PpEkxeJMNJ5zlcUT3a8Xzsp3blKcpHWeRGGI2pnofJWPdp+rhgmPOMp31eo1lJsy6X /tP/KCtBaKiWosGLa0f/IyASWIC7c3lPhWBnvY+J9DfdSHdNBAVMGK5je7AdooP6b1lk MvGa9FeeoglTUxP9Ui10PakDlmSTpxiDgWMphzFfM21MFLHpLq8BboenGzgIsmMC190x cCdBE3BWAHQ63bj6xLI+HI+xfHsieC/Dn1/IPoWk7Oh54Gh10tBc0RGf9Dd+44x5mDpZ Y6rQmq4Xyzmsmt1wXC9oJaRd7FVyZroBUTItS3uwhTFPQCpC1ZQV3HhBUxAQw//dxOeC XKNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789634256; x=1790239056; h=message-id:date:content-id: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=MbP/FelcJ+KEkZof0be/lvH7WCUxKG4jHWykXkNHxNQ=; b=AaKk3FNCAeuhpYkYo7z+eBVtcOc4lo1BZ70zklKOXdYNVGx0MaTSWqqJ2DciJmrdT8 iq9F6EyTBCI+XV8StYLXYK2Z53i1E/yGW9oQt3qa9Q/YcYgeWs+t1Q3vcST9K5KZKxe/ 1GaPwc+Ez080RNFw46dbuwxA7KsvpgblqldSc4FL4cYI2gzP8XixGnfcZDSt3LbgxTfm 88GJKL0Do61sCaQQtL59cv890HKKzrvgSY20L5WVYhdXdny/92oWtlQ9Kks49UjJWFHn PPnO2iK4DxVTZ2Y2Ay4ZeBtE56bgVIfO0DcdKgRPJafXfVZhXUJNtpPBF4HR9KmUz0Fy J2dw== X-Forwarded-Encrypted: i=1; AKwUvBye6JjwvYVu64jPcISzeWrukzNsFAAbeib4Lf0OquqUV1CyHqMkkHwVwQhi48tfkd//eC7vqZCWik5mr1xO@lists.postgresql.org X-Gm-Message-State: AFuF++myYmEHMGbs8a+Rk9ScJzMKm1tpYa/OSHLJxNiTcMYDm3Uy9xwH KNn7Te/pxRY7PZeAimfAYVYXMCM6BEDkMLIl3Uqw1Flyu1FE3yllfrXlGikmcm6Aosg= X-Gm-Gg: AYBFou0PZVQgAdsLkEIk9R3+DgJXR5PgWUHgeQAx3fyDIsSLQxAhP8vmTUAgI1OgUxB Qj9M/8ogMOM1L2kbhrjWSscW4PKs/Vi/or6uxraai6HYD+b58L7/3Oe4p+xb5cIgHBKGv/ugVe8 CpVhslpmIed1bsXu97JRFOccil2KOI4XaiaMOgPCp9xiDFdCFqxA7PJJ8G8jefEYJN6vUIj49wm 0Tdde1NiT9K8FnCWKNpuDHqixR2YwMRTVIblSh/bNLHyRPst6qhnOfkGdV6PQXSUy4nGBgmqoEE yqNyLsul/lgPDC0YdrTo1dO/uiEgQxQ+G0Gbtn/XfaBhZ8Gy/3pEYbfx38p83cGvI1tx4IQpAYf chEqlo8hvxbQaIqHtOt/24W9Ibw4CZOCmwKSsyh6HV/oLf+NBjkqodXMpPNs/Cmngo67V8rkA9u vdrTAEmbr0DhMjM6jFReXwy2lbVZDjoRXiyEuSjeRXbt5xvrscX5k7/FXs8nrwntolGLJs55ZC2 IzN7zTYV3RC X-Received: by 2002:a05:600c:3b0c:b0:49f:bc28:e8b1 with SMTP id 5b1f17b1804b1-49fbc28e978mr88028305e9.14.1789634256204; Thu, 17 Sep 2026 01:37:36 -0700 (PDT) Received: from localhost (109-81-170-190.rct.o2.cz. [109.81.170.190]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49fbd1d0d0bsm56083225e9.1.2026.09.17.01.37.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Sep 2026 01:37:35 -0700 (PDT) From: Antonin Houska To: Rui Zhao cc: alvherre@kurilemu.de, Andres Freund , pgsql-hackers@lists.postgresql.org, Mihail Nikalayeu Subject: Re: Race conditions in logical decoding In-reply-to: References: <202603201543.t6gxppyyk66p@alvherre.pgsql> Comments: In-reply-to Rui Zhao message dated "Sun, 13 Sep 2026 01:35:01 +0800." X-Mailer: MH-E 8.6+git; nmh 1.8; GNU Emacs 28.3 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <8246.1789634255.1@localhost> Date: Thu, 17 Sep 2026 10:37:35 +0200 Message-ID: <8247.1789634255@localhost> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Rui Zhao wrote: > 1. The wait belongs in SnapBuildInitialSnapshot() and nowhere else: > SnapBuildBuildSnapshot() does not need it, and in > SnapBuildInitialSnapshot() it can be a wait on the transaction lock. > 0001 does that. > > SnapBuildInitialSnapshot() is the only place where the builder's list of > committed transactions turns into a regular MVCC snapshot, and it is > HeapTupleSatisfiesMVCC() on that snapshot that asks CLOG about a > transaction between xmin and xmax. The historic snapshots that > SnapBuildBuildSnapshot() hands to the reorder buffer never do: > HeapTupleSatisfiesHistoricMVCC() decides the range [xmin, xmax) by the > xip array alone and consults CLOG only below xmin, and builder->xmin is > always the oldestRunningXid of an xl_running_xacts record, so a > transaction below it had left the procarray, and so updated CLOG, before > that record was written. I initially thought that it's silly to rely on such tricky details, but not consulting CLOG appears to be a design choice - see the header comment in snapbuild.c. * ........ Also, our snapshots need to be different in comparison to normal * MVCC ones because in contrast to those we cannot fully rely on the clog and * pg_subtrans for information about committed transactions because they might * commit in the future from the POV of the WAL entry we're currently * decoding. ... And regarding snapshot's xmin, I agree that it's controlled by xl_running_xacts WAL record and that it does not advance until the transaction has been recorded in CLOG. Thus I'm not opposed to the idea that it's enough to add the check to SnapBuildInitialSnapshot(). > + if (!RecoveryInProgress()) > + { > + RunningTransactions running; > + int nrunning; > + > + running = GetRunningTransactionData(); > + nrunning = running->xcnt + running->subxcnt; > + LWLockRelease(ProcArrayLock); > + LWLockRelease(XidGenLock); > + > + for (int i = 0; i < nrunning; i++) > + { > + TransactionId running_xid = running->xids[i]; > + > + if (bsearch(&running_xid, snap->xip, snap->xcnt, > + sizeof(TransactionId), xidComparator) != NULL) > + XactLockTableWait(running_xid, NULL, NULL, XLTW_None); > + } > + } I don't understand why you check all transactions in procarray, instead of only those in snap->xip. -- Antonin Houska Web: https://www.cybertec-postgresql.com