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 1o7fNG-0003VQ-EH for pgsql-hackers@arkaria.postgresql.org; Sat, 02 Jul 2022 15:49:34 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1o7fNE-0002At-G2 for pgsql-hackers@arkaria.postgresql.org; Sat, 02 Jul 2022 15:49:32 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1o7fNE-0002AN-1t for pgsql-hackers@lists.postgresql.org; Sat, 02 Jul 2022 15:49:32 +0000 Received: from mail-qk1-x732.google.com ([2607:f8b0:4864:20::732]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1o7fN5-00034Q-32 for pgsql-hackers@postgresql.org; Sat, 02 Jul 2022 15:49:30 +0000 Received: by mail-qk1-x732.google.com with SMTP id b133so3876613qkc.6 for ; Sat, 02 Jul 2022 08:49:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20210112.gappssmtp.com; s=20210112; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=2Csf7PEoDGwPmxdi8oVkL+twDaB8cXuXO8JAXTdygs0=; b=dtN4SoPtECc1pHuVhCuXp20OSITztzohktPYPP8+fAZK938+yd1HB/XuZ9BFILDnFZ suAvIfJ+9lJ9iCq+ArTdeF9sQ2DTGiOfA7+g8lN5YfCrQrO2RG9vYnxYppiQFII+ekm9 TGbf7AvKBfqP21n4SwpeuNgwxwU45PU7qoroxbETWqObSmyggegkhxFY/whBlGtH6K3m XYLnM/ySzNRl4vNNwkrqbQc3p5DpfNHQuTI06jXA54LrBlrQxLjQJGYiO+MP7SL14bqV yGXID5JjqifFeAxWwYMusUGmVaibgAL6AE77MUf5ACenMumPwgYBzzgFzPfFapS9+ymK ikvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=2Csf7PEoDGwPmxdi8oVkL+twDaB8cXuXO8JAXTdygs0=; b=pr8WZl1QCLmmdQRFCJnc36TNeUsOuWbzPom9tqrRU69bTMjFNuHC5KB3lrObTuJlR4 a/4WXyPAabhAUKtDHy/gTAu5SaNFcEErN8ns+kodEK5nB8RANtStQ8ss01Xh7OwfOiFx TkcUoaeR04n90mewB5LeYfKTlCxFJpnle3flXkPhNJ5WPQIY7mJb+Glm7OR+LEmCIR7P VTsV4cjSTCSqWVpjKL4V01R7DGf7TBU+UJCG+onbATfxo48fys8FQu6qhwuv3gBvCEV5 FMcs+P/pdMnrdv5jQ/dVYYIz515TH7Big+jmw1XuqZVHdOClS1n5H0RWhiKFAN13Skyt pbeg== X-Gm-Message-State: AJIora+Po3qX+0c1mm5tzT93YuHGUuT/HYvnia3gj26Jrm8FqD2ZpeNs a5qOc5dfHt+N6BGv2/3otF8Y8g== X-Google-Smtp-Source: AGRyM1vHpcD97sm7l8fnsKNIes17dxrs8Wgsp+YeSEqsx5k8CzsSG9Cj25oxpBSbAy4cnPReJ6rmgw== X-Received: by 2002:a37:a245:0:b0:6ae:de8e:9daf with SMTP id l66-20020a37a245000000b006aede8e9dafmr14464716qke.527.1656776959876; Sat, 02 Jul 2022 08:49:19 -0700 (PDT) Received: from pryzbyj.telsasoft (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id cm10-20020a05622a250a00b0031bed25394csm9548461qtb.3.2022.07.02.08.49.18 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Jul 2022 08:49:19 -0700 (PDT) Received: by pryzbyj.telsasoft (Postfix, from userid 1000) id AD5BA800785; Sat, 2 Jul 2022 10:49:17 -0500 (CDT) Date: Sat, 2 Jul 2022 10:49:17 -0500 From: Justin Pryzby To: Robert Haas Cc: pgsql-hackers@postgresql.org, Bruce Momjian , Shruthi Gowda Subject: Re: pg15b2: large objects lost on upgrade Message-ID: <20220702154917.GM13040@telsasoft.com> References: <20220701231413.GI13040@telsasoft.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="ieNMXl1Fr3cevapt" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --ieNMXl1Fr3cevapt Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sat, Jul 02, 2022 at 08:34:04AM -0400, Robert Haas wrote: > On Fri, Jul 1, 2022 at 7:14 PM Justin Pryzby wrote: > > I noticed this during beta1, but dismissed the issue when it wasn't easily > > reproducible. Now, I saw the same problem while upgrading from beta1 to beta2, > > so couldn't dismiss it. It turns out that LOs are lost if VACUUM FULL was run. > > Yikes. That's really bad, and I have no idea what might be causing it, > either. I'll plan to investigate this on Tuesday unless someone gets > to it before then. I suppose it's like Bruce said, here. https://www.postgresql.org/message-id/20210601140949.GC22012%40momjian.us |One tricky case is pg_largeobject, which is copied from the old to new |cluster since it has user data. To preserve that relfilenode, you would |need to have pg_upgrade perform cluster surgery in each database to |renumber its relfilenode to match since it is created by initdb. I |can't think of a case where pg_upgrade already does something like that. Rather than setting the filenode of the next object as for user tables, pg-upgrade needs to UPDATE the relfilenode. This patch "works for me" but feel free to improve on it. --ieNMXl1Fr3cevapt Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0001-wip-preserve-relfilenode-of-pg_largeobject-and-its-i.patch" From 88cbe118d4eb4dcf9b6d2831d81f723587d80942 Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Sat, 2 Jul 2022 00:48:47 -0500 Subject: [PATCH] wip: preserve relfilenode of pg_largeobject and its indexes An empty table is created by initdb, but its filenode was not preserved, so pg_largeobject was empty after upgrades. See also: 9a974cbcba005256a19991203583a94b4f9a21a9 https://www.postgresql.org/message-id/20210601140949.GC22012%40momjian.us https://www.postgresql.org/message-id/20220701231413.GI13040%40telsasoft.com --- src/bin/pg_dump/pg_dump.c | 37 +++++++++++++++----------- src/bin/pg_upgrade/t/002_pg_upgrade.pl | 2 ++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d9c5bcafd20..c629f4154fc 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -3135,7 +3135,7 @@ dumpDatabase(Archive *fout) /* * pg_largeobject comes from the old system intact, so set its - * relfrozenxids and relminmxids. + * relfrozenxids, relminmxids and relfilenode. */ if (dopt->binary_upgrade) { @@ -3143,34 +3143,41 @@ dumpDatabase(Archive *fout) PQExpBuffer loFrozenQry = createPQExpBuffer(); PQExpBuffer loOutQry = createPQExpBuffer(); int i_relfrozenxid, + i_relfilenode, + i_oid, i_relminmxid; /* * pg_largeobject */ if (fout->remoteVersion >= 90300) - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid\n" + appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" - "WHERE oid = %u;\n", - LargeObjectRelationId); + "WHERE oid IN (%u, %u);\n", + LargeObjectRelationId, LargeObjectLOidPNIndexId); else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid\n" + appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" - "WHERE oid = %u;\n", - LargeObjectRelationId); + "WHERE oid IN (%u, %u);\n", + LargeObjectRelationId, LargeObjectLOidPNIndexId); - lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data); + lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid"); i_relminmxid = PQfnumber(lo_res, "relminmxid"); + i_relfilenode = PQfnumber(lo_res, "relfilenode"); + i_oid = PQfnumber(lo_res, "oid"); + + appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid, relminmxid and relfilenode\n"); + for (int i = 0; i < PQntuples(lo_res); ++i) + appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n" + "SET relfrozenxid = '%u', relminmxid = '%u', relfilenode = '%u'\n" + "WHERE oid = %u;\n", + atooid(PQgetvalue(lo_res, i, i_relfrozenxid)), + atooid(PQgetvalue(lo_res, i, i_relminmxid)), + atooid(PQgetvalue(lo_res, i, i_relfilenode)), + atooid(PQgetvalue(lo_res, i, i_oid))); - appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n"); - appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n" - "SET relfrozenxid = '%u', relminmxid = '%u'\n" - "WHERE oid = %u;\n", - atooid(PQgetvalue(lo_res, 0, i_relfrozenxid)), - atooid(PQgetvalue(lo_res, 0, i_relminmxid)), - LargeObjectRelationId); ArchiveEntry(fout, nilCatalogId, createDumpId(), ARCHIVE_OPTS(.tag = "pg_largeobject", .description = "pg_largeobject", diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl index 67e0be68568..a22f0f8c885 100644 --- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl +++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl @@ -208,6 +208,8 @@ if (defined($ENV{oldinstall})) } } +$oldnode->safe_psql("regression", "VACUUM FULL pg_largeobject;"); + # In a VPATH build, we'll be started in the source directory, but we want # to run pg_upgrade in the build directory so that any files generated finish # in it, like delete_old_cluster.{sh,bat}. -- 2.17.1 --ieNMXl1Fr3cevapt--