summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-03-31 14:42:33 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-03-31 14:42:33 -0400
commit80c40f07eb31aa70d245a25b4a5b9ad1d010c431 (patch)
tree4c40d9c85b2e779a4a5fbbe9aca2e5bd95d99ade
parent19ab40fd468b78ef8e6e4e9db6e515d2232faefc (diff)
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.
-rw-r--r--src/bin/pg_dump/common.c3
-rw-r--r--src/bin/pg_dump/pg_dump.c41
-rw-r--r--src/bin/pg_dump/pg_dump.h1
3 files changed, 27 insertions, 18 deletions
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index fd8709f1d59..04379e39c44 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -124,6 +124,9 @@ getSchemaData(int *numTablesPtr)
tblinfo = getTables(&numTables);
tblinfoindex = buildIndexArray(tblinfo, numTables, sizeof(TableInfo));
+ /* Do this after we've built tblinfoindex */
+ getOwnedSeqs(tblinfo, numTables);
+
if (g_verbose)
write_msg(NULL, "reading user-defined functions\n");
funinfo = getFuncs(&numFuncs);
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 11764ce6bee..0981fbd4117 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -3585,38 +3585,43 @@ getTables(int *numTables)
PQclear(res);
+ destroyPQExpBuffer(query);
+
+ return tblinfo;
+}
+
+/*
+ * getOwnedSeqs
+ * identify owned sequences and mark them as dumpable if owning table is
+ *
+ * We used to do this in getTables(), but it's better to do it after the
+ * index used by findTableByOid() has been set up.
+ */
+void
+getOwnedSeqs(TableInfo tblinfo[], int numTables)
+{
+ int i;
+
/*
* Force sequences that are "owned" by table columns to be dumped whenever
* their owning table is being dumped.
*/
- for (i = 0; i < ntups; i++)
+ for (i = 0; i < numTables; i++)
{
TableInfo *seqinfo = &tblinfo[i];
- int j;
+ TableInfo *owning_tab;
if (!OidIsValid(seqinfo->owning_tab))
continue; /* not an owned sequence */
if (seqinfo->dobj.dump)
continue; /* no need to search */
-
- /* can't use findTableByOid yet, unfortunately */
- for (j = 0; j < ntups; j++)
+ owning_tab = findTableByOid(seqinfo->owning_tab);
+ if (owning_tab && owning_tab->dobj.dump)
{
- if (tblinfo[j].dobj.catId.oid == seqinfo->owning_tab)
- {
- if (tblinfo[j].dobj.dump)
- {
- seqinfo->interesting = true;
- seqinfo->dobj.dump = true;
- }
- break;
- }
+ seqinfo->interesting = true;
+ seqinfo->dobj.dump = true;
}
}
-
- destroyPQExpBuffer(query);
-
- return tblinfo;
}
/*
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 64e73b6e8ef..017c04a48ae 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -489,6 +489,7 @@ extern OpclassInfo *getOpclasses(int *numOpclasses);
extern OpfamilyInfo *getOpfamilies(int *numOpfamilies);
extern ConvInfo *getConversions(int *numConversions);
extern TableInfo *getTables(int *numTables);
+extern void getOwnedSeqs(TableInfo tblinfo[], int numTables);
extern InhInfo *getInherits(int *numInherits);
extern void getIndexes(TableInfo tblinfo[], int numTables);
extern void getConstraints(TableInfo tblinfo[], int numTables);