Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qEvmo-0006mF-7c for pgsql-hackers@arkaria.postgresql.org; Thu, 29 Jun 2023 17:50:30 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1qEvmn-0003kd-4I for pgsql-hackers@arkaria.postgresql.org; Thu, 29 Jun 2023 17:50:29 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qEvmm-0003kU-LY for pgsql-hackers@lists.postgresql.org; Thu, 29 Jun 2023 17:50:28 +0000 Received: from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qEvmj-0018WV-Et for pgsql-hackers@postgresql.org; Thu, 29 Jun 2023 17:50:27 +0000 Received: by mail-wm1-x32b.google.com with SMTP id 5b1f17b1804b1-3fbc12181b6so5949175e9.2 for ; Thu, 29 Jun 2023 10:50:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=postgres.ai; s=google; t=1688061024; x=1690653024; h=to:subject:message-id:date:from:disposition-notification-to :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=+quXqF4U9pKvRrS1BgYYeUThJ7nhIM7YPP6fsAlZAcM=; b=Qbf5GvIa8zA+xm3q4d+umnSiv9717r5O0yK0JOYX2+33h1e16CTTLueqRU+PAU13m2 eRoN6mjxgBNbBcoisSE0i7nPfCzQ0v7sQmT0Hms035ZLdwbxx5AvhQkj5t7myIay8wqU sY4GPzg6pUF4IeqYo6x1Z5nvW0tDD/aJ9hEqJ9edZ8KmfcehziB6HrBSXP3y3YcVpHig w8u1++I8sc/ZbAXTToNM436p8OkUtK7wnHvQeMoWdmUtUmBegs2zOU3a0UGp7t8q3Mqo hYicUTJ902mAN/iLwfdeh+J/yODj4dq7cF8k7XvjdZKnFXIX5kZdjjbFLwVA8pxAVwRI 9pyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688061024; x=1690653024; h=to:subject:message-id:date:from:disposition-notification-to :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=+quXqF4U9pKvRrS1BgYYeUThJ7nhIM7YPP6fsAlZAcM=; b=dlS+3C41aBRWcTksKfBhuAuOQ1FVIheI19LAznLD3Lc7CvzO3b5h/Xs/RhInEkjuQu 9HGeDDXVZZDD9NpetGNInPvtkiWMivbx+k3CFXbyNgMZ67esj402YctCdLE3ridXBmzS GZHKGnK+f1xBkqc1r3qIm4Lx5MOe1igoZ7lEKIYse5jz+wytzyTST3Gi5BHiC+Fdch7k b74p2H9wn+sGnbDbPCovyqTAZRm8pbypWZa6+U0K/zArOBiPd6P6o88yfWLqkImR4HeJ aKcWHK0313ADmX11DrGd78a2WzuI39KuIJOLDBmFXJ6xNpRxAirBeE3iChR3lgEeupu8 SPTw== X-Gm-Message-State: ABy/qLZCeer7RCAmlrJeg7T0GucKR5rnqjXTFxvlR6RjaKAmcm+HZaSD e6PsHspdpeh0ChX5CkBoHE7HQ/F487pZbRIFF9iOsk6BOEfkU/u4qHA= X-Google-Smtp-Source: APBJJlE8Fg7/JnUWIH/XBDS/TnpIySF1pigbXz8Sifnf7qUwZYDS8d2cBSpjpa+G3OwdcI4A1kyH3CUDdWnIdL7vW54= X-Received: by 2002:adf:d4c3:0:b0:314:172b:aa26 with SMTP id w3-20020adfd4c3000000b00314172baa26mr178875wrk.62.1688061023447; Thu, 29 Jun 2023 10:50:23 -0700 (PDT) MIME-Version: 1.0 Disposition-Notification-To: nik@postgres.ai From: Nikolay Samokhvalov Date: Thu, 29 Jun 2023 10:50:12 -0700 Message-ID: Subject: pg_upgrade instructions involving "rsync --size-only" might lead to standby corruption? To: pgsql-hackers@postgresql.org Content-Type: multipart/alternative; boundary="000000000000a9898e05ff4855dc" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000a9898e05ff4855dc Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi! (posting this to -hackers rather than to -docs since it seems a deeper problem than just adjusting the docs) I recently observed a case with standby corruption after upgrading pg12 to pg14, which was presented in the form of XX001 errors on the new cluster's standby nodes. e.g.: ERROR: missing chunk number 0 for toast value 3228893903 in pg_toast_79504413 Comparing the content of the data directory and checking files with md5sum, I noticed that some files for some TOAST index have different content on new standby nodes compared to the new primary =E2=80=93 and interesting was= the fact all standbys had the same content. Just different compared to the primary. We used the "rsync --size-only" snippet from the docs https://www.postgresql.org/docs/current/pgupgrade.html to upgrade standbys. With "--size-only", 1 GiB files for tables and indexes obviously cannot be reliably synchronized. In our case, we perform additional steps involving logical replication, advancing primary to certain LSN position -- and during that, we keep standbys down. This explains the increased corruption risks. But I think these risks are present for those who just follow the steps in the docs as is, and probably some fixes or improvements are needed here. The main question: why do we consider "rsync --size-only" as reliable in the general case? May standby corruption happen if we use follow steps from https://www.postgresql.org/docs/current/pgupgrade.html? Considering several general situations: 1. For streaming replication: a. if we shut down the primary first, based on the code in walsender.c defining how shutdown even is handled, replicas should receive all the changes? b. if shut down standbys first (might be preferred if we run cluster under Patroni control, to avoid unnecessary failover), then some changes from the primary won't be received by standbys =E2=80=93 and we do have sta= ndby corruption risks 2. For replication based on WAL shipping, I don't think we can guarantee that all changes are propagated to standbys. The docs also have this: > 9. Prepare for standby server upgrades > If you are upgrading standby servers using methods outlined in section Step 11, verify that the old standby servers are caught up by running pg_controldata against the old primary and standby clusters. Verify that the =E2=80=9CLatest checkpoint location=E2=80=9D values match in all cluste= rs. (There will be a mismatch if old standby servers were shut down before the old primary or if the old standby servers are still running.) Also, make sure wal_level is not set to minimal in the postgresql.conf file on the new primary cluster. =E2=80=93 admitting that there might be mismatch. But if there is mismatch,= rsync --size-only is not going to help synchronize properly, right? I was thinking about how to improve here, some ideas: - "rsync --checksum" doesn't seem to be a good idea, it's, unfortunately, very, very slow, though it would be the most reliable approach (but since it's slow, I guess it's not worth even mentioning, crossing this out) - we could remove "--size-only" and rely on default rsync behavior =E2=80= =93 checking size and modification time; but how reliable would it be in general case? - make the step verifying =E2=80=9CLatest checkpoint location=E2=80=9D *aft= er* shutting down all nodes as mandatory, with instructions on how to avoid mismatch: e.g., shut down primary first, disabling automated failover software, if any, then run pg_controldata on standbys while they are running, and on primary while it's already shut down (probably, different instructions are needed for WAL shipping and streaming cases) - probably, we should always run "rsync --checksum" for pg_wal - I think, it's time to provide a snippet to run "rsync" in multiple threads. A lot of installations today have many vCPUs and fast SSDs, and running single-threaded rsync seems to be very slow (especially if we do need to move away from "--size-only"). If it makes sense, I could come up with some patch proposal for the docs - it's probably time to implement support for standby upgrade in pg_upgrade itself, finding some way to take care of standbys and moving away from the need to run rsync or to rebuild standby nodes? Although, this is just a raw idea without a proper proposal yet. Does this make sense or I'm missing something and the current docs describe a reliable process? (As I said, we have deviated from the process, to involve logical replication, so I'm not 100% sure I'm right suspecting the original procedure in having standby corruption risks.) Thanks, Nikolay Samokhvalov Founder, Postgres.ai --000000000000a9898e05ff4855dc Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi!

