Skip to content

Commit 6c450a8

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 628bc9d commit 6c450a8

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
@@ -5232,6 +5232,7 @@ getTypes(Archive *fout, int *numTypes)
52325232
tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
52335233
tyinfo[i].dobj.namespace =
52345234
findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
5235+
tyinfo[i].ftypname = NULL; /* may get filled later */
52355236
tyinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
52365237
tyinfo[i].typacl = pg_strdup(PQgetvalue(res, i, i_typacl));
52375238
tyinfo[i].rtypacl = pg_strdup(PQgetvalue(res, i, i_rtypacl));
@@ -18892,12 +18893,11 @@ findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
1889218893
*
1889318894
* This does not guarantee to schema-qualify the output, so it should not
1889418895
* be used to create the target object name for CREATE or ALTER commands.
18895-
*
18896-
* TODO: there might be some value in caching the results.
1889718896
*/
1889818897
static char *
1889918898
getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1890018899
{
18900+
TypeInfo *typeInfo;
1890118901
char *result;
1890218902
PQExpBuffer query;
1890318903
PGresult *res;
@@ -18910,6 +18910,11 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1891018910
return pg_strdup("NONE");
1891118911
}
1891218912

18913+
/* see if we have the result cached in the type's TypeInfo record */
18914+
typeInfo = findTypeByOid(oid);
18915+
if (typeInfo && typeInfo->ftypname)
18916+
return pg_strdup(typeInfo->ftypname);
18917+
1891318918
query = createPQExpBuffer();
1891418919
appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
1891518920
oid);
@@ -18922,6 +18927,10 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
1892218927
PQclear(res);
1892318928
destroyPQExpBuffer(query);
1892418929

18930+
/* cache a copy for later requests */
18931+
if (typeInfo)
18932+
typeInfo->ftypname = pg_strdup(result);
18933+
1892518934
return result;
1892618935
}
1892718936

src/bin/pg_dump/pg_dump.h

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

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

0 commit comments

Comments
 (0)