From 9c64682938929eb7da0d901213471c14b7fb0227 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 8 Jul 2024 21:52:13 -0500 Subject: [PATCH v4 12/12] parallelize user defined encoding conversions check in pg_upgrade --- src/bin/pg_upgrade/check.c | 107 ++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 639a62d426..b20651c851 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -1654,15 +1654,66 @@ check_for_pg_role_prefix(ClusterInfo *cluster) check_ok(); } +static char * +user_defined_encoding_conversions_query(DbInfo *dbinfo, void *arg) +{ + /* + * The query below hardcodes FirstNormalObjectId as 16384 rather than + * interpolating that C #define into the query because, if that #define is + * ever changed, the cutoff we want to use is the value used by + * pre-version 14 servers, not that of some future version. + */ + return pstrdup("SELECT c.oid as conoid, c.conname, n.nspname " + "FROM pg_catalog.pg_conversion c, " + " pg_catalog.pg_namespace n " + "WHERE c.connamespace = n.oid AND " + " c.oid >= 16384"); +} + +static void +user_defined_encoding_conversions_process(DbInfo *dbinfo, PGresult *res, void *arg) +{ + FILE **script = (FILE **) arg; + bool db_used = false; + int ntups = PQntuples(res); + char output_path[MAXPGPATH]; + int i_conoid = PQfnumber(res, "conoid"); + int i_conname = PQfnumber(res, "conname"); + int i_nspname = PQfnumber(res, "nspname"); + + if (!ntups) + return; + + snprintf(output_path, sizeof(output_path), "%s/%s", + log_opts.basedir, + "encoding_conversions.txt"); + + for (int rowno = 0; rowno < ntups; rowno++) + { + if (*script == NULL && + (*script = fopen_priv(output_path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %m", output_path); + if (!db_used) + { + fprintf(*script, "In database: %s\n", dbinfo->db_name); + db_used = true; + } + fprintf(*script, " (oid=%s) %s.%s\n", + PQgetvalue(res, rowno, i_conoid), + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_conname)); + } +} + /* * Verify that no user-defined encoding conversions exist. */ static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster) { - int dbnum; FILE *script = NULL; char output_path[MAXPGPATH]; + AsyncTask *task = async_task_create(); prep_status("Checking for user-defined encoding conversions"); @@ -1670,55 +1721,11 @@ check_for_user_defined_encoding_conversions(ClusterInfo *cluster) log_opts.basedir, "encoding_conversions.txt"); - /* Find any user defined encoding conversions */ - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - int ntups; - int rowno; - int i_conoid, - i_conname, - i_nspname; - DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(cluster, active_db->db_name); - - /* - * The query below hardcodes FirstNormalObjectId as 16384 rather than - * interpolating that C #define into the query because, if that - * #define is ever changed, the cutoff we want to use is the value - * used by pre-version 14 servers, not that of some future version. - */ - res = executeQueryOrDie(conn, - "SELECT c.oid as conoid, c.conname, n.nspname " - "FROM pg_catalog.pg_conversion c, " - " pg_catalog.pg_namespace n " - "WHERE c.connamespace = n.oid AND " - " c.oid >= 16384"); - ntups = PQntuples(res); - i_conoid = PQfnumber(res, "conoid"); - i_conname = PQfnumber(res, "conname"); - i_nspname = PQfnumber(res, "nspname"); - for (rowno = 0; rowno < ntups; rowno++) - { - if (script == NULL && - (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("could not open file \"%s\": %m", output_path); - if (!db_used) - { - fprintf(script, "In database: %s\n", active_db->db_name); - db_used = true; - } - fprintf(script, " (oid=%s) %s.%s\n", - PQgetvalue(res, rowno, i_conoid), - PQgetvalue(res, rowno, i_nspname), - PQgetvalue(res, rowno, i_conname)); - } - - PQclear(res); - - PQfinish(conn); - } + async_task_add_step(task, user_defined_encoding_conversions_query, + user_defined_encoding_conversions_process, true, + &script); + async_task_run(task, cluster); + async_task_free(task); if (script) { -- 2.39.3 (Apple Git-146)