]> granicus.if.org Git - postgresql/commitdiff
Code review for superuser_reserved_connections patch. Don't try to do
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 21 Nov 2002 06:36:08 +0000 (06:36 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 21 Nov 2002 06:36:08 +0000 (06:36 +0000)
database access outside a transaction; revert bogus performance improvement
in SIBackendInit(); improve comments; add documentation (this part courtesy
Neil Conway).

doc/src/sgml/runtime.sgml
src/backend/postmaster/postmaster.c
src/backend/storage/ipc/sinval.c
src/backend/storage/ipc/sinvaladt.c
src/backend/utils/init/postinit.c

index 70b29118a22e8e160e00a14a887dcc48e5aa1bc8..7ecd951a3b97ef56688c4fd1496d5e0c729e777a 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.157 2002/11/21 00:42:18 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.158 2002/11/21 06:36:08 tgl Exp $
 -->
 
 <Chapter Id="runtime">
@@ -1902,6 +1902,28 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><varname>SUPERUSER_RESERVED_CONNECTIONS</varname>
+      (<type>integer</type>)</term>
+      <listitem>
+       <para>
+        Determines the number of <quote>connection slots</quote> that
+        are reserved for connections by <productname>PostgreSQL</>
+        superusers.  At most <varname>max_connections</> connections can
+       ever be active simultaneously.  Whenever the number of active
+       concurrent connections is at least <varname>max_connections</> minus
+        <varname>superuser_reserved_connections</varname>, new connections
+       will be accepted only from superuser accounts.
+       </para>
+
+       <para>
+        The default value is 2. The value must be less than the value of
+        <varname>max_connections</varname>. This parameter can only be
+        set at server start.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><varname>TCPIP_SOCKET</varname> (<type>boolean</type>)</term>
       <listitem>
@@ -2952,24 +2974,25 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
   </para>
 
   <para>
-   With SSL support compiled in, the <productname>PostgreSQL</> server
-   can be started with SSL support by setting the parameter
-   <varname>ssl</varname> to on in
-   <filename>postgresql.conf</filename>. When starting in SSL mode,
-   the server will look for the files <filename>server.key</> and
-   <filename>server.crt</> in the data directory.  These files should
-   contain the server private key and certificate respectively. These
-   files must be set up correctly before an SSL-enabled server can
-   start. If the private key is protected with a passphrase, the
-   server will prompt for the passphrase and will not start until it
-   has been entered.
+   With <acronym>SSL</> support compiled in, the
+   <productname>PostgreSQL</> server can be started with
+   <acronym>SSL</> support by setting the parameter
+   <varname>ssl</varname> to on in <filename>postgresql.conf</>. When
+   starting in <acronym>SSL</> mode, the server will look for the
+   files <filename>server.key</> and <filename>server.crt</> in the
+   data directory.  These files should contain the server private key
+   and certificate respectively. These files must be set up correctly
+   before an <acronym>SSL</>-enabled server can start. If the private key is
+   protected with a passphrase, the server will prompt for the
+   passphrase and will not start until it has been entered.
   </para>
 
   <para>
-   The server will listen for both standard and SSL connections on the
-   same TCP/IP port, and will negotiate with any connecting client on
-   whether to use SSL. See <xref linkend="client-authentication"> about
-   how to force the server to only use of SSL for certain connections.
+   The server will listen for both standard and <acronym>SSL</>
+   connections on the same TCP/IP port, and will negotiate with any
+   connecting client on whether to use <acronym>SSL</>. See <xref
+   linkend="client-authentication"> about how to force the server to
+   require use of <acronym>SSL</> for certain connections.
   </para>
 
   <para>
index 187f0191c94c104b4a2e6a53fd77617f998854f5..8f34a3fd2dcd5dd2cadbb7b6c49268431e6bc0e2 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.298 2002/11/18 00:40:46 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.299 2002/11/21 06:36:08 tgl Exp $
  *
  * NOTES
  *
@@ -154,12 +154,11 @@ int                       MaxBackends = DEF_MAXBACKENDS;
 /*
  * ReservedBackends is the number of backends reserved for superuser use.
  * This number is taken out of the pool size given by MaxBackends so
- * number of backend slots available to none super users is
- * (MaxBackends - ReservedBackends). Note, existing super user
- * connections are not taken into account once this lower limit has
- * been reached, i.e. superuser connections made before the lower limit
- * is reached always count towards that limit and are not taken from
- * ReservedBackends.
+ * number of backend slots available to non-superusers is
+ * (MaxBackends - ReservedBackends).  Note what this really means is
+ * "if there are <= ReservedBackends connections available, only superusers
+ * can make new connections" --- pre-existing superuser connections don't
+ * count against the limit.
  */
 int                    ReservedBackends = 2;
 
@@ -568,7 +567,15 @@ PostmasterMain(int argc, char *argv[])
        }
 
        /*
-        * Check for invalid combinations of switches
+        * Now we can set the data directory, and then read postgresql.conf.
+        */
+       checkDataDir(potential_DataDir);        /* issues error messages */
+       SetDataDir(potential_DataDir);
+
+       ProcessConfigFile(PGC_POSTMASTER);
+
+       /*
+        * Check for invalid combinations of GUC settings.
         */
        if (NBuffers < 2 * MaxBackends || NBuffers < 16)
        {
@@ -581,16 +588,11 @@ PostmasterMain(int argc, char *argv[])
                ExitPostmaster(1);
        }
 
