Cache typarray for fast lookups in binary upgrade mode

When upgrading a large schema it adds significant overhead to perform
individual catalog lookups per relation in order to retrieve Oid for
preserving Oid calls. This instead adds the typarray to the TypeInfo
cache which then allows for fast lookups using the existing API. A
35% reduction of pg_dump runtime in binary upgrade mode was observed
with this change.

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://postgr.es/m/8F1F1E1D-D17B-4B33-B014-EDBCD15F3F0B@yesql.se
This commit is contained in:
Daniel Gustafsson 2024-09-02 10:17:46 +02:00
parent 4d5111b3f1
commit 6ebeeae296
2 changed files with 9 additions and 12 deletions

View File

@ -5412,23 +5412,15 @@ binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
Oid pg_type_array_oid;
Oid pg_type_multirange_oid;
Oid pg_type_multirange_array_oid;
TypeInfo *tinfo;
appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
appendPQExpBuffer(upgrade_buffer,
"SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
pg_type_oid);
appendPQExpBuffer(upgrade_query,
"SELECT typarray "
"FROM pg_catalog.pg_type "
"WHERE oid = '%u'::pg_catalog.oid;",
pg_type_oid);
res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
pg_type_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
PQclear(res);
tinfo = findTypeByOid(pg_type_oid);
pg_type_array_oid = tinfo->typarray;
if (!OidIsValid(pg_type_array_oid) && force_array_type)
pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
@ -5910,6 +5902,7 @@ getTypes(Archive *fout)
int i_typtype;
int i_typisdefined;
int i_isarray;
int i_typarray;
/*
* we include even the built-in types because those may be used as array
@ -5930,7 +5923,7 @@ getTypes(Archive *fout)
"typnamespace, typacl, "
"acldefault('T', typowner) AS acldefault, "
"typowner, "
"typelem, typrelid, "
"typelem, typrelid, typarray, "
"CASE WHEN typrelid = 0 THEN ' '::\"char\" "
"ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
"typtype, typisdefined, "
@ -5957,6 +5950,7 @@ getTypes(Archive *fout)
i_typtype = PQfnumber(res, "typtype");
i_typisdefined = PQfnumber(res, "typisdefined");
i_isarray = PQfnumber(res, "isarray");
i_typarray = PQfnumber(res, "typarray");
for (i = 0; i < ntups; i++)
{
@ -5989,6 +5983,8 @@ getTypes(Archive *fout)
else
tyinfo[i].isArray = false;
tyinfo[i].typarray = atooid(PQgetvalue(res, i, i_typarray));
if (tyinfo[i].typtype == TYPTYPE_MULTIRANGE)
tyinfo[i].isMultirange = true;
else

View File

@ -200,6 +200,7 @@ typedef struct _typeInfo
const char *rolname;
Oid typelem;
Oid typrelid;
Oid typarray;
char typrelkind; /* 'r', 'v', 'c', etc */
char typtype; /* 'b', 'c', etc */
bool isArray; /* true if auto-generated array type */