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 1x9JsT-00000001vWn-2MOP for pgsql-hackers@arkaria.postgresql.org; Wed, 23 Sep 2026 10:07:02 +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 1x9JsS-00000004NUS-0Fpn for pgsql-hackers@arkaria.postgresql.org; Wed, 23 Sep 2026 10:07:00 +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 1x9JsR-00000004NUK-2Y4D for pgsql-hackers@lists.postgresql.org; Wed, 23 Sep 2026 10:06:59 +0000 Received: from mail-wr2-x24.google.com ([2a00:1450:4864:30::24]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1x9JsP-00000000paw-0eIL for pgsql-hackers@lists.postgresql.org; Wed, 23 Sep 2026 10:06:58 +0000 Received: by mail-wr2-x24.google.com with SMTP id ffacd0b85a97d-482f63546c3so628896f8f.1 for ; Wed, 23 Sep 2026 03:06:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec.at; s=google; t=1790158016; x=1790762816; darn=lists.postgresql.org; h=message-id:date:content-transfer-encoding:content-id:content-type :mime-version:comments:references:in-reply-to:subject:cc:to:from :from:to:cc:subject:date:message-id:reply-to:content-type; bh=jJd7SSvYBQqSpubynUyep+dUo74ztPxZpFYZIJgCNPA=; b=sbCLXRDG22vng9PmaKzI0jscb3UCXPiDajV93iU3V4DTC6U7PANRJzQ/wgkY986A06 X3armxn8TNxYrEYBo2h+9+QUPmHb+qxgCUCIND34UnVQcsx892CGROH4at/QNlb7qd9+ dmTTyW7ZrxGMH5Mq3xL0/vU8TPQ1dlmfNGkM8Oeba1rCW5eJ3XuYOfhh1FvV9D9tgb/Y aePelMj1dNvEOg2NcFExBTGqFLU2RSRSHuyjX+Lsw3zL0GqLCc1mw9mDFr5Xh72gFrjV 1hCgdacKRZEv/ftMW5BIk0UdxMHrY2x3aSiyom7udjxUmMtjgwzY6ExAlQIQPYnLFEB2 M3Vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790158016; x=1790762816; h=message-id:date:content-transfer-encoding:content-id:content-type :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:content-type; bh=jJd7SSvYBQqSpubynUyep+dUo74ztPxZpFYZIJgCNPA=; b=U4LBRjgvsd7FhuAEgGt3NL0DaNdBqR51H10ZvH60ggL5bLZiqJlN3e88tEEFIMe1cq 7/tScnAXQyrTGn+i1HR2G3INxJgUFDe7F7Ee5GCkcMLmti33c9v57Atvr47I59rdjslt DtVppeeX27jN/L8ep7TJKaWGZ6AiHWbFtPKv/ZkwBs76TcLRj/6ZSUzAYRm3yFV0sxIz hQ3jte12rxEXTAwuj+NIiYHCmAEUB+7zbDJIty/Ti8dhAeTEjF01pAjrEauYbvRMYw5F R6GVLzt/ZDIJZZDdo4Ru/I7j9HkEYPd/RReq7ZIh+JLsOeZzLwKSNm6SJ12UaIoXYz4X 87IQ== X-Forwarded-Encrypted: i=1; AKwUvBxc8PpLSm19fm2d7w50Dd8eiTRxff6DVESQYw0BBHw7r6NaJ7+Qm2FUKgV+bpDy23BVs+S5J3CXwe83uOEg@lists.postgresql.org X-Gm-Message-State: AFuF++kDJg7JAMLFkoL2grGz6YNst0clKcSOmAnFCBdqJ9TOzW2LYN/g oQAL2tRwIDDCIqL4DrQZ0FP7GALUD4/4HxO+tNGHiHxqTdQy1kASTpB5Xbnd4GsOIs8= X-Gm-Gg: AYBFou2fKKdUBjoWCQzXro/hcCSl0wQCrv5fwNGgTytSd3FSpfrVwUsmto0luwYOmui VfFL/gFjQyBMzvMdKaxYcWbdOdXHn5TtufE9O3LBf0YF9n58ML1ca/Bsr/fJqKRdaBHgeyxGmKZ 4KNmohrsyp1w8qP6fAd6gp+L52DNCjGObSLHq3HvVKwDMb9kxXcVmAOC0r+1z2cEvoD1Dp/Ls1u hOgZXTVZmTmxEVUBA+re2rWYJAuES+ZB3iUsmzFHthGIRwHbDWoDCYlm/R56JuvmQuGhpx1MCH6 JM9uyZBXvLbUH1ij9QONwD6RRKUz9A4e4ls9ZOqhVQHpBcQ+etvOcCfZoq25geMWg5EIikHYYI1 FUCL3ODzu4x6nr62rii6d9N4VuHLSkJB0q6kZZuz1wDfywjIY0qpxpLajBZTj5aV1NqDc2RKgel smAIuuObBA1MjgsDvbs4Rf4nYxGV2w2f+uKDepj77bo14I4qciitWVwZD9fxVGuPBGGdwqYO7ZP By9hHHihkL52wiMdP0s X-Received: by 2002:a05:6000:98d:b0:487:37f:9ea7 with SMTP id ffacd0b85a97d-488670a02fbmr3135038f8f.32.1790158016125; Wed, 23 Sep 2026 03:06:56 -0700 (PDT) Received: from localhost (109-81-170-16.rct.o2.cz. [109.81.170.16]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-488684863d9sm5554163f8f.12.2026.09.23.03.06.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Sep 2026 03:06:55 -0700 (PDT) From: Antonin Houska To: Manu cc: shihao zhong , pgsql-hackers@lists.postgresql.org Subject: Re: REPACK enhancements In-reply-to: <179004809718.4166269.6878292164216131831@gmail.com> References: <179004809718.4166269.6878292164216131831@gmail.com> Comments: In-reply-to Manu message dated "Tue, 22 Sep 2026 00:34:57 -0300." X-Mailer: MH-E 8.6+git; nmh 1.8; GNU Emacs 28.3 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <28302.1790158015.1@localhost> Content-Transfer-Encoding: quoted-printable Date: Wed, 23 Sep 2026 12:06:55 +0200 Message-ID: <28303.1790158015@localhost> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Manu wrote: > 1. 0008: "could not find target tuple" after a concurrent DELETE/UPDATE > = > REPACK (CONCURRENTLY) fails when a row is deleted or updated by a > transaction that is still in progress when the copy reads the row, and > that commits after the copy and before the changes are replayed. The > attached isolation spec does it on a 1000-row table (two ranges, the > DELETE in the second one) and fails every time; with UPDATE instead of > DELETE it is the same. > = > Since the failed run leaves the new heap behind (see 2), I could look at > it with pageinspect: it has exactly one tuple with xmax set, the copy of > that row, with the same xmin/xmax as in the old heap (666/668, 668 being > the DELETE). So I think the copy carries the xmax of the transaction > still in progress, and HeapTupleSatisfiesNewHeap() then takes any valid > xmax as committed, so find_target_tuple() skips the row when the DELETE > is replayed. When tuple is copied, xmax needs to be set to invalid. If the deleting transaction commits, it'll set the xmax during replay. I could fix it loca= lly, will include the fix in the next patch version. > 2. 0006: the new heap left behind by a failed run blocks other rewrites > = > The commit message says a failed run leaves the new heap, and the next > REPACK (CONCURRENTLY) drops it. But that cleanup is only in > make_new_heap_for_repack(), and the leftover is pg_temp_ in the > table's own schema, the same name make_new_heap() uses for everything > else. Perhaps we need to use more specific name for CONCURRENTLY. > The leftover is a regular table as far as pg_dump knows, and it comes > with a constraint also named t_pkey (on t_pkey_repacknew), so the dump > does not restore cleanly: > = > CREATE TABLE public.pg_temp_16395 (id integer, v text); > ALTER TABLE ONLY public.pg_temp_16395 > ADD CONSTRAINT t_pkey PRIMARY KEY (id); > -- ERROR: relation "t_pkey" already exists Interesting is that the pg_constraint catalog allows duplicate constraint name, as long as the constraints are on different relations. Again, the transient table obviously needs a different constraint name. > 3. 0008: assertion failure in compute_new_xmax_infomask() > = > TRAP: failed Assert("TransactionIdIsCurrentTransactionId(add_to_xmax= ) || !TransactionIdIsValid(GetTopTransactionIdIfAny())"), File: "heapam.c"= , Line: 5564 > = > It fails in the replay after AccessExclusiveLock, called from > rebuild_relation_finish_concurrent(), in heap_update() of a replayed > UPDATE. So REPACK already has an XID of its own at that point. I don't know at the moment when the XID could get assigned. I need to do s= ome investigation. > 4. Progress reporting > = > With the trace from [1], these are the phases reported (a table with > only its primary key): > = > be00f041a33 v03 > REPACK (CONCURRENTLY) t 1 7 5 6 8 7 1 5 6 8 > ... USING INDEX t_pkey 1 3 4 7 5 6 8 7 1 5 7 5 6 8 > REPACK t [USING INDEX t_pkey] unchanged > = > build_new_index() sets PROGRESS_REPACK_PHASE_REBUILD_INDEX and now has > other callers: the identity index of the empty new heap, the one of the > auxiliary table, and the clustering index on the auxiliary table, which > is where the sort happens. So "rebuilding index" shows before "seq > scanning heap", and with USING INDEX "sorting tuples" and "writing new > heap" are never shown. Maybe the phase should only be set where the tabl= e's > own indexes are built, Do you mean that we should add variants of WRITE_NEW_HEAP and REBUILD_INDE= X specifically for the auxiliary table? > and SORT_TUPLES and WRITE_NEW_HEAP reported around the build and the sca= n of > the auxiliary table's index. With the auxiliary table, sorting IMO hapens in two phases: 1) build the clustering index and 2) scan the index and insert the output into the new heap. As long as each phase is reported on its own, I don't see room for SORT_TUPLES. > A small thing: your diff makes gcc warn that nblocks may be used > uninitialized in heapam_handler.c. I'll fix that. > [1] https://www.postgresql.org/message-id/CA%2BbCEdBKvmoOd%3DShLZA99FNHF= Oc5kjdPRzfOZLgSdcm07uy28g%40mail.gmail.com Thanks for review, I'll reflect it in the next patch version. -- = Antonin Houska Web: https://www.cybertec-postgresql.com