Commit 6c3c9d41 authored by Thomas Munro's avatar Thomas Munro

Defer restoration of libraries in parallel workers.

Several users of extensions complained of crashes in parallel workers
that turned out to be due to syscache access from their _PG_init()
functions.  Reorder the initialization of parallel workers so that
libraries are restored after the caches are initialized, and inside a
transaction.

This was reported in bug #15350 and elsewhere.  We don't consider it
to be a bug: extensions shouldn't do that, because then they can't be
used in shared_preload_libraries.  However, it's a fairly obscure
hazard and these extensions worked in practice before parallel query
came along.  So let's make it work.  Later commits might add a warning
message and eventually an error.

Back-patch to 9.6, where parallel query landed.

Author: Thomas Munro
Reviewed-by: Amit Kapila
Reported-by: Kieran McCusker, Jimmy
Discussion: https://postgr.es/m/153512195228.1489.8545997741965926448%40wrigleys.postgresql.org
parent 40cfe860
...@@ -1311,14 +1311,6 @@ ParallelWorkerMain(Datum main_arg) ...@@ -1311,14 +1311,6 @@ ParallelWorkerMain(Datum main_arg)
fps->parallel_master_pid)) fps->parallel_master_pid))
return; return;
/*
* Load libraries that were loaded by original backend. We want to do
* this before restoring GUCs, because the libraries might define custom
* variables.
*/
libraryspace = shm_toc_lookup(toc, PARALLEL_KEY_LIBRARY, false);
RestoreLibraryState(libraryspace);
/* /*
* Identify the entry point to be called. In theory this could result in * Identify the entry point to be called. In theory this could result in
* loading an additional library, though most likely the entry point is in * loading an additional library, though most likely the entry point is in
...@@ -1341,9 +1333,17 @@ ParallelWorkerMain(Datum main_arg) ...@@ -1341,9 +1333,17 @@ ParallelWorkerMain(Datum main_arg)
*/ */
SetClientEncoding(GetDatabaseEncoding()); SetClientEncoding(GetDatabaseEncoding());
/*
* Load libraries that were loaded by original backend. We want to do
* this before restoring GUCs, because the libraries might define custom
* variables.
*/
libraryspace = shm_toc_lookup(toc, PARALLEL_KEY_LIBRARY, false);
StartTransactionCommand();
RestoreLibraryState(libraryspace);
/* Restore GUC values from launching backend. */ /* Restore GUC values from launching backend. */
gucspace = shm_toc_lookup(toc, PARALLEL_KEY_GUC, false); gucspace = shm_toc_lookup(toc, PARALLEL_KEY_GUC, false);
StartTransactionCommand();
RestoreGUCState(gucspace); RestoreGUCState(gucspace);
CommitTransactionCommand(); CommitTransactionCommand();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment