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 1vfKsT-0016kt-2a for pgsql-hackers@arkaria.postgresql.org; Mon, 12 Jan 2026 16:34:51 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vfKrS-0019xV-0F for pgsql-hackers@arkaria.postgresql.org; Mon, 12 Jan 2026 16:33:46 +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.96) (envelope-from ) id 1vfKrQ-0019xM-2d for pgsql-hackers@lists.postgresql.org; Mon, 12 Jan 2026 16:33:45 +0000 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vfKrF-0003DM-1w for pgsql-hackers@lists.postgresql.org; Mon, 12 Jan 2026 16:33:43 +0000 Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-47775fb6cb4so36455955e9.0 for ; Mon, 12 Jan 2026 08:33:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec.at; s=google; t=1768235613; x=1768840413; darn=lists.postgresql.org; h=message-id:date:mime-version:comments:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=cYEAm7NfQ4Dqms4FdTkvtKFt6UsqdqKLlV4HlVZcFX4=; b=buEdHuM+dngrI9gm91QTVXJCqnnuD4F+Jizip6s2MKYmhMhSr1dwG8P1yOcaoX0xBm aasL4Xx9VXtNJipg7q39Aib2QR2XJvoGXkkPzXnjaXs/T8xIAULdDIILRGOCxpj5u04f VTMU3SQByFILps15I811Rc5ftu8cVlSN6snUE3sdZMTMdLx9uUmLb3wjgyCgtWVErsoM FTaC3ts3xxURA6+srCVYDuDjda4m5ooeul6QSHlw51NjA2SiSDLA5ioh+fJ7vHePRy+G IIqlOZlvZUD1nFcLeBR1UrLu+6pVDV9GQyRYQRUXB/acg5HhBC6me48mZe1t+0RjY17p iW1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768235613; x=1768840413; h=message-id:date: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; bh=cYEAm7NfQ4Dqms4FdTkvtKFt6UsqdqKLlV4HlVZcFX4=; b=uccGmItfI3bN4o5GZXcrxl1/kaJZZvJX0KcDeviMSfONFldTgMaRdvFRdL5xx1CYQ5 N9Zrlvc8/yP0Kd/siITXPdcNJkGb3u80kp9ovRFOTPDjlsF7d5PHD+aOeRWD2or/Phn9 CAQlz0uXLHCuwr3+riZKc2nuQk7QtAzCoYjRUkYl5BXACK5DJVIrhDe+UbpZmjugdnbc gE0IiWVeZayZfFFhaynDvK+9mTqON0AiPpNp6RjaBxx2KYDplAGfbQS7+pQfOMhhv9h3 oNu/8G7TmX+vWfBETngztfeD21UIdnf20vZYptXS1a2xkJ3AEtPqkfGzTjY57MokbjXS +5uA== X-Forwarded-Encrypted: i=1; AJvYcCXMgkfVJO5k0CW6M1SjeHg4xcgpaGoITccpziKpStkn61qgqpr0DyUH24wTRABGXDr9VVTFVJxaimVzkIH3@lists.postgresql.org X-Gm-Message-State: AOJu0Yw66Zozx7CUEaDB6fHjGOmGEYLmeBNliKhoudKgKnGhP+DSmcPW qsAKnhRE4GVNW7L9gS4CTBLgMJE9a11+ZQzLNQSZLQdk1J90EqB4YrCwXf7x4lO/4sc= X-Gm-Gg: AY/fxX49CkJsoGWibvt3P3XHmJ7L2nJnTknFx0cuoJqkQZOWXsplPfLomkhlYG76ulF zj6bwSfczuuQnD5RztEX1hcDBY/66X7BVitZPgt54ihNb2osQ8lN57lbzW66xm7pFqx+teuTFxN MpNKazcb8YlyXzZO4hpsipW4i2fyvRkYAc/xK8EWwYSHrWBjzIwZjLyOhozZH9THzGESkuw7oyj DBMuEwoFcE86kzZGXGUigbRj37udUbG9emaGxo2PcbPGOglMhgr1/qVSnOFkas1Ag4gV9JrJVTx WJQDrO60+WXTmv4z0ZyabZMATXEwwcw1lEvw0QNajxHQ7U/kF1F85+fWoducA8lakQs9EdSyM49 Xe54yymsqMZo+lD2zj5ime+qonUVM51wYNxbqWZPq39KWowi1LNVdC92BemL8MzgGOM1fZ/UsIW ZVCoqSQ+hah2gt/QVpHbsK6sd7 X-Google-Smtp-Source: AGHT+IHCCu5FW/nOUwrtqvQDhop4iLJtVnFwIbvqiEICKLp5oh9ksm5eGe4qmiz3TlKhotGwiJP/yA== X-Received: by 2002:a05:600c:458e:b0:47b:e29f:e067 with SMTP id 5b1f17b1804b1-47d84b0b21dmr199346195e9.6.1768235612169; Mon, 12 Jan 2026 08:33:32 -0800 (PST) Received: from localhost (109-81-168-246.rct.o2.cz. [109.81.168.246]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47d8717a48asm138090755e9.8.2026.01.12.08.33.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jan 2026 08:33:31 -0800 (PST) From: Antonin Houska To: Mihail Nikalayeu cc: Alvaro Herrera , Pg Hackers , Robert Treat Subject: Re: Adding REPACK [concurrently] In-reply-to: References: <202512151349.vlq3mpfniyk3@alvherre.pgsql> <11247.1767609087@localhost> <11558.1767609632@localhost> <141054.1767891540@localhost> Comments: In-reply-to Mihail Nikalayeu message dated "Sat, 10 Jan 2026 20:37:06 +0300." X-Mailer: MH-E 8.6+git; nmh 1.8; GNU Emacs 28.3 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Date: Mon, 12 Jan 2026 17:33:30 +0100 Message-ID: <137668.1768235610@localhost> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Mihail Nikalayeu wrote: > On Thu, Jan 8, 2026 at 7:59=E2=80=AFPM Antonin Houska wr= ote: > > v29 tries to fix the problem. >=20 > Some comments for 0001-0004. Thanks. > ------ 0001 ----- > > * FIXME: this is missing a way to specify the index to use to repack one > > * table, or whether to pass a WITH INDEX clause when multiple tables are > > * used. Something like --index[=3Dindexname]. Adding that bleeds into > > * vacuuming.c as well. >=20 > Comments look stale. This is an open question, see [1]. > > return "???"; > I think it is better to add Assert(false); before (done that way in a > few places). This is not really uncommon, see for example event_trigger.c. Added the comment /* keep compiler quiet */ > > =E2=80=9CAn utility=E2=80=9D > Should be =E2=80=9CA utility=E2=80=9D Not sure it *should be* [2], but "a utility" appears to be much more common= in the tree. Changed. > > else if (pg_strcasecmp(cmd, "CLUSTER") =3D=3D 0) > > cmdtype =3D PROGRESS_COMMAND_CLUSTER; >=20 > Should we set PROGRESS_COMMAND_REPACK here? Because cluster is not > used anywhere. Probably we may even delete PROGRESS_COMMAND_CLUSTER. Good point. Actually we do not need this branch at all as there's no pg_stat_get_progress_info('CLUSTER') call in system_views.sql. Removed. > > CLUOPT_RECHECK_ISCLUSTERED > It is not set anymore... Probably something is wrong here or we need > to just remove that constant and check for it. Yes, it got lost somehow. I added it where I think it's appropriate. > ------ 0002 ----- >=20 > > rebuild_relation(Relation OldHeap, Relation index, bool verbose) > It removes unused cmd parameter, but I think it is better to not add > it in the previous commit. Yes, the changes were not correctly split into diffs. Fixed. > ------ 0003 ----- >=20 > > int newxcnt =3D 0; >=20 > I think it is better to use uint32 for consistency here. This diff only moves code across functions, I'm not going to do other chang= es now. > Also, I think it is worth adding Assert(snapshot->snapshot_type =3D=3D > SNAPSHOT_HISTORIC_MVCC) ok > ------ 0004 ----- >=20 > > /* Is REPACK (CONCURRENTLY) being run by this backend? */ > > if (am_decoding_for_repack()) >=20 > We should check change_useless_for_repack here - to avoid looking and > TRUNCATE of unrelated tables. In v29, if XLOG_HEAP_TRUNCATE of an unrelated table is seen here, we'll rai= se ERROR unnecessarily instead of truncating the table. That's obviously wrong= as well. On the other hand, it's not trivial to teach change_useless_for_repac= k() to filter the TRUNCATE records by file locator. So besides adding a call of change_useless_for_repack(), I removed that ereport(ERROR) from heap_decode= () and added a comment to plugin_change() explaining why TRUNCATE on the table being repacked should fire the Assert() statement: TRUNCATE shouldn't appear here due to locking. > > /* For the same reason, unlock TOAST relation. */ > > if (OldHeap->rd_rel->reltoastrelid) > > LockRelationOid(OldHeap->rd_rel->reltoastrelid, AccessExclusiveLock); >=20 > Hm, we are locking here instead of unlocking ;) Copy-pasto, the lock level is incorrect as well. Actually the whole idea of unlocking index and TOAST relation is probably wrong: if some transaction already locked the table with a lock that does not conflict with ShareUpdateExclusiveLock, it should not need to wait for ShareUpdateExclusiveLock on index / TOAST relation. At least I don't recall= a case where index / TOAST requires stronger lock than the main table. So I removed the unlocking altogether. > > (errhint("Relation \"%s\" has no identity index.", > > RelationGetRelationName(rel))))); >=20 > One level of braces may be removed. > > * to decode on behalf of REPACK (CONCURRENT)? >=20 > CONCURRENTLY > > * If recheck is required, it must have been preformed on the source >=20 > "performed" > > * On exit,'*scan_p' contains the scan descriptor used. The caller must = close > > * it when he no longer needs the tuple returned. >=20 > There is no scan_p argument here. > > * Copyright (c) 2012-2025, PostgreSQL Global Development Group >=20 > 2026 ok > > newtuple =3D change->data.tp.newtuple !=3D NULL ? > > change->data.tp.newtuple : NULL; >=20 > > oldtuple =3D change->data.tp.oldtuple !=3D NULL ? > > change->data.tp.oldtuple : NULL; > > newtuple =3D change->data.tp.newtuple !=3D NULL ? > > change->data.tp.newtuple : NULL; >=20 > Hm, should it be just x =3D y ? Thanks for spotting this. The reason is that significant portion of this pa= tch is copied from the pg_squeeze extension, and there it originally looked lik= e: oldtuple =3D change->data.tp.oldtuple !=3D NULL ? &change->data.tp.oldtuple->tuple : NULL; I failed to notice the unnecessary complexity when adapting the code to the commit 08e6344fd642 in postgres core, and then copied it to the REPACK patch. Fixed now. > > apply_concurrent_insert >=20 > Double newline at function start. ok > > heap2_decode >=20 > Should we check for change_useless_for_repack here also? (for multi > insert, for example). Yes, done, thanks. While doing that, I've done the same for XLOG_HEAP_CONFI= RM in heap_decode() as it'd be bad for reorderbuffer.c to receive the CONFIRM record w/o previously receiving the actual (speculative) INSERT. [1] https://www.postgresql.org/message-id/7224.1762326739%40localhost [2] https://en.wiktionary.org/wiki/an#Usage_notes --=20 Antonin Houska Web: https://www.cybertec-postgresql.com --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=v30-0001-Add-REPACK-command.patch Content-Transfer-Encoding: quoted-printable