From 9ce7f29c424595b36e455dbb927535f10845a716 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Thu, 30 Aug 2018 10:21:41 +1200 Subject: [PATCH 2/2] Defer restoration of libraries in parallel workers. Several users of extensions complained of crashes in parallel workers, which turned out to be due to syscache access from their _PG_init() functions. While it's not clear that we really want to encourage that (for one thing, it means you can't load the extension via shared_preload_libraries), it's a fairly obscure hazard that several extensions are apparently running into, and it worked in practice before parallelism came along. An alternative would be to make all such extensions fail to initialize even in regular backends so that authors are quickly made aware, but that seems a little unfriendly. Reorder the initialization of parallel workers so that libraries are restored after the caches are initialized, and inside a transaction. Author: Thomas Munro Bug: #15350 Reported-by: Kieran McCusker, Jimmy Reviewed-by: Discussion: https://postgr.es/m/153512195228.1489.8545997741965926448%40wrigleys.postgresql.org --- src/backend/access/transam/parallel.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index c168118467..cdaa32e29a 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -1311,14 +1311,6 @@ ParallelWorkerMain(Datum main_arg) fps->parallel_master_pid)) 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 * loading an additional library, though most likely the entry point is in @@ -1341,9 +1333,17 @@ ParallelWorkerMain(Datum main_arg) */ 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. */ gucspace = shm_toc_lookup(toc, PARALLEL_KEY_GUC, false); - StartTransactionCommand(); RestoreGUCState(gucspace); CommitTransactionCommand(); -- 2.17.0