-       checkDataDir(potential_DataDir);        /* issues error messages */
-       SetDataDir(potential_DataDir);
-
-       ProcessConfigFile(PGC_POSTMASTER);
-
-       /*
-        * Force an exit if ReservedBackends is not less than MaxBackends.
-        */
        if (ReservedBackends >= MaxBackends)
-               elog(FATAL, "superuser_reserved_connections must be less than max_connections.");
+       {
+               postmaster_error("superuser_reserved_connections must be less than max_connections.");
+               ExitPostmaster(1);
+       }
 
        /*
         * Now that we are done processing the postmaster arguments, reset
index 87f7a2924523f542608ac643473a5e2a929696bb..239c3bc8d30f26a6eeec1d08ef9016f5366177d2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.52 2002/09/04 20:31:25 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.53 2002/11/21 06:36:08 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -542,12 +542,11 @@ BackendIdGetProc(BackendId procId)
 /*
  * CountEmptyBackendSlots - count empty slots in backend process table
  *
- * Doesn't count since the procState array could be large and we've already
- * allowed for that by running a freeBackends counter in the SI segment.
- * Unlike CountActiveBackends() we do not need to interrogate the
- * backends to determine the free slot count.
- * Goes for a lock despite being a trival look up in case other backends
- * are busy starting or exiting since there is scope for confusion.
+ * We don't actually need to count, since sinvaladt.c maintains a
+ * freeBackends counter in the SI segment.
+ *
+ * Acquiring the lock here is almost certainly overkill, but just in
+ * case fetching an int is not atomic on your machine ...
  */
 int
 CountEmptyBackendSlots(void)
index b4ab1689f942de57ccdde5cc43c6b4cc0486265f..6850fa8cf52c504af1e5165d958d5d3ff4b23666 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.48 2002/08/29 21:02:12 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.49 2002/11/21 06:36:08 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -92,13 +92,6 @@ SIBackendInit(SISeg *segP)
        int                     index;
        ProcState  *stateP = NULL;
 
-       if (segP->freeBackends == 0)
-       {
-               /* out of procState slots */
-               MyBackendId = InvalidBackendId;
-               return 0;
-       }
-
        /* Look for a free entry in the procState array */
        for (index = 0; index < segP->lastBackend; index++)
        {
@@ -111,9 +104,18 @@ SIBackendInit(SISeg *segP)
 
        if (stateP == NULL)
        {
-               stateP = &segP->procState[segP->lastBackend];
-               Assert(stateP->nextMsgNum < 0);
-               segP->lastBackend++;
+               if (segP->lastBackend < segP->maxBackends)
+               {
+                       stateP = &segP->procState[segP->lastBackend];
+                       Assert(stateP->nextMsgNum < 0);
+                       segP->lastBackend++;
+               }
+               else
+               {
+                       /* out of procState slots */
+                       MyBackendId = InvalidBackendId;
+                       return 0;
+               }
        }
 
        MyBackendId = (stateP - &segP->procState[0]) + 1;
index 9ac71c6a812ed01a93fa7f451aa6df2538794aae..3ad2c50a84387fca9d53b4897d74e2534b8d4660 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.117 2002/10/03 19:19:09 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.118 2002/11/21 06:36:08 tgl Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -377,6 +377,18 @@ InitPostgres(const char *dbname, const char *username)
         */
        RelationCacheInitializePhase3();
 
+       /*
+        * Check a normal user hasn't connected to a superuser reserved slot.
+        * We can't do this till after we've read the user information, and
+        * we must do it inside a transaction since checking superuserness
+        * may require database access.  The superuser check is probably the
+        * most expensive part; don't do it until necessary.
+        */
+       if (ReservedBackends > 0 &&
+               CountEmptyBackendSlots() < ReservedBackends &&
+               !superuser())
+               elog(FATAL, "Non-superuser connection limit exceeded");
+
        /*
         * Initialize various default states that can't be set up until we've
         * selected the active user and done ReverifyMyDatabase.
@@ -397,17 +409,6 @@ InitPostgres(const char *dbname, const char *username)
        /* close the transaction we started above */
        if (!bootstrap)
                CommitTransactionCommand(true);
-
-       /*
-        * Check a normal user hasn't connected to a superuser reserved slot.
-        * Do this here since we need the user information and that only
-        * happens after we've started bringing the shared memory online. So
-        * we wait until we've registered exit handlers and potentially shut
-        * an open transaction down for an as safety conscious rejection as
-        * possible.
-        */
-       if (CountEmptyBackendSlots() < ReservedBackends && !superuser())
-               elog(ERROR, "Non-superuser connection limit exceeded");
 }
 
 /*