Skip to content

Commit 9407dbb

Browse files
committed
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
1 parent 4090ff2 commit 9407dbb

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5206,6 +5206,7 @@ getTypes(Archive *fout, int *numTypes)
52065206
tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
52075207
tyinfo[i].dobj.namespace =
52085208
findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
5209+
tyinfo[i].ftypname = NULL; /* may get filled later */
52095210
tyinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
52105211
tyinfo[i].typacl = pg_strdup(PQgetvalue(res, i, i_typacl));
52115212
tyinfo[i].rtypacl = pg_strdup(PQgetvalue(res, i, i_rtypacl));
@@ -18761,12 +18762,11 @@ findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
1876118762
*
1876218763
* This does not guarantee to schema-qualify the output, so it should not
1876318764
* be used to create the target object name for CREATE or ALTER commands.
18764-
*
18765-
* TODO: there might be some value in caching the results.
1876618765
*/
1876718766
static char *
1876818767
getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1876918768
{
18769+
TypeInfo *typeInfo;
1877018770
char *result;
1877118771
PQExpBuffer query;
1877218772
PGresult *res;
@@ -18779,6 +18779,11 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1877918779
return pg_strdup("NONE");
1878018780
}
1878118781

18782+
/* see if we have the result cached in the type's TypeInfo record */
18783+
typeInfo = findTypeByOid(oid);
18784+
if (typeInfo && typeInfo->ftypname)
18785+
return pg_strdup(typeInfo->ftypname);
18786+
1878218787
query = createPQExpBuffer();
1878318788
appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
1878418789
oid);
@@ -18791,6 +18796,10 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1879118796
PQclear(res);
1879218797
destroyPQExpBuffer(query);
1879318798

18799+
/* cache a copy for later requests */
18800+
if (typeInfo)
18801+
typeInfo->ftypname = pg_strdup(result);
18802+
1879418803
return result;
1879518804
}
1879618805

src/bin/pg_dump/pg_dump.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,11 @@ typedef struct _typeInfo
164164
DumpableObject dobj;
165165

166166
/*
167-
* Note: dobj.name is the pg_type.typname entry. format_type() might
168-
* produce something different than typname
167+
* Note: dobj.name is the raw pg_type.typname entry. ftypname is the
168+
* result of format_type(), which will be quoted if needed, and might be
169+
* schema-qualified too.
169170
*/
171+
char *ftypname;
170172
char *rolname; /* name of owner, or empty string */
171173
char *typacl;
172174
char *rtypacl;

0 commit comments

Comments
 (0)