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 1vdtwE-006Q5E-2o for pgsql-hackers@arkaria.postgresql.org; Thu, 08 Jan 2026 17:36:47 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vdtwD-003c6i-1Z for pgsql-hackers@arkaria.postgresql.org; Thu, 08 Jan 2026 17:36:46 +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 1vdtwD-003c6W-0M for pgsql-hackers@lists.postgresql.org; Thu, 08 Jan 2026 17:36:45 +0000 Received: from mail-oi1-x22f.google.com ([2607:f8b0:4864:20::22f]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vdtwB-005K0d-1t for pgsql-hackers@postgresql.org; Thu, 08 Jan 2026 17:36:45 +0000 Received: by mail-oi1-x22f.google.com with SMTP id 5614622812f47-4557f0e5e60so2205074b6e.3 for ; Thu, 08 Jan 2026 09:36:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1767893802; x=1768498602; 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=Rgt1zdnhM1aALQ0RCahG+5mkhNP8ZxMK+Aq/GrS58/Q=; b=h4AQzE/DMlpjSH5SpUZsaAYTZUBWerD/7ZRIBVaN9+9w/fDJJFw7dEvuhaK851jTE0 fo7BEEURZq55qrVWhhvLzZFNCqzf4JqzdJOWlEkcuCD/GWxa7lK8NLuddi6xchf7KkXb iVd+VOho4s5UiqAlhqeGH2ZwXRIsIe72ODLQImYRzuDbX+LK2nXgLcJslG+ZVjRmaQj+ 61VhTkGqGoH3qJHSzceLEz5k7KZZtPQH7ks2Clpu24qS45x3yaY5A77owUdq/13FiaEz aQ4n6Z1k8zG0NQtGFOA5OXClcZywLyi+hZJyhnZYy+Px1Rotcqlao9hWiETW4ZH2jd+9 fvRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767893802; x=1768498602; 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=Rgt1zdnhM1aALQ0RCahG+5mkhNP8ZxMK+Aq/GrS58/Q=; b=s2uz/HZcnmrJhE2nPR6WdT36ZdzqidAw9jXXNckn5ZwgY1PuUPBbJfDBlBKyHZ8zA6 yNaKqh46Y0IMVklf+vLjQYYGiRULaMDh/yz9brTX4YnLTvEBaIF/Vm0hCCf+Bvosah4n hk2Iim6JNlefS+QkKnLasHsqx+JCWQjUdsIWLzuP3p1ikaaMI9fXreqrMPUEE1eHc2lc U+prAonf/rxsAGVCaczb9UDZ4l85kfQym2JlitrONeP2IhdixCeVR9y85WWtTzvkBvMV j5z7tsvJx2fAsyeyuIjajuJ+7hjtqlR5oo7sVJRKXxaF8owkyLGkOnD4gj/QZDguGUZR XYxg== X-Forwarded-Encrypted: i=1; AJvYcCXOCUFKLvnvW6lB3MOsVUN7hQEHMLPX6kRZy1JBi5wR61GbpKIDDOroUPYst9keY/WuQz4V9KwAvFqXZ6fb@postgresql.org X-Gm-Message-State: AOJu0YyrfW4tMi3eWEiEK1OVn51tEdms3V8XSPD5EDswQw4rOnLAJEqX j1htwyUE6EdyygUfDIG87K//pt97Ymcc2fEMIt3fZJO8CMi7wsx5LMNoHpFUAA== X-Gm-Gg: AY/fxX56LGDOxt2LMY2BNCC3NCjT3RAXTDX6hgiEaFUMJKfjw9UbzAX8c8NVSdaVXqq Ys8ntPSfANz8jd5pKi1sXMAEn3/1D9L6xLvzJ3uBqb+GzVhUOFRVOhBkXnqRsCc5ux6wwWYVDSi 9hl+29yldQQdm2FS99w9mmPC0VcK02msYkqB/IipgG2udk5T6fHj1Hv76XwMl9HstAXvDgRh9Mm RHTBMx1Pt0ihlpPO8QVLX+8n3P17qbldptF0pM7F9n0qGqKolyn7KvbcM/2CBlfW51BSLfaxbbI 4Y9y3oa/Zn0cusJHe8LhnpaR1iHV6wj2JDJVV+Q9qftpyyQtkcPqrK4c5gECWcaRKt6EKLq6W+O FwycqFnRY1tl4Ck64aRJZWc8bwAOlNONFjb59I0gUfnTPHF0EaEucabCITNWiChV6j2eVVgcUJM pJ0cYRBn02rmqkHgqHH5g7Rhtf8ec4X3Ac7N5Hw8Y491VyCFrv9UfkHt9dShmL6wCxJKZR7fVYQ Fze52bcF3K6dmI= X-Google-Smtp-Source: AGHT+IFgiGFARddwlXaCGQ1JeZM5LFO6+wOaYUGNl8WLLKKd6Hujw4j0hYQsYdsCtXrB0U8sLRpIWQ== X-Received: by 2002:a05:6808:3c49:b0:450:5ca:5170 with SMTP id 5614622812f47-45a6be3885amr3120793b6e.33.1767893801950; Thu, 08 Jan 2026 09:36:41 -0800 (PST) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id 5614622812f47-45a76abe858sm1602755b6e.9.2026.01.08.09.36.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Jan 2026 09:36:41 -0800 (PST) Date: Thu, 8 Jan 2026 11:36:38 -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: <3640163.1721275101@sss.pgh.pa.us> <2885944.1767029161@sss.pgh.pa.us> <1862355.1767827628@sss.pgh.pa.us> <1869482.1767831892@sss.pgh.pa.us> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="iyprHr6gT7UrymdC" Content-Disposition: inline In-Reply-To: <1869482.1767831892@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --iyprHr6gT7UrymdC Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Jan 07, 2026 at 07:24:52PM -0500, Tom Lane wrote: > Nathan Bossart writes: >> On Wed, Jan 07, 2026 at 06:13:48PM -0500, Tom Lane wrote: >>> That would be a fine argument were it not that collectSequences() >>> tries to vacuum up the data for every sequence in the DB, whether >>> the user has asked to dump them all or not. > >> I meant that we could teach pg_dump to error in dumpSequenceData() if it >> sees nulls for the sequence in question. > > Ah, gotcha; I thought you were talking about changing > pg_get_sequence_data() to throw an error instead of returning nulls. Here is a patch that does this along with what you described upthread, i.e., teaching pg_get_sequence_data to return nulls for missing sequences. Apparently pg_dump still runs through dumpSequenceData() for schema-only dumps, which is a problem for this patch. I've taught it to immediately return for schema-only dumps to evade this problem. That seems like a win for older versions, too, as they will no longer run useless queries. I believe this helps the reporter's case, as their problem involves dumping one schema while dropping another, which v18 indeed makes worse because (as you mentioned) we gather data for all sequences in the database. -- nathan --iyprHr6gT7UrymdC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0001-pg_dump-fix-use-of-pg_get_sequence_data.patch From aeabbd9b6e336d086941eb89f2b4983b58c5881e Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 8 Jan 2026 11:29:59 -0600 Subject: [PATCH v1 1/1] pg_dump: fix use of pg_get_sequence_data --- src/backend/access/sequence/sequence.c | 20 ++++++++++++++++++++ src/backend/commands/sequence.c | 14 ++++++++------ src/bin/pg_dump/pg_dump.c | 10 ++++++++++ src/include/access/sequence.h | 1 + 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/backend/access/sequence/sequence.c b/src/backend/access/sequence/sequence.c index 106af1477e9..6f21f49a520 100644 --- a/src/backend/access/sequence/sequence.c +++ b/src/backend/access/sequence/sequence.c @@ -45,6 +45,26 @@ sequence_open(Oid relationId, LOCKMODE lockmode) return r; } +/* ---------------- + * try_sequence_open - open a sequence relation by relation OID + * + * Same as sequence_open, except return NULL instead of failing if the + * relation does not exist. + * ---------------- + */ +Relation +try_sequence_open(Oid relationId, LOCKMODE lockmode) +{ + Relation r; + + r = try_relation_open(relationId, lockmode); + + if (r) + validate_relation_kind(r); + + return r; +} + /* ---------------- * sequence_close - close a sequence * diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 904eeada5ab..e3202dfe951 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_sequence_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 && + 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) + sequence_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; } diff --git a/src/include/access/sequence.h b/src/include/access/sequence.h index cbe93775b1b..42f199003b4 100644 --- a/src/include/access/sequence.h +++ b/src/include/access/sequence.h @@ -18,6 +18,7 @@ #include "utils/relcache.h" extern Relation sequence_open(Oid relationId, LOCKMODE lockmode); +extern Relation try_sequence_open(Oid relationId, LOCKMODE lockmode); extern void sequence_close(Relation relation, LOCKMODE lockmode); #endif /* ACCESS_SEQUENCE_H */ -- 2.39.5 (Apple Git-154) --iyprHr6gT7UrymdC--