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 1vfyV6-006ebv-1i for pgsql-hackers@arkaria.postgresql.org; Wed, 14 Jan 2026 10:53:21 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vfyU6-009pWB-1a for pgsql-hackers@arkaria.postgresql.org; Wed, 14 Jan 2026 10:52:18 +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 1vfyU5-009pW1-3B for pgsql-hackers@lists.postgresql.org; Wed, 14 Jan 2026 10:52:18 +0000 Received: from mail-qt1-x82d.google.com ([2607:f8b0:4864:20::82d]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vfyU3-000Mbv-1b for pgsql-hackers@lists.postgresql.org; Wed, 14 Jan 2026 10:52:17 +0000 Received: by mail-qt1-x82d.google.com with SMTP id d75a77b69052e-5014b5d8551so197231cf.0 for ; Wed, 14 Jan 2026 02:52:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1768387935; cv=none; d=google.com; s=arc-20240605; b=aojuQVXzdMiY68vHXP/pKfuhJzASdlBhho6f+2LPJ6MpOK6lEtpNF0i30Zu/kJuxYP kJiymTh2pWKc4JZ0CDt99tBWq6kea+fV/Q2FaymKS3W8m6VJG3guZgagdYYe+rUaINnM IJdL0VqZmQnlSFA2XyAxHs8amslhIkNx4vnA20uYl4tNApm2eNCzZ4Yyq3gVYFZtA0wE oqA9f2VB/CwLaH1ydxX8kEHIYbgGm8cB9f7ou4VTl13nQM6gl5SHNsfEwsO5jL0XU6Pz P6wEexvnALtCR60s0OKv6SBFhhpmjSbZ7UOZtRndIuFnEE/U12SvyK7aw9xocvTO1g/C FTZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=DkAN6vCOKUBaALozTuRvD/daS9QKBWN5hxf8lJovENE=; fh=kW9M1fAaQ5heWY4vRMGR7bd+ToI6o0ynH8pL9shhoaY=; b=Tl9cZDF5Kxq6KUEgtXbc53ieQ1inNvUKmRCPGvT6Q4MpGxLlyicJvpuGRmenpkLe3T oxfJZOtgknoZ/GpcIkSdms8cml4kqnaKY9/ID29cF6F2oz4/f01fJrkI9R8q05FSS8TI nrr2e4z5zJBE2SD5cHdINW5r1+y64nRZhlOIi0+CAfgEclB38KL+gW1VzF3XrnUlYkzi b8UiTGA/GHSCxhfFHqdFQ2eW/NrLju++A48yPdMa8N9ycT1SVGO432113vi7SIlDWXV6 IdJ5WQuXibzxO+ajAIqQnA4wPMcd3xQBcbW4G3Io6ZMzTxjFz8KXY7NKLEa56pb6Sm1U Hi/g==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1768387935; x=1768992735; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=DkAN6vCOKUBaALozTuRvD/daS9QKBWN5hxf8lJovENE=; b=ndlGKDkS56F8JacXMmxgsvDIPdTsV8RP80JSQ+vN+rHzTF9kybSbRXe30/PET9m7JA CfR4q8+5zqlrvw8/AbJWKRUgH4PifmMfxXTYaqK0u+Osre3UPJQj+jC9zkSsy8ZLbpLS wAGYy0qrBpoHV17027/a5LyZetMXTblnPcC230urmLC1h+tOdmhz8cmKKEi1i32i5HYa HAc0qA3q63zpTCYc7oVPf41r9Wo7Rad0TrLwEbYaC8L47TrwZCP3cSLyKW6rp/Now4xY Zv+HZocMFFBKtc6WSUnQEsG23jhJU4k1ZQR1WwAXJXp/255S3Av84JQH8x8v0HirMojn JOnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768387935; x=1768992735; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=DkAN6vCOKUBaALozTuRvD/daS9QKBWN5hxf8lJovENE=; b=KHXreuXqhKO8vpmY7JHuyWvEVPutfTjbxTCFIeMIpKl1kVL1EKLbHARms9aFKJxmLT nsobqCCiHdt44xynGPVDYe9bQ91nEkuZaKydVVtR+ZYomB9qK0iHZqBiyHyFV+jkkrH1 jN0DDcl9ipWWLJeNMEc8QLnc/kYHeLXt3WLAldUv3vsZ3j0h4V2j0MowzrW0dduJPKqY YpLFJOT77DbaClGghbEbbIPg0jWC3o9e/ptYeUzJKpjSHHtPx9HtJRmH56H9tUEvjGx9 u4GhTdnj5+ubKPAXHOFGI7XiGEpsIJxzFs1v1md2DJeS04C1G+XBf2rTYdQe3xIdIZSS fDcg== X-Forwarded-Encrypted: i=1; AJvYcCUs4T6iTeiBdyqLzN7bfh8GPxAaaoXP9MIYQCsIuRHIbXebjt7vDQQWfSDuDRJ//NabseOYZyUyHTtJNUXn@lists.postgresql.org X-Gm-Message-State: AOJu0YzDgqvOaskXjYBfP//5vEbVvUBc6VmbUiBXHY9Kebj+Zw7M9H8p glQB2w7wHmuSWThqHurMnABHskWVsSeRQnrksuMRMC03U1WanNROZUX8j16iGMuXJAq2wqflfXe u63foF92KVxZmA306Tc1DLKqhoE/auv0Rkirp72ep X-Gm-Gg: AY/fxX6+nb1ULGYW8EcVrc0w8w88B2g6KJYovkzmtozZmTG4b+HzLnFwDYeXZnD0QvN wOwM4Hho9DuoccJIC/zb7rHJTuaKzOYpFGZjQJlg9MlJKJn2J08iqSdKFuZW3fppK+VP1xN7nk1 wsm8r4Zy2TzFtTQdztMX+fa0+XClxk1WAU13G4DQ5SpWAGGNi9a8ktXdyG/ik7B0vegLYPRy6uJ A/WCT0DDUu/NQzPBiTnHtqBo7vyhjm99vx1tq0RPVN6P8eN2Hk3fx05O+BjamNDlg/Qy9/r7c36 wTyca1R9QQB+g0lbNXmW5HK6E5o= X-Received: by 2002:ac8:5749:0:b0:4f3:54eb:f26e with SMTP id d75a77b69052e-5014929462amr8037761cf.1.1768387935109; Wed, 14 Jan 2026 02:52:15 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Hannu Krosing Date: Wed, 14 Jan 2026 11:52:04 +0100 X-Gm-Features: AZwV_QjDcZpB8d_1VA9C0dZG8B0mewhuadCftr5pQGAM3dOsR8r9UJOi2ZMgjKI Message-ID: Subject: Re: Patch: dumping tables data in multiple chunks in pg_dump To: David Rowley Cc: Ashutosh Bapat , PostgreSQL Hackers , Nathan Bossart Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Tue, Jan 13, 2026 at 3:27=E2=80=AFAM David Rowley = wrote: > > On Fri, 14 Nov 2025 at 09:34, Hannu Krosing wrote: > > Added to https://commitfest.postgresql.org/patch/6219/ > > I think this could be useful, but I think you'll need to find a way to > not do this for non-heap tables. Per the comments in TableAmRoutine, > both scan_set_tidrange and scan_getnextslot_tidrange are optional > callback functions and the planner won't produce TIDRangePaths if > either of those don't exist. Maybe that means you need to consult > pg_class.relam to ensure the amname is 'heap' or at least the relam =3D > 2. Makes sense, will add. > On testing Citus's columnar AM, I get: > postgres=3D# select * from t where ctid between '(0,1)' and '(10,0)'; > ERROR: UPDATE and CTID scans not supported for ColumnarScan Should we just silently not chunk tables that have some storage architecture that does not have tids, or should pg_dump just error out in thiscase ? I imagine the Citus columnar is often used with huge tables where chunking would be most useful. Later it likely makes sense to have another option for chunking other types of tables, or maybe evan add something to the TableAM for chunking support. > 1. For the patch, I think you should tighten the new option up to mean > the maximum segment size that a table will be dumped in. I see you > have comments like: > > /* TODO: add hysteresis here, maybe < 1.1 * huge_table_chunk_pages */ > > You *have* to put the cutoff *somewhere*, so I think it very much > should be exactly the specified threshold. If anyone is unhappy that > some segments consist of a single page, then that's on them to adjust > the parameter accordingly. Otherwise, someone complaints that they got > a 1-page segment when the table was 10.0001% bigger than the cutoff > and then we're tempted to add a new setting to control the 1.1 factor, > which is just silly. If there's a 1-page segment, so what? It's not a > big deal. Agreed, will drop the TODO > Perhaps --max-table-segment-pages is a better name than > --huge-table-chunk-pages as it's quite subjective what the minimum > number of pages required to make a table "huge". I agree. My initial thinking was that it is mainly useful for huge tables, but indeed that does not need to be reflected in the flag name > 2. I'm not sure if you're going to get away with using relpages for > this. Is it really that bad to query pg_relation_size() when this > option is set? If it really is a problem, then maybe let the user > choose with another option. I understand we're using relpages for > sorting table sizes so we prefer dumping larger tables first, but that > just seems way less important if it's not perfectly accurate. Yeah, I had thought of pg_relation_size() myself. Another option would be something more complex which tries to estimate the dump file sizes by figuring out TOAST for each chunk. The think that makes this really complex is the possible uneven distribution of toast and needing to take into account both the compression of toast AND the compression of resulting dump file. > 3. You should be able to simplify the code in dumpTableData() so > you're not adding any extra cases. You could use InvalidBlockNumber to > indicate an unbounded ctid range and only add ctid qual to the WHERE > clause when you have a bounded range (i.e not InvalidBlockNumber). > That way the first segment will need WHERE ctid <=3D '...' and the final > one will need WHERE ctid >=3D '...'. Everything in between will have an > upper and lower bound. That results in no ctid quals being added when > both ranges are set to InvalidBlockNumber, which you should use for > all tables not large enough to be segmented, thus no special case. Makes sense, will look into it. > TID Range scans are perfectly capable of working when only bounded at one= side. > > 4. I think using "int" here is a future complaint waiting to happen. > > + if (!option_parse_int(optarg, "--huge-table-chunk-pages", 1, INT32_MAX, > + &dopt.huge_table_chunk_pages)) > > I bet we'll eventually see a complaint that someone can't make the > segment size larger than 16TB. I think option_parse_uint32() might be > called for. There can be no more than 2 * INT2_MAX pages anyway. I thought half of the max possible size should be enough. Do you really think that somebody would want that ? > David