Re: optimizing pg_upgrade's once-in-each-database steps
Nathan Bossart <nathandbossart@gmail.com>
On Wed, Jul 17, 2024 at 11:16:59PM +0200, Daniel Gustafsson wrote:
> First reaction after a read-through is that this seems really cool, can't wait
> to see how much v18 pg_upgrade will be over v17. I will do more testing and
> review once back from vacation, below are some comments from reading which is
> all I had time for at this point:
Thanks for taking a look!
> +static void
> +conn_failure(PGconn *conn)
> +{
> + pg_log(PG_REPORT, "%s", PQerrorMessage(conn));
> + printf(_("Failure, exiting\n"));
> + exit(1);
> +}
>
> Any particular reason this isn't using pg_fatal()?
IIRC this was to match the error in connectToServer(). We could probably
move to pg_fatal().
> +static void
> +dispatch_query(const ClusterInfo *cluster, AsyncSlot *slot,
> ....
> + pg_free(query);
> +}
>
> A minor point, perhaps fueled by me not having played around much with this
> patchset. It seems a bit odd that dispatch_query is responsible for freeing
> the query from the get_query callback. I would have expected the output from
> AsyncTaskGetQueryCB to be stored in AsyncTask and released by async_task_free.
I don't see any problem with doing it the way you suggest.
Tangentially related, I waffled a bit on whether to require the query
callbacks to put the result in allocated memory. Some queries are the same
no matter what, and some require customization at runtime. As you can see,
I ended up just requiring allocated memory. That makes the code a tad
simpler, and I doubt the extra work is noticeable.
> +static void
> +sub_process(DbInfo *dbinfo, PGresult *res, void *arg)
> +{
> ....
> + fprintf(state->script, "The table sync state \"%s\" is not allowed for database:\"%s\" subscription:\"%s\" schema:\"%s\" relation:\"%s\"\n",
> + PQgetvalue(res, i, 0),
> + dbinfo->db_name,
> + PQgetvalue(res, i, 1),
>
> With the query being in a separate place in the code from the processing it
> takes a bit of jumping around to resolve the columns in PQgetvalue calls like
> this. Using PQfnumber() calls and descriptive names would make this easier. I
> know this case is copying old behavior, but the function splits make it less
> useful than before.
Good point.
> + char *query = pg_malloc(QUERY_ALLOC);
>
> Should we convert this to a PQExpBuffer?
Seems like a good idea. I think I was trying to change as few lines as
possible for my proof-of-concept. :)
--
nathan
Commits
-
Introduce framework for parallelizing various pg_upgrade tasks.
- 40e2e5e92b7d 18.0 landed
-
pg_upgrade: Parallelize WITH OIDS check.
- f93f5f7b984e 18.0 landed
-
pg_upgrade: Parallelize contrib/isn check.
- 9db3018cf83b 18.0 landed
-
pg_upgrade: Parallelize data type checks.
- bbf83cab98f2 18.0 landed
-
pg_upgrade: Parallelize encoding conversion check.
- c880cf258864 18.0 landed
-
pg_upgrade: Parallelize incompatible polymorphics check.
- cf2f82a37cc3 18.0 landed
-
pg_upgrade: Parallelize postfix operator check.
- c34eabfbbfd3 18.0 landed
-
pg_upgrade: Parallelize retrieving extension updates.
- 6ab8f27bc716 18.0 landed
-
pg_upgrade: Parallelize retrieving loadable libraries.
- 46cad8b31927 18.0 landed
-
pg_upgrade: Parallelize retrieving relation information.
- 6d3d2e8e541f 18.0 landed
-
pg_upgrade: Parallelize subscription check.
- 7baa36de58bd 18.0 landed
-
pg_upgrade: Move live_check variable to user_opts.
- 4b56bb4ab485 18.0 landed
-
pg_upgrade: run all data type checks per connection
- 347758b12063 17.0 cited