(posting this to -hacker= s rather than to -docs since it seems a deeper problem than just adjusting = the docs)

I recently observed a case with standby corru= ption after upgrading pg12 to pg14, which was presented in the form of XX00= 1 errors on the new cluster's standby nodes. e.g.:
=C2=A0 ERROR: mi= ssing chunk number 0 for toast value 3228893903 in pg_toast_79504413
Comparing the content of the data directory and checking files= with md5sum, I noticed that some files for some TOAST index have different= content on new standby nodes compared to the new primary =E2=80=93 and int= eresting was the fact all standbys had the same content. Just different com= pared to the primary.

We used the "rsync --si= ze-only" snippet from the docs https://www.postgresql.org/docs/current/pgupgra= de.html to upgrade standbys.

With "--size= -only", 1 GiB files for tables and indexes obviously cannot be reliabl= y synchronized. In our case, we perform additional steps involving logical = replication, advancing primary to certain LSN position -- and during that, = we keep standbys down. This explains the increased corruption risks. But I = think these risks are present for those who just follow the steps in the do= cs as is, and probably some fixes or improvements are needed here.

The main question: why do we consider "rsync --size-o= nly" as reliable in the general case? May standby corruption happen if= we use follow steps from https://www.postgresql.org/docs/current/pgupgrade.html?

1. For streaming replication:



<= div>- we could remove "--size-only" and rely on default rsync beh= avior =E2=80=93 checking size and modification time; but how reliable would= it be in general case?
- make the step verifying =E2=80=9CLatest= checkpoint location=E2=80=9D *after* shutting down all nodes as mandatory,= with instructions on how to avoid mismatch: e.g., shut down primary first,= disabling automated failover software, if any, then run pg_controldata on = standbys while they are running, and on primary while it's already shut= down (probably, different instructions are needed for WAL shipping and str= eaming cases)=C2=A0
- probably, we should always run "rsync = --checksum" for pg_wal=C2=A0
- I think, it's time to pro= vide a snippet to run "rsync" in multiple threads. A lot of insta= llations today have many vCPUs and fast SSDs, and running single-threaded r= sync seems to be very slow (especially if we do need to move away from &quo= t;--size-only"). If it makes sense, I could come up with some patch pr= oposal for the docs
-=C2=A0 it's probably time to implement s= upport for standby upgrade in pg_upgrade itself, finding some way to take c= are of standbys and moving away from the need to run rsync or to rebuild st= andby nodes? Although, this is just a raw idea without a proper proposal ye= t.

Does this make sense or I'm missing somethi= ng and the current docs describe a reliable process? (As I said, we have de= viated from the process, to involve logical replication, so I'm not 100= % sure I'm right suspecting the original procedure in having standby co= rruption risks.)

Thanks,
Nikolay SamokhvalovFounder, Postgres.ai
--000000000000a9898e05ff4855dc--