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 1xBsnG-00000003R66-0JlE for pgsql-hackers@arkaria.postgresql.org; Wed, 30 Sep 2026 11:48:14 +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 1xBsnE-000000028Oi-4BhS for pgsql-hackers@arkaria.postgresql.org; Wed, 30 Sep 2026 11:48:13 +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 1xBsnD-000000028Oa-41R1 for pgsql-hackers@lists.postgresql.org; Wed, 30 Sep 2026 11:48:12 +0000 Received: from fhigh-b7-smtp.messagingengine.com ([202.12.124.158]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1xBsnB-000000021wQ-3bsE for pgsql-hackers@lists.postgresql.org; Wed, 30 Sep 2026 11:48:11 +0000 Received: from phl-compute-05.internal (phl-compute-05.internal [10.202.2.45]) by mailfhigh.stl.internal (Postfix) with ESMTP id BAA8D7A0742; Wed, 30 Sep 2026 07:48:08 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-05.internal (MEProxy); Wed, 30 Sep 2026 07:48:08 -0400 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=fm3; t=1790768888; x= 1790855288; bh=XoeLQA0zGVAzitIb0vpd5aFRFW9VSbf4c7mI77pN/3A=; b=r g+z1hSBBMf7nE4ddolGsYeXv9Y/tkme5IN+H9fbxsGBzY6Js31V31CRPVE6qwyI6 UGNvjCYoFDEZqB1pUBlWbr435Ek0Lejw6zDYlO7zczz502xaZLPRAFaUmNKHdATD C1SQwbH1KorsIyf9cg8Pxa0cEUMsauuprdzxz0vgdcfZz0xA71ygoHVeW1RWacBP dH8/VyXxetAy20nud0sNddt+cJQQiGQHZzNTG6bAuMHXaKJYmiPnkvYTk3iGOTbl E9FGMYYpEF+Bt7zLC3s5APf+MjMkziIDNgCfU+/h/boImhJ7PeRnVd318LE0CMAP DYllDBBM0fGbHf24X5H4w== 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=fm1; t=1790768888; x=1790855288; bh=X oeLQA0zGVAzitIb0vpd5aFRFW9VSbf4c7mI77pN/3A=; b=lkRrQMiTmmuHhvHRD cCERgZ3uYn41ADcGIiroFq+XGuZwUpFvrnSLkhKa1+DowtK+06fpHYdSvCKPdlbD UmWOexdv3ryzo7x1CQIKFNbkWMKFMdjXn4I/7dNnazyYBO+R43A3qWMv+KAFNAhN QjdgQDgoSquP10D+SfQsJoIVRW9mSRdjk+qgiwUn4WVK4EI68TlgiStxEZkVff3i 4YKUPCdxiDBU4Nh/gKQk3ielKyCoZaKW1+QmMBgRoJcfAdIWmM6fb9yo3AN8LiQl rvfkY3PfKEUhxxFwnxu9vV+SQtTbipvoDNobDXmnrI/1DyRr2SZ6G1NN5U6+Y0mj UrV/Q== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTEqr2xzkqMYZQ0qt5IRdhk6Wf09U2rzKVmsGMP8hB8sZJWlKu7BOrljPqr36teYEz gE2p6K3WVnBpmfuWwNT6/N5bWEJbMURzymzvfswx+wGi4VQWZvv2GchjfVGUpPX2OiyBaJ ZA0zPbxxT1d6XBrgPr2pm+8okps/0H7kcZ0FUB1+ww9O1EkcFu2BoLVuYRiEA7U9pv58ah ICNc2zrBuBRtmUH+Rb5IP9xqwMCc/Na5d+NqrBo34QMfEuq42JN+9xs38SP3E9d0ms8N7x DhHQnkaLVeOirxoLpExBLHOF/y+c14NZTtUR4mxHwxbfCZbT90IlIRpChD+AnYgX1QnZqO kiw3RxoRn3VTwxcX4qpRvgnkEN2ZLscPfLI9WUfHJ8kHAChgr3tjIpvi9Xd7X3AAA6epOK mtFj92qQEh5S6PJQyDPozcWjXtA6PBeq34N8el2fHppFk/x8oO92so1UYy4PM9L4qRd81w luc1NyiYX4XpM8CSF74vnCV4uPx91+0KOrBn2h5KY0HXHVmLXOrujOvpSeQ3+1qjTRVsa3 IrmH4l6A6V8AfQA0UztrF21EWyQgBBROaWS8Siwzgts/6RfouvKBiVBsxbYSWYUJEux+2a unmfY50AuLPVUZzeolejAEdrfApXAJvu+qbyr4b4z+1YNdwugPjbEgBe0hJw X-ME-Proxy: Feedback-ID: ie3de48e3:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 30 Sep 2026 07:48:07 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kurilemu.de; s=schmee; t=1790768885; bh=pLkCa67JAtMCpg9my3IJBwY8Y+cx00bcgeiRPulLTMI=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=iLiqzb2FmyF6wOJ/Dqg1O9dLevdfrRWutzULYQOp9B8yuVJBhLvrEyd4m9HCTkNMI CVBC6DUDKBlVbd+cBrB0np1qwZ8AwP9cas5ACR2QmCWwRGq/Osd+zWjLPxsY3mD0il lAiIQqQFORL5x8FvWRz7/wc5HRC1NnZzY5hkJw7s8f2ZZC8lnYehf92KksTgEYM6wZ T4ShkFNgElX/Tcthis2hi4iX9hPqbMqYWy5Jk8o3X/CybxgMtyuYFD9iUYFuAKpgeK DGApebxyass74tavnT7HEhiFfUoe2ua3MlhQsQjgq+m3q1Sl1X2MRDzWqtEbvQqD5c +mt2cydcS/t7g== Received: by ida.kurilemu.internal (Postfix, from userid 1000) id A5AAAB00044; Wed, 30 Sep 2026 13:48:05 +0200 (CEST) Date: Wed, 30 Sep 2026 13:48:05 +0200 From: =?utf-8?Q?=C3=81lvaro?= Herrera To: Radim Marek Cc: PostgreSQL Hackers , "ah@cybertec.at" Subject: Re: REPACK (CONCURRENTLY) might keep dropped-column data Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="7velbpnu6zwkp5df" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --7velbpnu6zwkp5df Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit Hello Radim, thanks for testing! On 2026-Sep-30, Radim Marek wrote: > Aha, so on my way to office I started thinking and got more silly ideas, > and now can confirm this is more widespread than logical subscriber use > case. Oh, thanks for the simplified test case. We can fix this easily by setting the column to null in the tuple to write out, as in the attached patch. The adjust_toast_pointers() function should perhaps be renamed, and the comment rewritten, since it's no longer just about toast ... I didn't do that though. I put together a crude test case to verify with isolationtester. Without the fix, this reproduces the bloat you saw; with the fix, the toast table's size after the repack is zero. This needs some more boiling before being committable, but it suffices to show the problem. Regards -- Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/ "The Gord often wonders why people threaten never to come back after they've been told never to return" (www.actsofgord.com) --7velbpnu6zwkp5df Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=0001-Clear-out-values-from-dropped-columns.patch From 4ff5f220652e8a2bdb20ce3c6b3958ac7f6e312d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Wed, 30 Sep 2026 13:37:34 +0200 Subject: [PATCH 1/2] Clear out values from dropped columns Reported-by: Radim Marek Discussion: https://postgr.es/m/CAJgoLkK2UBzB1J9buCsSUbjf7bOqz-o_0=CeiTruU789BhBw-Q@mail.gmail.com --- src/backend/commands/repack.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 596c1abaf78..eadaec72d30 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -3017,6 +3017,9 @@ restore_tuple(BufFile *file, Relation relation, TupleTableSlot *slot) /* * Adjust 'dest' replacing any EXTERNAL_ONDISK toast pointers with the * corresponding ones from 'src'. + * + * We also take the opportunity to clear out the values in columns that were + * dropped. */ static void adjust_toast_pointers(Relation relation, TupleTableSlot *dest, TupleTableSlot *src) @@ -3029,7 +3032,10 @@ adjust_toast_pointers(Relation relation, TupleTableSlot *dest, TupleTableSlot *s varlena *varlena_dst; if (attr->attisdropped) + { + dest->tts_isnull[i] = true; continue; + } if (attr->attlen != -1) continue; if (slot_attisnull(dest, i + 1)) -- 2.47.3 --7velbpnu6zwkp5df Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=0002-Crude-test-case.patch From d4a40603003fadd01456ad74f17c97a219c365f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Wed, 30 Sep 2026 13:43:45 +0200 Subject: [PATCH 2/2] Crude test case XXX not for commit just yet --- .../specs/repack_dropped.spec | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/test/modules/injection_points/specs/repack_dropped.spec diff --git a/src/test/modules/injection_points/specs/repack_dropped.spec b/src/test/modules/injection_points/specs/repack_dropped.spec new file mode 100644 index 00000000000..1a1ea085299 --- /dev/null +++ b/src/test/modules/injection_points/specs/repack_dropped.spec @@ -0,0 +1,52 @@ +setup { + CREATE EXTENSION IF NOT EXISTS injection_points; + + create table repack_dropped (id int primary key, a text, b text); + alter table repack_dropped alter column b set storage external; + insert into repack_dropped select g, cash_words(g::money), repeat(cash_words(g::money), 10 * g) from generate_series(10, 100) g; + create function repack_dropped_f() returns trigger language plpgsql as $$ begin return OLD; end $$; + create trigger repack_dropped_t before update on repack_dropped for each row execute function repack_dropped_f(); + alter table repack_dropped drop column b; +} + +teardown { + drop table repack_dropped; + drop function repack_dropped_f; +} + +session s1 + +step s1_size +{ + select pg_relation_size(oid), pg_relation_size(reltoastrelid) from pg_class where relname = 'repack_dropped'; +} + +step s1_unlock +{ + SELECT injection_points_wakeup('repack-concurrently-before-lock'); +} + +session s2 +setup +{ + SELECT injection_points_set_local(); + SELECT injection_points_attach('repack-concurrently-before-lock', 'wait'); +} + +step s2_repack +{ + repack (concurrently) repack_dropped; +} + +session s3 +step s3_updates +{ + update repack_dropped set a = a || a; +} + +permutation + s1_size + s2_repack + s3_updates + s1_unlock + s1_size -- 2.47.3 --7velbpnu6zwkp5df--