]> granicus.if.org Git - postgresql/commitdiff
Allow background workers to bypass datallowconn
authorMagnus Hagander <magnus@hagander.net>
Thu, 5 Apr 2018 16:59:32 +0000 (18:59 +0200)
committerMagnus Hagander <magnus@hagander.net>
Thu, 5 Apr 2018 17:02:45 +0000 (19:02 +0200)
THis adds a "flags" field to the BackgroundWorkerInitializeConnection()
and BackgroundWorkerInitializeConnectionByOid(). For now only one flag,
BGWORKER_BYPASS_ALLOWCONN, is defined, which allows the worker to ignore
datallowconn.

contrib/pg_prewarm/autoprewarm.c
src/backend/access/transam/parallel.c
src/backend/bootstrap/bootstrap.c
src/backend/postmaster/autovacuum.c
src/backend/postmaster/postmaster.c
src/backend/replication/logical/launcher.c
src/backend/replication/logical/worker.c
src/backend/tcop/postgres.c
src/backend/utils/init/postinit.c
src/include/miscadmin.h
src/include/postmaster/bgworker.h

index f99f9c07af3e8033e1bc8e33c3aa4fbd45b67d7c..bb28e237d173441c5c01a3cbe5e259e3bada854f 100644 (file)
@@ -445,7 +445,7 @@ autoprewarm_database_main(Datum main_arg)
                ereport(ERROR,
                                (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
                                 errmsg("could not map dynamic shared memory segment")));
-       BackgroundWorkerInitializeConnectionByOid(apw_state->database, InvalidOid);
+       BackgroundWorkerInitializeConnectionByOid(apw_state->database, InvalidOid, 0);
        block_info = (BlockInfoRecord *) dsm_segment_address(seg);
        pos = apw_state->prewarm_start_idx;
 
index 9d4efc0f8fc0fc2b115c077b4d08828b1846b919..1d631b727552cf235e3f00303e5574ca9c8cb6f2 100644 (file)
@@ -1324,7 +1324,8 @@ ParallelWorkerMain(Datum main_arg)
 
        /* Restore database connection. */
        BackgroundWorkerInitializeConnectionByOid(fps->database_id,
-                                                                                         fps->authenticated_user_id);
+                                                                                         fps->authenticated_user_id,
+                                                                                         0);
 
        /*
         * Set the client encoding to the database encoding, since that is what
index 28ff2f0979817c81cb7e4943854c36fc59be42e2..1430894ad23a08eafae44b2a7a985719e3e7c2d8 100644 (file)
@@ -498,7 +498,7 @@ BootstrapModeMain(void)
         */
        InitProcess();
 
-       InitPostgres(NULL, InvalidOid, NULL, InvalidOid, NULL);
+       InitPostgres(NULL, InvalidOid, NULL, InvalidOid, NULL, false);
 
        /* Initialize stuff for bootstrap-file processing */
        for (i = 0; i < MAXATTR; i++)
index c4bc09ea810911ac9386984e5f3faf59315ea873..3b90b16daecd86022718fa54846815df2c9863f1 100644 (file)
@@ -477,7 +477,7 @@ AutoVacLauncherMain(int argc, char *argv[])
        InitProcess();
 #endif
 
-       InitPostgres(NULL, InvalidOid, NULL, InvalidOid, NULL);
+       InitPostgres(NULL, InvalidOid, NULL, InvalidOid, NULL, false);
 
        SetProcessingMode(NormalProcessing);
 
@@ -1693,7 +1693,7 @@ AutoVacWorkerMain(int argc, char *argv[])
                 * Note: if we have selected a just-deleted database (due to using
                 * stale stats info), we'll fail and exit here.
                 */
-               InitPostgres(NULL, dbid, NULL, InvalidOid, dbname);
+               InitPostgres(NULL, dbid, NULL, InvalidOid, dbname, false);
                SetProcessingMode(NormalProcessing);
                set_ps_display(dbname, false);
                ereport(DEBUG1,
index 660f3185e6bc8822de8bf350dfd6689cb087b7e5..3dfb87d7019073e4c6510bc910b1fefc26980633 100644 (file)
@@ -5582,7 +5582,7 @@ MaxLivePostmasterChildren(void)
  * Connect background worker to a database.
  */
 void
-BackgroundWorkerInitializeConnection(const char *dbname, const char *username)
+BackgroundWorkerInitializeConnection(const char *dbname, const char *username, uint32 flags)
 {
        BackgroundWorker *worker = MyBgworkerEntry;
 
@@ -5592,7 +5592,7 @@ BackgroundWorkerInitializeConnection(const char *dbname, const char *username)
                                (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                 errmsg("database connection requirement not indicated during registration")));
 
-       InitPostgres(dbname, InvalidOid, username, InvalidOid, NULL);
+       InitPostgres(dbname, InvalidOid, username, InvalidOid, NULL, (flags & BGWORKER_BYPASS_ALLOWCONN) != 0);
 
        /* it had better not gotten out of "init" mode yet */
        if (!IsInitProcessingMode())
@@ -5605,7 +5605,7 @@ BackgroundWorkerInitializeConnection(const char *dbname, const char *username)
  * Connect background worker to a database using OIDs.
  */
 void
-BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid)
+BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags)
 {
        BackgroundWorker *worker = MyBgworkerEntry;
 
@@ -5615,7 +5615,7 @@ BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid)
                                (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                 errmsg("database connection requirement not indicated during registration")));
 
