aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2021-08-31 13:53:33 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2021-08-31 13:53:49 -0400
commit6c450a861f1a928f44c9ae80814ed9a91927c25a (patch)
treecf723a95772774e1b1739a29498ca8f8eed19794
parent628bc9d13be8c55492aef122c25dbba3b036366d (diff)
downloadpostgresql-6c450a861f1a928f44c9ae80814ed9a91927c25a.tar.gz
postgresql-6c450a861f1a928f44c9ae80814ed9a91927c25a.zip
Cache the results of format_type() queries in pg_dump.
There's long been a "TODO: there might be some value in caching the results" annotation on pg_dump's getFormattedTypeName function; but we hadn't gotten around to checking what it was costing us to repetitively look up type names. It turns out that when dumping the current regression database, about 10% of the total number of queries issued are duplicative format_type() queries. However, Hubert Depesz Lubaczewski reported a not-unusual case where these account for over half of the queries issued by pg_dump. Individually these queries aren't expensive, but when network lag is a factor, they add up to a problem. We can very easily add some caching to getFormattedTypeName to solve it. Since this is such a simple fix and can have a visible performance benefit, back-patch to all supported branches. Discussion: https://postgr.es/m/20210826084430.GA26282@depesz.com
-rw-r--r--src/bin/pg_dump/pg_dump.c13
-rw-r--r--src/bin/pg_dump/pg_dump.h6
2 files changed, 15 insertions, 4 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 6adbd20778d..6259e68aa4b 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -5232,6 +5232,7 @@ getTypes(Archive *fout, int *numTypes)
tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
tyinfo[i].dobj.namespace =
findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
+ tyinfo[i].ftypname = NULL; /* may get filled later */
tyinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
tyinfo[i].typacl = pg_strdup(PQgetvalue(res, i, i_typacl));
tyinfo[i].rtypacl = pg_strdup(PQgetvalue(res, i, i_rtypacl));
@@ -18892,12 +18893,11 @@ findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
*
* This does not guarantee to schema-qualify the output, so it should not
* be used to create the target object name for CREATE or ALTER commands.
- *
- * TODO: there might be some value in caching the results.
*/
static char *
getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
{
+ TypeInfo *typeInfo;
char *result;
PQExpBuffer query;
PGresult *res;
@@ -18910,6 +18910,11 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
return pg_strdup("NONE");
}
+ /* see if we have the result cached in the type's TypeInfo record */
+ typeInfo = findTypeByOid(oid);
+ if (typeInfo && typeInfo->ftypname)
+ return pg_strdup(typeInfo->ftypname);
+
query = createPQExpBuffer();
appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
oid);
@@ -18922,6 +18927,10 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
PQclear(res);
destroyPQExpBuffer(query);
+ /* cache a copy for later requests */
+ if (typeInfo)
+ typeInfo->ftypname = pg_strdup(result);
+
return result;
}
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index f5e170e0dbc..29af845ece6 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -166,9 +166,11 @@ typedef struct _typeInfo
DumpableObject dobj;
/*
- * Note: dobj.name is the pg_type.typname entry. format_type() might
- * produce something different than typname
+ * Note: dobj.name is the raw pg_type.typname entry. ftypname is the
+ * result of format_type(), which will be quoted if needed, and might be
+ * schema-qualified too.
*/
+ char *ftypname;
char *rolname; /* name of owner, or empty string */
char *typacl;
char *rtypacl;