Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Defer restoration of libraries in parallel workers.
authorThomas Munro <tmunro@postgresql.org>
Thu, 20 Sep 2018 02:02:40 +0000 (14:02 +1200)
committerThomas Munro <tmunro@postgresql.org>
Thu, 20 Sep 2018 02:21:18 +0000 (14:21 +1200)
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

index c1681184670de99ccd81a552001a732d699d67a2..cdaa32e29a487281e91d6068dda4c750fdadb89a 100644 (file)
@@ -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();