Code review for superuser_reserved_connections patch. Don't try to do
database access outside a transaction; revert bogus performance improvement in SIBackendInit(); improve comments; add documentation (this part courtesy Neil Conway).
This commit is contained in:
parent
02d83d7565
commit
8362be35e8
@ -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">
|
<Chapter Id="runtime">
|
||||||
@ -1902,6 +1902,28 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term><varname>TCPIP_SOCKET</varname> (<type>boolean</type>)</term>
|
<term><varname>TCPIP_SOCKET</varname> (<type>boolean</type>)</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -2952,24 +2974,25 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
With SSL support compiled in, the <productname>PostgreSQL</> server
|
With <acronym>SSL</> support compiled in, the
|
||||||
can be started with SSL support by setting the parameter
|
<productname>PostgreSQL</> server can be started with
|
||||||
<varname>ssl</varname> to on in
|
<acronym>SSL</> support by setting the parameter
|
||||||
<filename>postgresql.conf</filename>. When starting in SSL mode,
|
<varname>ssl</varname> to on in <filename>postgresql.conf</>. When
|
||||||
the server will look for the files <filename>server.key</> and
|
starting in <acronym>SSL</> mode, the server will look for the
|
||||||
<filename>server.crt</> in the data directory. These files should
|
files <filename>server.key</> and <filename>server.crt</> in the
|
||||||
contain the server private key and certificate respectively. These
|
data directory. These files should contain the server private key
|
||||||
files must be set up correctly before an SSL-enabled server can
|
and certificate respectively. These files must be set up correctly
|
||||||
start. If the private key is protected with a passphrase, the
|
before an <acronym>SSL</>-enabled server can start. If the private key is
|
||||||
server will prompt for the passphrase and will not start until it
|
protected with a passphrase, the server will prompt for the
|
||||||
has been entered.
|
passphrase and will not start until it has been entered.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The server will listen for both standard and SSL connections on the
|
The server will listen for both standard and <acronym>SSL</>
|
||||||
same TCP/IP port, and will negotiate with any connecting client on
|
connections on the same TCP/IP port, and will negotiate with any
|
||||||
whether to use SSL. See <xref linkend="client-authentication"> about
|
connecting client on whether to use <acronym>SSL</>. See <xref
|
||||||
how to force the server to only use of SSL for certain connections.
|
linkend="client-authentication"> about how to force the server to
|
||||||
|
require use of <acronym>SSL</> for certain connections.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -154,12 +154,11 @@ int MaxBackends = DEF_MAXBACKENDS;
|
|||||||
/*
|
/*
|
||||||
* ReservedBackends is the number of backends reserved for superuser use.
|
* ReservedBackends is the number of backends reserved for superuser use.
|
||||||
* This number is taken out of the pool size given by MaxBackends so
|
* This number is taken out of the pool size given by MaxBackends so
|
||||||
* number of backend slots available to none super users is
|
* number of backend slots available to non-superusers is
|
||||||
* (MaxBackends - ReservedBackends). Note, existing super user
|
* (MaxBackends - ReservedBackends). Note what this really means is
|
||||||
* connections are not taken into account once this lower limit has
|
* "if there are <= ReservedBackends connections available, only superusers
|
||||||
* been reached, i.e. superuser connections made before the lower limit
|
* can make new connections" --- pre-existing superuser connections don't
|
||||||
* is reached always count towards that limit and are not taken from
|
* count against the limit.
|
||||||
* ReservedBackends.
|
|
||||||
*/
|
*/
|
||||||
int ReservedBackends = 2;
|
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)
|
if (NBuffers < 2 * MaxBackends || NBuffers < 16)
|
||||||
{
|
{
|
||||||
@ -581,16 +588,11 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
ExitPostmaster(1);
|
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)
|
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
|
* Now that we are done processing the postmaster arguments, reset
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* CountEmptyBackendSlots - count empty slots in backend process table
|
||||||
*
|
*
|
||||||
* Doesn't count since the procState array could be large and we've already
|
* We don't actually need to count, since sinvaladt.c maintains a
|
||||||
* allowed for that by running a freeBackends counter in the SI segment.
|
* freeBackends counter in the SI segment.
|
||||||
* Unlike CountActiveBackends() we do not need to interrogate the
|
*
|
||||||
* backends to determine the free slot count.
|
* Acquiring the lock here is almost certainly overkill, but just in
|
||||||
* Goes for a lock despite being a trival look up in case other backends
|
* case fetching an int is not atomic on your machine ...
|
||||||
* are busy starting or exiting since there is scope for confusion.
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
CountEmptyBackendSlots(void)
|
CountEmptyBackendSlots(void)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
int index;
|
||||||
ProcState *stateP = NULL;
|
ProcState *stateP = NULL;
|
||||||
|
|
||||||
if (segP->freeBackends == 0)
|
|
||||||
{
|
|
||||||
/* out of procState slots */
|
|
||||||
MyBackendId = InvalidBackendId;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look for a free entry in the procState array */
|
/* Look for a free entry in the procState array */
|
||||||
for (index = 0; index < segP->lastBackend; index++)
|
for (index = 0; index < segP->lastBackend; index++)
|
||||||
{
|
{
|
||||||
@ -111,9 +104,18 @@ SIBackendInit(SISeg *segP)
|
|||||||
|
|
||||||
if (stateP == NULL)
|
if (stateP == NULL)
|
||||||
{
|
{
|
||||||
stateP = &segP->procState[segP->lastBackend];
|
if (segP->lastBackend < segP->maxBackends)
|
||||||
Assert(stateP->nextMsgNum < 0);
|
{
|
||||||
segP->lastBackend++;
|
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;
|
MyBackendId = (stateP - &segP->procState[0]) + 1;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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();
|
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
|
* Initialize various default states that can't be set up until we've
|
||||||
* selected the active user and done ReverifyMyDatabase.
|
* selected the active user and done ReverifyMyDatabase.
|
||||||
@ -397,17 +409,6 @@ InitPostgres(const char *dbname, const char *username)
|
|||||||
/* close the transaction we started above */
|
/* close the transaction we started above */
|
||||||
if (!bootstrap)
|
if (!bootstrap)
|
||||||
CommitTransactionCommand(true);
|
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user