From de4fe83c7e6d14d996babec814c4fc12490889ef Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Thu, 20 Sep 2018 14:02:40 +1200 Subject: [PATCH] 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 --- src/backend/access/transam/parallel.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index 9de5239524..82b2f3e146 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -1148,15 +1148,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); - Assert(libraryspace != NULL); - 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 @@ -1186,10 +1177,19 @@ 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); + Assert(libraryspace != NULL); + StartTransactionCommand(); + RestoreLibraryState(libraryspace); + /* Restore GUC values from launching backend. */ gucspace = shm_toc_lookup(toc, PARALLEL_KEY_GUC); Assert(gucspace != NULL); - StartTransactionCommand(); RestoreGUCState(gucspace); CommitTransactionCommand();