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 1vdvnH-006oQ6-2k for pgsql-hackers@arkaria.postgresql.org; Thu, 08 Jan 2026 19:35:40 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vdvmG-0041by-0w for pgsql-hackers@arkaria.postgresql.org; Thu, 08 Jan 2026 19:34:37 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vdvmF-0041bp-2x for pgsql-hackers@lists.postgresql.org; Thu, 08 Jan 2026 19:34:36 +0000 Received: from mail-oo1-xc2a.google.com ([2607:f8b0:4864:20::c2a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vdvmE-005Kx9-0J for pgsql-hackers@postgresql.org; Thu, 08 Jan 2026 19:34:36 +0000 Received: by mail-oo1-xc2a.google.com with SMTP id 006d021491bc7-65745a436f7so2068628eaf.3 for ; Thu, 08 Jan 2026 11:34:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1767900871; x=1768505671; darn=postgresql.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=sh/805RrRaVYGLp70+PtusY5V5bUIHI5T+ab0y1mXm0=; b=HfqRKNKPSy0Pybz1ACOvrQxfcLJojPQGk70MUD0pzTaVZMwPm6yP+enC8XgdzhgBAg sXwVfzgNYp0SqbSR94E1qU71QGH0v3Egmg19hg0B6w6ieeANvmhsmhRoqNIzWhB57l5h YfaHHsyyLAP8YTlAAbFDMvJ8VXPp46mUVOYjrfqkxrv4EvQyjETn/JrnWXpKEKJ6Pm4G 3YG3a4qgLKzX96Ovbu4VlcLQlpFdHZolV2OEqWFNofEnko/jKGPumhcXXP1XTFjAPb4Q pApuaXnlZNA7p0kH3H/0+2m/Rj7jSnUzU49J5cV2pcmrVYbYy17TSsRrmoFsydgEZGyU 9WoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767900871; x=1768505671; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sh/805RrRaVYGLp70+PtusY5V5bUIHI5T+ab0y1mXm0=; b=iAVlZpLBZ54lXk4ocLIHIIvLH4Ze+lIO6dhTNFSNYfMG6z8KBBcvWT+ZTP8fNB5Pjt vyM3a+5FGzb3eTzg8xF63/dfItgrwvOOceENlBJ9to3MjuWxUUbAvVtNrfa/nmmEjj4x IiROwbu1/YNchcfoJCiFfFxAmbUGp8vZ2qxs6z4+M8eksMyTS5702Ru1uGwAu6tZ47A4 IXzVmqGdHpM2nquJfqRIr29xPVXsHwEDfDk7cXdmsFmOEQvkvuXlW4PhvU8Aw9e9Je3H vG7/Mvlq1LLv8IzBE487dTzuCEf2IAzJ8KKiHq68poDShXBCCnCKWhJ7n8mR3QGVWX6I CPkw== X-Forwarded-Encrypted: i=1; AJvYcCWVCs6w28kuFbs4jj3UsrPB8U26NathJ6DnWdxfgbXnX9eeZTx8499Xjnrvr+Ky6HwUJYClC7Mia7ZdM3nN@postgresql.org X-Gm-Message-State: AOJu0YzNeHiEOlIs6GF3pgczIdx/3r6PT1cAvijSHH/jNa3Lsgp/V/XX +zbtHGtqtebdGQNitdOwXYyA8TJHTZMUt/ltcKI+oWKPFYXwAy5misgx X-Gm-Gg: AY/fxX6tmpyNi1DQ5nlhcGX9T8ZTX7eurUHlDybfUvqlMTjCbgZp9Ke52KEHvVlc+Co TFsBrMYEebEGrvPs2KPg6opApcQNaL3NxXg6ZDj0oWCI48eJ4BkVMD4N1d2kYorVGf0PGzklx7B MKqUyXcmRAKC7eOlu17So76LNmV1LWMkUriNKGkglPsuNxwuzQ93OE3DNJB7G9BoSc4+JXe1hs8 DJz8f4kOY5HEA4yx4sTMpTfUVVS55FqxO+DarpgTm1fNFOzOYQzgCKIPr/CsQnEeWcYC779jRlQ GRkCfbef8Wba4TcriA06cJQi1damfBiCLjqqUh+MgSn3pjI7ok0uE26eqMj51aSsWjCcN2tQq8U PORKgHuFovNZ7CPlo5ONuaIJpCcaKdT71966VAgcNK/ZC+1VwK3AZ8cxHIeyEU0oTy2L4RTCQCD J+M6Bd76JEB2pw+8oQk3EBcqhR8KiFaMNVhsiuruFqVgI9mac0PdVcE/k6pql4zc+zM5/w9Ipas 2p1HZAFRNRnXUU= X-Google-Smtp-Source: AGHT+IEOiVfH98AVwFfIvgo4RXwgU2C0OOQnCbLe0Vcp6CHrMMTrjZc9ujOhiKKfRllQ9fckZp3cXg== X-Received: by 2002:a4a:e2d8:0:b0:65c:fe8b:53b3 with SMTP id 006d021491bc7-65f54ed6e82mr2031439eaf.9.1767900871415; Thu, 08 Jan 2026 11:34:31 -0800 (PST) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-65f48bbb218sm3682109eaf.1.2026.01.08.11.34.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Jan 2026 11:34:30 -0800 (PST) Date: Thu, 8 Jan 2026 13:34:28 -0600 From: Nathan Bossart To: Tom Lane Cc: Michael Paquier , Euler Taveira , pgsql-hackers Subject: Re: improve performance of pg_dump with many sequences Message-ID: References: <2885944.1767029161@sss.pgh.pa.us> <1862355.1767827628@sss.pgh.pa.us> <1869482.1767831892@sss.pgh.pa.us> <1980877.1767896379@sss.pgh.pa.us> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="WE5vjb+B2g0raN9A" Content-Disposition: inline In-Reply-To: <1980877.1767896379@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --WE5vjb+B2g0raN9A Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Jan 08, 2026 at 01:19:39PM -0500, Tom Lane wrote: > One nitpicky point is that try_sequence_open() will still error out > if it is given an OID that is a non-sequence relation. I think it'd > be more desirable for it to close the relation again and return NULL. > That's probably insignificant for pg_dump's usage, because we could > only hit the case with very improbable OID wraparound timing. But > I think our experience with catalog-inspection functions similar to > pg_get_sequence_data is that it's usually better to return NULL than > throw an error. Hm. That makes sense, but both try_table_open and try_index_open error for wrong relkinds. I could change all of the try_*_open functions to return NULL in that case, or I could just open-code the relkind check in pg_get_sequence_data after try_relation_open (and have it return NULL for non-sequences). I'm leaning towards the latter, if for no other reason than it might be slightly nicer for back-patching (e.g., smaller, no new extern functions). -- nathan --WE5vjb+B2g0raN9A Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0001-pg_dump-fix-use-of-pg_get_sequence_data.patch From 68a9b7fb9714805819b040f19851601f1426c990 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 8 Jan 2026 11:29:59 -0600 Subject: [PATCH v2 1/1] pg_dump: fix use of pg_get_sequence_data --- src/backend/commands/sequence.c | 14 ++++++++------ src/bin/pg_dump/pg_dump.c | 10 ++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 904eeada5ab..e1b808bbb60 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -1794,7 +1794,6 @@ pg_get_sequence_data(PG_FUNCTION_ARGS) { #define PG_GET_SEQUENCE_DATA_COLS 3 Oid relid = PG_GETARG_OID(0); - SeqTable elm; Relation seqrel; Datum values[PG_GET_SEQUENCE_DATA_COLS] = {0}; bool isnull[PG_GET_SEQUENCE_DATA_COLS] = {0}; @@ -1811,13 +1810,15 @@ pg_get_sequence_data(PG_FUNCTION_ARGS) LSNOID, -1, 0); resultTupleDesc = BlessTupleDesc(resultTupleDesc); - init_sequence(relid, &elm, &seqrel); + seqrel = try_relation_open(relid, AccessShareLock); /* - * Return all NULLs for sequences for which we lack privileges, other - * sessions' temporary sequences, and unlogged sequences on standbys. + * Return all NULLs for missing sequences, sequences for which we lack + * privileges, other sessions' temporary sequences, and unlogged sequences + * on standbys. */ - if (pg_class_aclcheck(relid, GetUserId(), ACL_SELECT) == ACLCHECK_OK && + if (seqrel && seqrel->rd_rel->relkind == RELKIND_SEQUENCE && + pg_class_aclcheck(relid, GetUserId(), ACL_SELECT) == ACLCHECK_OK && !RELATION_IS_OTHER_TEMP(seqrel) && (RelationIsPermanent(seqrel) || !RecoveryInProgress())) { @@ -1838,7 +1839,8 @@ pg_get_sequence_data(PG_FUNCTION_ARGS) else memset(isnull, true, sizeof(isnull)); - sequence_close(seqrel, NoLock); + if (seqrel) + relation_close(seqrel, AccessShareLock); resultHeapTuple = heap_form_tuple(resultTupleDesc, values, isnull); result = HeapTupleGetDatum(resultHeapTuple); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 7df56d8b1b0..573fb0c06a1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -137,6 +137,7 @@ typedef struct int64 cache; /* cache size */ int64 last_value; /* last value of sequence */ bool is_called; /* whether nextval advances before returning */ + bool null_seqtuple; /* did pg_get_sequence_data return nulls? */ } SequenceItem; typedef enum OidOptions @@ -18959,6 +18960,7 @@ collectSequences(Archive *fout) sequences[i].cycled = (strcmp(PQgetvalue(res, i, 7), "t") == 0); sequences[i].last_value = strtoi64(PQgetvalue(res, i, 8), NULL, 10); sequences[i].is_called = (strcmp(PQgetvalue(res, i, 9), "t") == 0); + sequences[i].null_seqtuple = (PQgetisnull(res, i, 8) || PQgetisnull(res, i, 9)); } PQclear(res); @@ -19230,6 +19232,10 @@ dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo) bool called; PQExpBuffer query = createPQExpBuffer(); + /* needn't bother if not dumping sequence data */ + if (!fout->dopt->dumpData && !fout->dopt->sequence_data) + return; + /* * For versions >= 18, the sequence information is gathered in the sorted * array before any calls to dumpSequenceData(). See collectSequences() @@ -19271,6 +19277,10 @@ dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo) entry = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); + if (entry->null_seqtuple) + pg_fatal("failed to get data for sequence \"%s\"; user may lack privileges or sequence may have been dropped", + tbinfo->dobj.name); + last = entry->last_value; called = entry->is_called; } -- 2.39.5 (Apple Git-154) --WE5vjb+B2g0raN9A--