-       InitPostgres(NULL, dboid, NULL, useroid, NULL);
+       InitPostgres(NULL, dboid, NULL, useroid, NULL, (flags & BGWORKER_BYPASS_ALLOWCONN) != 0);
 
        /* it had better not gotten out of "init" mode yet */
        if (!IsInitProcessingMode())
index 2da9129562afa40d97321d263ab4712a3edfd0e8..6ef333b7257e993ce842ca91d365ae556d95099c 100644 (file)
@@ -901,7 +901,7 @@ ApplyLauncherMain(Datum main_arg)
         * Establish connection to nailed catalogs (we only ever access
         * pg_subscription).
         */
-       BackgroundWorkerInitializeConnection(NULL, NULL);
+       BackgroundWorkerInitializeConnection(NULL, NULL, 0);
 
        /* Enter main loop */
        for (;;)
index fdace7eea2b12f2561f4a659a003fd476eb3a0ef..93a42d9322cd73a043726e348ff5b3172a6a3e04 100644 (file)
@@ -1544,7 +1544,8 @@ ApplyWorkerMain(Datum main_arg)
 
        /* Connect to our database. */
        BackgroundWorkerInitializeConnectionByOid(MyLogicalRepWorker->dbid,
-                                                                                         MyLogicalRepWorker->userid);
+                                                                                         MyLogicalRepWorker->userid,
+                                                                                         0);
 
        /* Load the subscription into persistent memory context. */
        ApplyContext = AllocSetContextCreate(TopMemoryContext,
index 6fc1cc272b572a756d1718626da2c1ed971924f1..7bdecc32ec0c648b4a8240fa1f6fc13d740a339c 100644 (file)
@@ -3775,7 +3775,7 @@ PostgresMain(int argc, char *argv[],
         * it inside InitPostgres() instead.  In particular, anything that
         * involves database access should be there, not here.
         */
-       InitPostgres(dbname, InvalidOid, username, InvalidOid, NULL);
+       InitPostgres(dbname, InvalidOid, username, InvalidOid, NULL, false);
 
        /*
         * If the PostmasterContext is still around, recycle the space; we don't
index d8f45b3c43f51912bea19cc06c726eb92e580b37..09e0df290dd46c4bc4e213b9eca76eb8429edfec 100644 (file)
@@ -66,7 +66,7 @@
 static HeapTuple GetDatabaseTuple(const char *dbname);
 static HeapTuple GetDatabaseTupleByOid(Oid dboid);
 static void PerformAuthentication(Port *port);
-static void CheckMyDatabase(const char *name, bool am_superuser);
+static void CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections);
 static void InitCommunication(void);
 static void ShutdownPostgres(int code, Datum arg);
 static void StatementTimeoutHandler(void);
@@ -290,7 +290,7 @@ PerformAuthentication(Port *port)
  * CheckMyDatabase -- fetch information from the pg_database entry for our DB
  */
 static void
-CheckMyDatabase(const char *name, bool am_superuser)
+CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections)
 {
        HeapTuple       tup;
        Form_pg_database dbform;
@@ -326,7 +326,7 @@ CheckMyDatabase(const char *name, bool am_superuser)
                /*
                 * Check that the database is currently allowing connections.
                 */
-               if (!dbform->datallowconn)
+               if (!dbform->datallowconn && !override_allow_connections)
                        ereport(FATAL,
                                        (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
                                         errmsg("database \"%s\" is not currently accepting connections",
@@ -563,7 +563,7 @@ BaseInit(void)
  */
 void
 InitPostgres(const char *in_dbname, Oid dboid, const char *username,
-                        Oid useroid, char *out_dbname)
+                        Oid useroid, char *out_dbname, bool override_allow_connections)
 {
        bool            bootstrap = IsBootstrapProcessingMode();
        bool            am_superuser;
@@ -1006,7 +1006,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
         * user is a superuser, so the above stuff has to happen first.)
         */
        if (!bootstrap)
-               CheckMyDatabase(dbname, am_superuser);
+               CheckMyDatabase(dbname, am_superuser, override_allow_connections);
 
        /*
         * Now process any command-line switches and any additional GUC variable
index a429a19964e38c8586be9fa38f69927a6da8c178..b5ad8419684afbec3e71985c2736c4c2d8a58ea4 100644 (file)
@@ -421,7 +421,7 @@ extern AuxProcType MyAuxProcType;
 extern void pg_split_opts(char **argv, int *argcp, const char *optstr);
 extern void InitializeMaxBackends(void);
 extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username,
-                        Oid useroid, char *out_dbname);
+                        Oid useroid, char *out_dbname, bool override_allow_connections);
 extern void BaseInit(void);
 
 /* in utils/init/miscinit.c */
index a8753df8d161cc5938d5a51e2e6ce077f75eb293..9c49bb7f4b09b3996a5b24dabce11df234b1fbc5 100644 (file)
@@ -140,10 +140,13 @@ extern PGDLLIMPORT BackgroundWorker *MyBgworkerEntry;
  * If dbname is NULL, connection is made to no specific database;
  * only shared catalogs can be accessed.
  */
-extern void BackgroundWorkerInitializeConnection(const char *dbname, const char *username);
+extern void BackgroundWorkerInitializeConnection(const char *dbname, const char *username, uint32 flags);
 
 /* Just like the above, but specifying database and user by OID. */
-extern void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid);
+extern void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags);
+
+/* Flags to BackgroundWorkerInitializeConnection et al */
+#define BGWORKER_BYPASS_ALLOWCONN 1
 
 /* Block/unblock signals in a background worker process */
 extern void BackgroundWorkerBlockSignals(void);