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 1vNyQp-003r11-1x for pgsql-general@arkaria.postgresql.org; Tue, 25 Nov 2025 19:10:31 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vNyQn-00AxLb-0J for pgsql-general@arkaria.postgresql.org; Tue, 25 Nov 2025 19:10:29 +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.96) (envelope-from ) id 1vNyQm-00AxLS-2I for pgsql-general@lists.postgresql.org; Tue, 25 Nov 2025 19:10:29 +0000 Received: from mail-vs1-xe2a.google.com ([2607:f8b0:4864:20::e2a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vNyQk-001TRR-3C for pgsql-general@postgresql.org; Tue, 25 Nov 2025 19:10:28 +0000 Received: by mail-vs1-xe2a.google.com with SMTP id ada2fe7eead31-5de78e66cb1so282228137.2 for ; Tue, 25 Nov 2025 11:10:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1764097824; x=1764702624; darn=postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=nC14TiKXmutlr/HAb+CSK2rllYeDmdg9lSugpvXQuSU=; b=IGSAf5M8lhH9BheELyBYPu355urqMfTCbP9tDFhy5bDEpNE40ilGPSvijGwnjD/Iyp yY2pakK+8Uu4TOrO3TaGOJkxvyvpGYI57NeD7hpQq3BT/qJ/IHfxnudauRs6AxYBFgKV Dzsvl/cOhzWkHxsQelAFl1ppXCcp/PKRQhQ0jnjuQeECGSdDTWv4M4T8NEaqew+tzMMu grhapxv1pH6g/KA9QMxLsv4WsA5y0OQbD+97mzeGmEvZPCur4fog1Eq6iSVGupCgg002 2mYFyWsmbvpUy3SDG6mbUwJ66c3gwbb9LAYPi9Py8Ojk6u9tMKo/QaQiQkQeZzcqtL2a 0XvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764097824; x=1764702624; h=to:subject:message-id:date:from:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nC14TiKXmutlr/HAb+CSK2rllYeDmdg9lSugpvXQuSU=; b=auGx/IKSD7HwFdaghmNfAOvL7nl1pCcOOGQfv8LTzQYlt1a40YVR1j4mmr7widgjgf 0svgYmM5FTAIxysSXAIHNRcjNmR+gti3Cy+JnHAU44xMauJggkLNSwhNpYPzvoTgxfH3 bA/ljMiUrdOCMr22uIARqlCwQI0MSv43NqjQaOTzgL1co5dRg8MBoYe4zkGYE7G98VwL OzBhNogZUdGkjIFcBvpLcP3PW/5Nx1pqMLgbbrhR9MME7FSZDB1xZegwq6+eG2UccjT6 KzXT8gIrwuad8E7HdVRj4iTx8VWLWXdUwMsqvP2HKECBIXQshxefJRDSKwmO7r48osgR RpBA== X-Gm-Message-State: AOJu0YxMV+iml6ceTDJ1YaK7T1+7pZaslH/DKb/8jHFWANyB7T8WXQRq APXYccbmqN+rEX631t4WGz0A8TNQCpgVumMLXt3iu7aQJcjojv34F4Bpbu3VBINAG2FwgFssttT jFVnekMVw7DOaM44U+ni/h6gIYfvgMlwUoege X-Gm-Gg: ASbGncuU3H2jL8JgyL52lKgBAkenctFF58jPG0BlREzZQ9Y+LOgwvU9xpv5SCtYCkpa c2aHukF4hEaXf+liXseFpX3vH3y/6ODOBqGjaSaqCsuAYgIK81PHVu6i378S8Sh8UjOFWutC0vE KAzTvvPeMkVGgPiZgpNizHVSiJ/BCk/lBgl08RVqtQK4zNuQvDRkh8n293b5BEMvOFCDr/MtcRH aCZ5J+hp8CsOTN0YhNnEBZfXgxw/q1+Yct7KsczZ1rnCL6hAhFJpmUJbi1jNKpZ7m0LDq1p X-Google-Smtp-Source: AGHT+IEMd1d+l80HXS3K2myaMD0rBNAqQoZHWA2i3Cx/6iu+JvdMkW83rh7yiNdExkKM2OTMWUJdQOB4d3fodt9SBVg= X-Received: by 2002:a05:6102:dd2:b0:5db:25d3:28b4 with SMTP id ada2fe7eead31-5e1de3c40d0mr3281956137.5.1764097824330; Tue, 25 Nov 2025 11:10:24 -0800 (PST) MIME-Version: 1.0 From: Pavel Suderevsky Date: Tue, 25 Nov 2025 19:10:13 +0000 X-Gm-Features: AWmQ_blj5IcxDWekatnjxdEcdCXCmjkalR9cdz9fCTNFVaoCpRT1wpkrapbfg4U Message-ID: Subject: Commit LSN after Redo Done At LSN applied during recovery To: Postgres General Content-Type: multipart/alternative; boundary="0000000000002b1631064470083f" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000002b1631064470083f Content-Type: text/plain; charset="UTF-8" Hi all, Migrating a large database from 13 to 17 using a logical replication. Postgres - SaaS (GCP). Subscriber - 17.7. Publisher - 13.22. Plan: 1. create publication [pub] 2. create logical replication slot [pub] 3. copy instance [pub -> sub] 4. extract the LSN of the "redo done" point from the log [sub] 5. upgrade the copied instance to version 17 [sub] 6. adjust the LSN of the replication slot (pg_replication_slot_advance) [pub] 7. create subscription [sub] There is a constant load on the Primary with inserts and updates. The problem is: After creating a Subscription, a transaction that had already been committed on the Subscriber during the restore, is applied again. As a result, getting PK violation on INSERT. If you compare LSNs, "redo done at" point is indeed before the COMMIT of the transaction. But the conflicting row already exists on the Subscriber. Meanwhile, if move *confirmed_flush_lsn* of the replication slot by 1 byte, replication goes further without issues. But again, formally this LSN is still before the COMMIT. Example: redo done at - *276/8FEE68E0*, which is before the last DML ( *276/8FEE6458*) and COMMIT (*276/8FEE6910*). Records around this COMMIT (*xid 13347755*) ordered by lsn: | lsn | older_than_redo | xid | operator | cmt | | 276/8FEE4BB0 | false | 13347755 | INSERT | | | 276/8FEE5FC0 | false | 13347755 | UPDATE | | | 276/8FEE6458 | false | 13347755 | UPDATE | | | 276/8FEE6910 | true | 13347755 | COMMIT | COMMIT 13347755 | | 276/8FEE6910 | true | 13347756 | BEGIN | BEGIN 13347756 | | 276/8FEE6910 | true | 13347756 | UPDATE | | | 276/8FEE6980 | true | 13347756 | INSERT | | (the second column is just "*lsn > '276/8FEE68E0'::pg_lsn*") And advanced by 1 byte slot position is "*276/8FEE68E1*"*.* Please help to understand what is going on: *1.* Why after copying the instance a transaction that has COMMIT LSN lower than *"Redo Done At*" point LSN appears to be already committed? *2.* Why shifting the *confirmed_flush_lsn* of the replication slot by *1 byte* fixes the problem? *3.* From the consistency perspective, how safe is this trick with advancing the replication slot position by 1 byte? Thank you, -- Pavel Suderevsky --0000000000002b1631064470083f Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi all,

Migrating a large database from 13 to = 17 using a logical replication. Postgres - SaaS (GCP).
Subscriber - 17.7= .
Publisher - 13.22.

Plan:
1. create publication [pub]
2. c= reate logical replication slot [pub]
3. copy instance [pub -> sub]4. extract the LSN of the "redo done" point from the log [sub]5. upgrade the copied instance to version 17 [sub]
6. adjust the LSN o= f the replication slot (pg_replication_slot_advance) [pub]
7. create sub= scription [sub]

There is a constant load on the Primary with inserts= and updates.

The problem is:
After creating a Subscription, a tr= ansaction that had already been committed on the Subscriber during the rest= ore, is applied again. As a result, getting PK violation on INSERT.

= If you compare LSNs, "redo done at" point is indeed before the CO= MMIT of the transaction. But the conflicting row already exists on the Subs= criber.
Meanwhile, if move confirmed_flush_lsn of the replication= slot by 1 byte, replication goes further without issues. But again, formal= ly this LSN is still before the COMMIT.

Example: redo done at - 2= 76/8FEE68E0, which is before the last DML (276/8FEE6458) and COM= MIT (276/8FEE6910).
Records around this COMMIT (xid 13347755) ordered by lsn:

| lsn | older_than_redo | xid | operator | cmt |=
| 276/8FEE4BB0 | false | 13347755 | INSERT | |
| 276/8FEE5FC0 | fals= e | 13347755 | UPDATE | |
| 276/8FEE6458 | false | 13347755 | UPDATE | |=
| 276/8FEE6910 | true | 13347755 | COMMIT | COMMIT 13347755 |
| 276/= 8FEE6910 | true | 13347756 | BEGIN | BEGIN 13347756 |
| 276/8FEE6910 | t= rue | 13347756 | UPDATE | |
| 276/8FEE6980 | true | 13347756 | INSERT | = |

(the second column is just "lsn > '276/8FEE68E0'= ;::pg_lsn")
And advanced by 1 byte slot position is "= 276/8FEE68E1".

Please help to understand= what is going on:
1. Why after copying the instance a transactio= n that has COMMIT LSN lower than "Redo Done At" point LSN = appears to be already committed?
2. Why shifting=C2=A0the conf= irmed_flush_lsn of the replication slot by 1 byte fixes the prob= lem?
3. From the consistency perspective, how safe is this trick = with advancing the replication slot position by 1 byte?

Thank you,--
Pavel Suderevsky
--0000000000002b1631064470083f--