Skip to content

Commit 80c40f0

Browse files
committed
Fix O(N^2) behavior in pg_dump for large numbers of owned sequences.
The loop that matched owned sequences to their owning tables required time proportional to number of owned sequences times number of tables; although this work was only expended in selective-dump situations, which is probably why the issue wasn't recognized long since. Refactor slightly so that we can perform this work after the index array for findTableByOid has been set up, reducing the time to O(M log N). Per gripe from Mike Roest. Since this is a longstanding performance bug, backpatch to all supported versions.
1 parent 19ab40f commit 80c40f0

File tree

3 files changed

+27
-18
lines changed

3 files changed

+27
-18
lines changed

src/bin/pg_dump/common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ getSchemaData(int *numTablesPtr)
124124
tblinfo = getTables(&numTables);
125125
tblinfoindex = buildIndexArray(tblinfo, numTables, sizeof(TableInfo));
126126

127+
/* Do this after we've built tblinfoindex */
128+
getOwnedSeqs(tblinfo, numTables);
129+
127130
if (g_verbose)
128131
write_msg(NULL, "reading user-defined functions\n");
129132
funinfo = getFuncs(&numFuncs);

src/bin/pg_dump/pg_dump.c

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3585,38 +3585,43 @@ getTables(int *numTables)
35853585

35863586
PQclear(res);
35873587

3588+
destroyPQExpBuffer(query);
3589+
3590+
return tblinfo;
3591+
}
3592+
3593+
/*
3594+
* getOwnedSeqs
3595+
* identify owned sequences and mark them as dumpable if owning table is
3596+
*
3597+
* We used to do this in getTables(), but it's better to do it after the
3598+
* index used by findTableByOid() has been set up.
3599+
*/
3600+
void
3601+
getOwnedSeqs(TableInfo tblinfo[], int numTables)
3602+
{
3603+
int i;
3604+
35883605
/*
35893606
* Force sequences that are "owned" by table columns to be dumped whenever
35903607
* their owning table is being dumped.
35913608
*/
3592-
for (i = 0; i < ntups; i++)
3609+
for (i = 0; i < numTables; i++)
35933610
{
35943611
TableInfo *seqinfo = &tblinfo[i];
3595-
int j;
3612+
TableInfo *owning_tab;
35963613

35973614
if (!OidIsValid(seqinfo->owning_tab))
35983615
continue; /* not an owned sequence */
35993616
if (seqinfo->dobj.dump)
36003617
continue; /* no need to search */
3601-
3602-
/* can't use findTableByOid yet, unfortunately */
3603-
for (j = 0; j < ntups; j++)
3618+
owning_tab = findTableByOid(seqinfo->owning_tab);
3619+
if (owning_tab && owning_tab->dobj.dump)
36043620
{
3605-
if (tblinfo[j].dobj.catId.oid == seqinfo->owning_tab)
3606-
{
3607-
if (tblinfo[j].dobj.dump)
3608-
{
3609-
seqinfo->interesting = true;
3610-
seqinfo->dobj.dump = true;
3611-
}
3612-
break;
3613-
}
3621+
seqinfo->interesting = true;
3622+
seqinfo->dobj.dump = true;
36143623
}
36153624
}
3616-
3617-
destroyPQExpBuffer(query);
3618-
3619-
return tblinfo;
36203625
}
36213626

36223627
/*

src/bin/pg_dump/pg_dump.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ extern OpclassInfo *getOpclasses(int *numOpclasses);
489489
extern OpfamilyInfo *getOpfamilies(int *numOpfamilies);
490490
extern ConvInfo *getConversions(int *numConversions);
491491
extern TableInfo *getTables(int *numTables);
492+
extern void getOwnedSeqs(TableInfo tblinfo[], int numTables);
492493
extern InhInfo *getInherits(int *numInherits);
493494
extern void getIndexes(TableInfo tblinfo[], int numTables);
494495
extern void getConstraints(TableInfo tblinfo[], int numTables);

0 commit comments

Comments
 (0)