1996-10-31 08:10:14 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* miscadmin.h
|
2004-03-24 23:40:29 +01:00
|
|
|
* This file contains general postgres administration and initialization
|
1996-10-31 08:10:14 +01:00
|
|
|
* stuff that used to be spread out between the following files:
|
|
|
|
* globals.h global variables
|
|
|
|
* pdir.h directory path crud
|
|
|
|
* pinit.h postgres initialization
|
|
|
|
* pmod.h processing modes
|
2004-03-24 23:40:29 +01:00
|
|
|
* Over time, this has also become the preferred place for widely known
|
|
|
|
* resource-limitation stuff, such as work_mem and check_stack_depth().
|
1996-10-31 08:10:14 +01:00
|
|
|
*
|
2022-01-08 01:04:57 +01:00
|
|
|
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-10-31 08:10:14 +01:00
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/miscadmin.h
|
1996-10-31 08:10:14 +01:00
|
|
|
*
|
|
|
|
* NOTES
|
2004-05-30 00:48:23 +02:00
|
|
|
* some of the information in this file should be moved to other files.
|
1996-10-31 08:10:14 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#ifndef MISCADMIN_H
|
|
|
|
#define MISCADMIN_H
|
|
|
|
|
2017-06-06 03:53:41 +02:00
|
|
|
#include <signal.h>
|
|
|
|
|
2019-08-19 09:21:39 +02:00
|
|
|
#include "datatype/timestamp.h" /* for TimestampTz */
|
2008-02-17 03:09:32 +01:00
|
|
|
#include "pgtime.h" /* for pg_time_t */
|
2007-08-03 01:39:45 +02:00
|
|
|
|
2002-05-05 02:03:29 +02:00
|
|
|
|
2013-08-28 20:08:13 +02:00
|
|
|
#define InvalidPid (-1)
|
|
|
|
|
2004-05-30 00:48:23 +02:00
|
|
|
|
2001-01-14 06:08:17 +01:00
|
|
|
/*****************************************************************************
|
2001-01-19 23:08:47 +01:00
|
|
|
* System interrupt and critical section handling
|
2001-01-14 06:08:17 +01:00
|
|
|
*
|
|
|
|
* There are two types of interrupts that a running backend needs to accept
|
|
|
|
* without messing up its state: QueryCancel (SIGINT) and ProcDie (SIGTERM).
|
|
|
|
* In both cases, we need to be able to clean up the current transaction
|
|
|
|
* gracefully, so we can't respond to the interrupt instantaneously ---
|
|
|
|
* there's no guarantee that internal data structures would be self-consistent
|
|
|
|
* if the code is interrupted at an arbitrary instant. Instead, the signal
|
|
|
|
* handlers set flags that are checked periodically during execution.
|
|
|
|
*
|
|
|
|
* The CHECK_FOR_INTERRUPTS() macro is called at strategically located spots
|
|
|
|
* where it is normally safe to accept a cancel or die interrupt. In some
|
|
|
|
* cases, we invoke CHECK_FOR_INTERRUPTS() inside low-level subroutines that
|
|
|
|
* might sometimes be called in contexts that do *not* want to allow a cancel
|
2001-01-19 23:08:47 +01:00
|
|
|
* or die interrupt. The HOLD_INTERRUPTS() and RESUME_INTERRUPTS() macros
|
|
|
|
* allow code to ensure that no cancel or die interrupt will be accepted,
|
|
|
|
* even if CHECK_FOR_INTERRUPTS() gets called in a subroutine. The interrupt
|
2002-01-02 00:16:22 +01:00
|
|
|
* will be held off until CHECK_FOR_INTERRUPTS() is done outside any
|
|
|
|
* HOLD_INTERRUPTS() ... RESUME_INTERRUPTS() section.
|
2001-01-14 06:08:17 +01:00
|
|
|
*
|
Be more careful to not lose sync in the FE/BE protocol.
If any error occurred while we were in the middle of reading a protocol
message from the client, we could lose sync, and incorrectly try to
interpret a part of another message as a new protocol message. That will
usually lead to an "invalid frontend message" error that terminates the
connection. However, this is a security issue because an attacker might
be able to deliberately cause an error, inject a Query message in what's
supposed to be just user data, and have the server execute it.
We were quite careful to not have CHECK_FOR_INTERRUPTS() calls or other
operations that could ereport(ERROR) in the middle of processing a message,
but a query cancel interrupt or statement timeout could nevertheless cause
it to happen. Also, the V2 fastpath and COPY handling were not so careful.
It's very difficult to recover in the V2 COPY protocol, so we will just
terminate the connection on error. In practice, that's what happened
previously anyway, as we lost protocol sync.
To fix, add a new variable in pqcomm.c, PqCommReadingMsg, that is set
whenever we're in the middle of reading a message. When it's set, we cannot
safely ERROR out and continue running, because we might've read only part
of a message. PqCommReadingMsg acts somewhat similarly to critical sections
in that if an error occurs while it's set, the error handler will force the
connection to be terminated, as if the error was FATAL. It's not
implemented by promoting ERROR to FATAL in elog.c, like ERROR is promoted
to PANIC in critical sections, because we want to be able to use
PG_TRY/CATCH to recover and regain protocol sync. pq_getmessage() takes
advantage of that to prevent an OOM error from terminating the connection.
To prevent unnecessary connection terminations, add a holdoff mechanism
similar to HOLD/RESUME_INTERRUPTS() that can be used hold off query cancel
interrupts, but still allow die interrupts. The rules on which interrupts
are processed when are now a bit more complicated, so refactor
ProcessInterrupts() and the calls to it in signal handlers so that the
signal handlers always call it if ImmediateInterruptOK is set, and
ProcessInterrupts() can decide to not do anything if the other conditions
are not met.
Reported by Emil Lenngren. Patch reviewed by Noah Misch and Andres Freund.
Backpatch to all supported versions.
Security: CVE-2015-0244
2015-02-02 16:08:45 +01:00
|
|
|
* There is also a mechanism to prevent query cancel interrupts, while still
|
|
|
|
* allowing die interrupts: HOLD_CANCEL_INTERRUPTS() and
|
|
|
|
* RESUME_CANCEL_INTERRUPTS().
|
|
|
|
*
|
2021-05-14 18:54:26 +02:00
|
|
|
* Note that ProcessInterrupts() has also acquired a number of tasks that
|
|
|
|
* do not necessarily cause a query-cancel-or-die response. Hence, it's
|
|
|
|
* possible that it will just clear InterruptPending and return.
|
|
|
|
*
|
|
|
|
* INTERRUPTS_PENDING_CONDITION() can be checked to see whether an
|
|
|
|
* interrupt needs to be serviced, without trying to do so immediately.
|
|
|
|
* Some callers are also interested in INTERRUPTS_CAN_BE_PROCESSED(),
|
|
|
|
* which tells whether ProcessInterrupts is sure to clear the interrupt.
|
|
|
|
*
|
2001-01-14 06:08:17 +01:00
|
|
|
* Special mechanisms are used to let an interrupt be accepted when we are
|
2001-09-29 06:02:27 +02:00
|
|
|
* waiting for a lock or when we are waiting for command input (but, of
|
|
|
|
* course, only if the interrupt holdoff counter is zero). See the
|
2001-01-14 06:08:17 +01:00
|
|
|
* related code for details.
|
|
|
|
*
|
2011-12-09 10:37:21 +01:00
|
|
|
* A lost connection is handled similarly, although the loss of connection
|
|
|
|
* does not raise a signal, but is detected when we fail to write to the
|
|
|
|
* socket. If there was a signal for a broken connection, we could make use of
|
|
|
|
* it by setting ClientConnectionLost in the signal handler.
|
|
|
|
*
|
2001-01-19 23:08:47 +01:00
|
|
|
* A related, but conceptually distinct, mechanism is the "critical section"
|
|
|
|
* mechanism. A critical section not only holds off cancel/die interrupts,
|
2003-07-27 19:10:07 +02:00
|
|
|
* but causes any ereport(ERROR) or ereport(FATAL) to become ereport(PANIC)
|
|
|
|
* --- that is, a system-wide reset is forced. Needless to say, only really
|
|
|
|
* *critical* code should be marked as a critical section! Currently, this
|
|
|
|
* mechanism is only used for XLOG-related code.
|
2001-01-19 23:08:47 +01:00
|
|
|
*
|
2001-01-14 06:08:17 +01:00
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/* in globals.c */
|
|
|
|
/* these are marked volatile because they are set by signal handlers: */
|
2018-09-27 00:47:20 +02:00
|
|
|
extern PGDLLIMPORT volatile sig_atomic_t InterruptPending;
|
|
|
|
extern PGDLLIMPORT volatile sig_atomic_t QueryCancelPending;
|
|
|
|
extern PGDLLIMPORT volatile sig_atomic_t ProcDiePending;
|
|
|
|
extern PGDLLIMPORT volatile sig_atomic_t IdleInTransactionSessionTimeoutPending;
|
2021-01-07 00:28:42 +01:00
|
|
|
extern PGDLLIMPORT volatile sig_atomic_t IdleSessionTimeoutPending;
|
2019-12-19 20:56:20 +01:00
|
|
|
extern PGDLLIMPORT volatile sig_atomic_t ProcSignalBarrierPending;
|
Add function to log the memory contexts of specified backend process.
Commit 3e98c0bafb added pg_backend_memory_contexts view to display
the memory contexts of the backend process. However its target process
is limited to the backend that is accessing to the view. So this is
not so convenient when investigating the local memory bloat of other
backend process. To improve this situation, this commit adds
pg_log_backend_memory_contexts() function that requests to log
the memory contexts of the specified backend process.
This information can be also collected by calling
MemoryContextStats(TopMemoryContext) via a debugger. But
this technique cannot be used in some environments because no debugger
is available there. So, pg_log_backend_memory_contexts() allows us to
see the memory contexts of specified backend more easily.
Only superusers are allowed to request to log the memory contexts
because allowing any users to issue this request at an unbounded rate
would cause lots of log messages and which can lead to denial of service.
On receipt of the request, at the next CHECK_FOR_INTERRUPTS(),
the target backend logs its memory contexts at LOG_SERVER_ONLY level,
so that these memory contexts will appear in the server log but not
be sent to the client. It logs one message per memory context.
Because if it buffers all memory contexts into StringInfo to log them
as one message, which may require the buffer to be enlarged very much
and lead to OOM error since there can be a large number of memory
contexts in a backend.
When a backend process is consuming huge memory, logging all its
memory contexts might overrun available disk space. To prevent this,
now this patch limits the number of child contexts to log per parent
to 100. As with MemoryContextStats(), it supposes that practical cases
where the log gets long will typically be huge numbers of siblings
under the same parent context; while the additional debugging value
from seeing details about individual siblings beyond 100 will not be large.
There was another proposed patch to add the function to return
the memory contexts of specified backend as the result sets,
instead of logging them, in the discussion. However that patch is
not included in this commit because it had several issues to address.
Thanks to Tatsuhito Kasahara, Andres Freund, Tom Lane, Tomas Vondra,
Michael Paquier, Kyotaro Horiguchi and Zhihong Yu for the discussion.
Bump catalog version.
Author: Atsushi Torikoshi
Reviewed-by: Kyotaro Horiguchi, Zhihong Yu, Fujii Masao
Discussion: https://postgr.es/m/0271f440ac77f2a4180e0e56ebd944d1@oss.nttdata.com
2021-04-06 06:44:15 +02:00
|
|
|
extern PGDLLIMPORT volatile sig_atomic_t LogMemoryContextPending;
|
2022-04-07 06:29:46 +02:00
|
|
|
extern PGDLLIMPORT volatile sig_atomic_t IdleStatsUpdateTimeoutPending;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2021-04-02 21:52:30 +02:00
|
|
|
extern PGDLLIMPORT volatile sig_atomic_t CheckClientConnectionPending;
|
2018-09-27 00:47:20 +02:00
|
|
|
extern PGDLLIMPORT volatile sig_atomic_t ClientConnectionLost;
|
2011-12-09 10:37:21 +01:00
|
|
|
|
2001-01-14 06:08:17 +01:00
|
|
|
/* these are marked volatile because they are examined by signal handlers: */
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT volatile uint32 InterruptHoldoffCount;
|
Be more careful to not lose sync in the FE/BE protocol.
If any error occurred while we were in the middle of reading a protocol
message from the client, we could lose sync, and incorrectly try to
interpret a part of another message as a new protocol message. That will
usually lead to an "invalid frontend message" error that terminates the
connection. However, this is a security issue because an attacker might
be able to deliberately cause an error, inject a Query message in what's
supposed to be just user data, and have the server execute it.
We were quite careful to not have CHECK_FOR_INTERRUPTS() calls or other
operations that could ereport(ERROR) in the middle of processing a message,
but a query cancel interrupt or statement timeout could nevertheless cause
it to happen. Also, the V2 fastpath and COPY handling were not so careful.
It's very difficult to recover in the V2 COPY protocol, so we will just
terminate the connection on error. In practice, that's what happened
previously anyway, as we lost protocol sync.
To fix, add a new variable in pqcomm.c, PqCommReadingMsg, that is set
whenever we're in the middle of reading a message. When it's set, we cannot
safely ERROR out and continue running, because we might've read only part
of a message. PqCommReadingMsg acts somewhat similarly to critical sections
in that if an error occurs while it's set, the error handler will force the
connection to be terminated, as if the error was FATAL. It's not
implemented by promoting ERROR to FATAL in elog.c, like ERROR is promoted
to PANIC in critical sections, because we want to be able to use
PG_TRY/CATCH to recover and regain protocol sync. pq_getmessage() takes
advantage of that to prevent an OOM error from terminating the connection.
To prevent unnecessary connection terminations, add a holdoff mechanism
similar to HOLD/RESUME_INTERRUPTS() that can be used hold off query cancel
interrupts, but still allow die interrupts. The rules on which interrupts
are processed when are now a bit more complicated, so refactor
ProcessInterrupts() and the calls to it in signal handlers so that the
signal handlers always call it if ImmediateInterruptOK is set, and
ProcessInterrupts() can decide to not do anything if the other conditions
are not met.
Reported by Emil Lenngren. Patch reviewed by Noah Misch and Andres Freund.
Backpatch to all supported versions.
Security: CVE-2015-0244
2015-02-02 16:08:45 +01:00
|
|
|
extern PGDLLIMPORT volatile uint32 QueryCancelHoldoffCount;
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT volatile uint32 CritSectionCount;
|
2001-01-14 06:08:17 +01:00
|
|
|
|
2004-03-24 23:40:29 +01:00
|
|
|
/* in tcop/postgres.c */
|
2001-01-14 06:08:17 +01:00
|
|
|
extern void ProcessInterrupts(void);
|
|
|
|
|
2021-05-14 18:54:26 +02:00
|
|
|
/* Test whether an interrupt is pending */
|
2004-02-08 23:28:57 +01:00
|
|
|
#ifndef WIN32
|
2021-05-14 18:54:26 +02:00
|
|
|
#define INTERRUPTS_PENDING_CONDITION() \
|
|
|
|
(unlikely(InterruptPending))
|
|
|
|
#else
|
|
|
|
#define INTERRUPTS_PENDING_CONDITION() \
|
|
|
|
(unlikely(UNBLOCKED_SIGNAL_QUEUE()) ? pgwin32_dispatch_queued_signals() : 0, \
|
|
|
|
unlikely(InterruptPending))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Service interrupt, if one is pending and it's safe to service it now */
|
2004-02-08 23:28:57 +01:00
|
|
|
#define CHECK_FOR_INTERRUPTS() \
|
|
|
|
do { \
|
2021-05-14 18:54:26 +02:00
|
|
|
if (INTERRUPTS_PENDING_CONDITION()) \
|
2004-02-08 23:28:57 +01:00
|
|
|
ProcessInterrupts(); \
|
2004-02-10 04:42:45 +01:00
|
|
|
} while(0)
|
2004-02-08 23:28:57 +01:00
|
|
|
|
2021-05-14 18:54:26 +02:00
|
|
|
/* Is ProcessInterrupts() guaranteed to clear InterruptPending? */
|
|
|
|
#define INTERRUPTS_CAN_BE_PROCESSED() \
|
|
|
|
(InterruptHoldoffCount == 0 && CritSectionCount == 0 && \
|
|
|
|
QueryCancelHoldoffCount == 0)
|
2001-01-14 06:08:17 +01:00
|
|
|
|
2001-01-19 23:08:47 +01:00
|
|
|
#define HOLD_INTERRUPTS() (InterruptHoldoffCount++)
|
|
|
|
|
|
|
|
#define RESUME_INTERRUPTS() \
|
2004-01-09 22:08:50 +01:00
|
|
|
do { \
|
|
|
|
Assert(InterruptHoldoffCount > 0); \
|
|
|
|
InterruptHoldoffCount--; \
|
|
|
|
} while(0)
|
2001-01-19 23:08:47 +01:00
|
|
|
|
Be more careful to not lose sync in the FE/BE protocol.
If any error occurred while we were in the middle of reading a protocol
message from the client, we could lose sync, and incorrectly try to
interpret a part of another message as a new protocol message. That will
usually lead to an "invalid frontend message" error that terminates the
connection. However, this is a security issue because an attacker might
be able to deliberately cause an error, inject a Query message in what's
supposed to be just user data, and have the server execute it.
We were quite careful to not have CHECK_FOR_INTERRUPTS() calls or other
operations that could ereport(ERROR) in the middle of processing a message,
but a query cancel interrupt or statement timeout could nevertheless cause
it to happen. Also, the V2 fastpath and COPY handling were not so careful.
It's very difficult to recover in the V2 COPY protocol, so we will just
terminate the connection on error. In practice, that's what happened
previously anyway, as we lost protocol sync.
To fix, add a new variable in pqcomm.c, PqCommReadingMsg, that is set
whenever we're in the middle of reading a message. When it's set, we cannot
safely ERROR out and continue running, because we might've read only part
of a message. PqCommReadingMsg acts somewhat similarly to critical sections
in that if an error occurs while it's set, the error handler will force the
connection to be terminated, as if the error was FATAL. It's not
implemented by promoting ERROR to FATAL in elog.c, like ERROR is promoted
to PANIC in critical sections, because we want to be able to use
PG_TRY/CATCH to recover and regain protocol sync. pq_getmessage() takes
advantage of that to prevent an OOM error from terminating the connection.
To prevent unnecessary connection terminations, add a holdoff mechanism
similar to HOLD/RESUME_INTERRUPTS() that can be used hold off query cancel
interrupts, but still allow die interrupts. The rules on which interrupts
are processed when are now a bit more complicated, so refactor
ProcessInterrupts() and the calls to it in signal handlers so that the
signal handlers always call it if ImmediateInterruptOK is set, and
ProcessInterrupts() can decide to not do anything if the other conditions
are not met.
Reported by Emil Lenngren. Patch reviewed by Noah Misch and Andres Freund.
Backpatch to all supported versions.
Security: CVE-2015-0244
2015-02-02 16:08:45 +01:00
|
|
|
#define HOLD_CANCEL_INTERRUPTS() (QueryCancelHoldoffCount++)
|
|
|
|
|
|
|
|
#define RESUME_CANCEL_INTERRUPTS() \
|
|
|
|
do { \
|
|
|
|
Assert(QueryCancelHoldoffCount > 0); \
|
|
|
|
QueryCancelHoldoffCount--; \
|
|
|
|
} while(0)
|
|
|
|
|
2001-01-14 06:08:17 +01:00
|
|
|
#define START_CRIT_SECTION() (CritSectionCount++)
|
|
|
|
|
|
|
|
#define END_CRIT_SECTION() \
|
2004-01-09 22:08:50 +01:00
|
|
|
do { \
|
|
|
|
Assert(CritSectionCount > 0); \
|
|
|
|
CritSectionCount--; \
|
|
|
|
} while(0)
|
|
|
|
|
2004-01-26 23:59:54 +01:00
|
|
|
|
1996-10-31 08:10:14 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
* globals.h -- *
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* from utils/init/globals.c
|
|
|
|
*/
|
2016-06-03 19:50:51 +02:00
|
|
|
extern PGDLLIMPORT pid_t PostmasterPid;
|
2016-11-26 16:29:18 +01:00
|
|
|
extern PGDLLIMPORT bool IsPostmasterEnvironment;
|
2009-01-05 03:27:45 +01:00
|
|
|
extern PGDLLIMPORT bool IsUnderPostmaster;
|
2016-11-26 16:29:18 +01:00
|
|
|
extern PGDLLIMPORT bool IsBackgroundWorker;
|
2014-08-26 15:25:18 +02:00
|
|
|
extern PGDLLIMPORT bool IsBinaryUpgrade;
|
2003-05-28 20:19:09 +02:00
|
|
|
|
2017-12-05 15:23:57 +01:00
|
|
|
extern PGDLLIMPORT bool ExitOnAnyError;
|
2003-05-28 20:19:09 +02:00
|
|
|
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT char *DataDir;
|
2018-04-07 23:45:39 +02:00
|
|
|
extern PGDLLIMPORT int data_directory_mode;
|
1996-10-31 08:10:14 +01:00
|
|
|
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT int NBuffers;
|
2022-04-12 20:45:23 +02:00
|
|
|
extern PGDLLIMPORT int MaxBackends;
|
2017-12-05 15:23:57 +01:00
|
|
|
extern PGDLLIMPORT int MaxConnections;
|
|
|
|
extern PGDLLIMPORT int max_worker_processes;
|
2018-02-09 21:54:45 +01:00
|
|
|
extern PGDLLIMPORT int max_parallel_workers;
|
2004-05-30 00:48:23 +02:00
|
|
|
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT int MyProcPid;
|
2008-02-17 03:09:32 +01:00
|
|
|
extern PGDLLIMPORT pg_time_t MyStartTime;
|
2018-10-19 02:59:14 +02:00
|
|
|
extern PGDLLIMPORT TimestampTz MyStartTimestamp;
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT struct Port *MyProcPort;
|
2015-01-14 18:45:22 +01:00
|
|
|
extern PGDLLIMPORT struct Latch *MyLatch;
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT int32 MyCancelKey;
|
|
|
|
extern PGDLLIMPORT int MyPMChildSlot;
|
1998-07-09 05:29:11 +02:00
|
|
|
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT char OutputFileName[];
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT char my_exec_path[];
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT char pkglib_path[];
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2004-05-28 07:13:32 +02:00
|
|
|
#ifdef EXEC_BACKEND
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT char postgres_exec_path[];
|
2004-05-28 07:13:32 +02:00
|
|
|
#endif
|
1996-10-31 08:10:14 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* done in storage/backendid.h for now.
|
|
|
|
*
|
|
|
|
* extern BackendId MyBackendId;
|
|
|
|
*/
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT Oid MyDatabaseId;
|
1996-10-31 08:10:14 +01:00
|
|
|
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT Oid MyDatabaseTableSpace;
|
2004-06-18 08:14:31 +02:00
|
|
|
|
2003-07-29 02:03:19 +02:00
|
|
|
/*
|
|
|
|
* Date/Time Configuration
|
1997-03-25 09:11:24 +01:00
|
|
|
*
|
2003-07-29 02:03:19 +02:00
|
|
|
* DateStyle defines the output formatting choice for date/time types:
|
|
|
|
* USE_POSTGRES_DATES specifies traditional Postgres format
|
|
|
|
* USE_ISO_DATES specifies ISO-compliant format
|
|
|
|
* USE_SQL_DATES specifies Oracle/Ingres-compliant format
|
|
|
|
* USE_GERMAN_DATES specifies German-style dd.mm/yyyy
|
1997-03-25 09:11:24 +01:00
|
|
|
*
|
2003-07-29 02:03:19 +02:00
|
|
|
* DateOrder defines the field order to be assumed when reading an
|
|
|
|
* ambiguous date (anything not in YYYY-MM-DD format, with a four-digit
|
|
|
|
* year field first, is taken to be ambiguous):
|
|
|
|
* DATEORDER_YMD specifies field order yy-mm-dd
|
|
|
|
* DATEORDER_DMY specifies field order dd-mm-yy ("European" convention)
|
|
|
|
* DATEORDER_MDY specifies field order mm-dd-yy ("US" convention)
|
1997-03-25 09:11:24 +01:00
|
|
|
*
|
2003-07-29 02:03:19 +02:00
|
|
|
* In the Postgres and SQL DateStyles, DateOrder also selects output field
|
|
|
|
* order: day comes before month in DMY style, else month comes before day.
|
|
|
|
*
|
|
|
|
* The user-visible "DateStyle" run-time parameter subsumes both of these.
|
1997-03-18 17:36:50 +01:00
|
|
|
*/
|
|
|
|
|
2003-07-29 02:03:19 +02:00
|
|
|
/* valid DateStyle values */
|
1997-03-25 09:11:24 +01:00
|
|
|
#define USE_POSTGRES_DATES 0
|
|
|
|
#define USE_ISO_DATES 1
|
|
|
|
#define USE_SQL_DATES 2
|
1997-12-05 00:58:01 +01:00
|
|
|
#define USE_GERMAN_DATES 3
|
2007-03-01 15:52:04 +01:00
|
|
|
#define USE_XSD_DATES 4
|
1997-03-25 09:11:24 +01:00
|
|
|
|
2003-07-29 02:03:19 +02:00
|
|
|
/* valid DateOrder values */
|
|
|
|
#define DATEORDER_YMD 0
|
|
|
|
#define DATEORDER_DMY 1
|
|
|
|
#define DATEORDER_MDY 2
|
|
|
|
|
2014-02-16 18:37:07 +01:00
|
|
|
extern PGDLLIMPORT int DateStyle;
|
|
|
|
extern PGDLLIMPORT int DateOrder;
|
2009-06-11 16:49:15 +02:00
|
|
|
|
2008-11-09 01:28:35 +01:00
|
|
|
/*
|
|
|
|
* IntervalStyles
|
|
|
|
* INTSTYLE_POSTGRES Like Postgres < 8.4 when DateStyle = 'iso'
|
|
|
|
* INTSTYLE_POSTGRES_VERBOSE Like Postgres < 8.4 when DateStyle != 'iso'
|
|
|
|
* INTSTYLE_SQL_STANDARD SQL standard interval literals
|
2008-11-11 03:42:33 +01:00
|
|
|
* INTSTYLE_ISO_8601 ISO-8601-basic formatted intervals
|
2008-11-09 01:28:35 +01:00
|
|
|
*/
|
2008-11-11 03:42:33 +01:00
|
|
|
#define INTSTYLE_POSTGRES 0
|
|
|
|
#define INTSTYLE_POSTGRES_VERBOSE 1
|
|
|
|
#define INTSTYLE_SQL_STANDARD 2
|
|
|
|
#define INTSTYLE_ISO_8601 3
|
2008-11-09 01:28:35 +01:00
|
|
|
|
2014-02-16 18:37:07 +01:00
|
|
|
extern PGDLLIMPORT int IntervalStyle;
|
2003-07-29 02:03:19 +02:00
|
|
|
|
|
|
|
#define MAXTZLEN 10 /* max TZ name len, not counting tr. null */
|
|
|
|
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT bool enableFsync;
|
2017-12-05 15:23:57 +01:00
|
|
|
extern PGDLLIMPORT bool allowSystemTableMods;
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT int work_mem;
|
2020-07-29 23:14:58 +02:00
|
|
|
extern PGDLLIMPORT double hash_mem_multiplier;
|
2007-07-25 14:22:54 +02:00
|
|
|
extern PGDLLIMPORT int maintenance_work_mem;
|
Support parallel btree index builds.
To make this work, tuplesort.c and logtape.c must also support
parallelism, so this patch adds that infrastructure and then applies
it to the particular case of parallel btree index builds. Testing
to date shows that this can often be 2-3x faster than a serial
index build.
The model for deciding how many workers to use is fairly primitive
at present, but it's better than not having the feature. We can
refine it as we get more experience.
Peter Geoghegan with some help from Rushabh Lathia. While Heikki
Linnakangas is not an author of this patch, he wrote other patches
without which this feature would not have been possible, and
therefore the release notes should possibly credit him as an author
of this feature. Reviewed by Claudio Freire, Heikki Linnakangas,
Thomas Munro, Tels, Amit Kapila, me.
Discussion: http://postgr.es/m/CAM3SWZQKM=Pzc=CAHzRixKjp2eO5Q0Jg1SoFQqeXFQ647JiwqQ@mail.gmail.com
Discussion: http://postgr.es/m/CAH2-Wz=AxWqDoVvGU7dq856S4r6sJAj6DBn7VMtigkB33N5eyg@mail.gmail.com
2018-02-02 19:25:55 +01:00
|
|
|
extern PGDLLIMPORT int max_parallel_maintenance_workers;
|
2004-02-06 20:36:18 +01:00
|
|
|
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT int VacuumCostPageHit;
|
|
|
|
extern PGDLLIMPORT int VacuumCostPageMiss;
|
|
|
|
extern PGDLLIMPORT int VacuumCostPageDirty;
|
|
|
|
extern PGDLLIMPORT int VacuumCostLimit;
|
|
|
|
extern PGDLLIMPORT double VacuumCostDelay;
|
2004-02-10 04:42:45 +01:00
|
|
|
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT int64 VacuumPageHit;
|
|
|
|
extern PGDLLIMPORT int64 VacuumPageMiss;
|
|
|
|
extern PGDLLIMPORT int64 VacuumPageDirty;
|
2011-11-25 16:10:46 +01:00
|
|
|
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT int VacuumCostBalance;
|
|
|
|
extern PGDLLIMPORT bool VacuumCostActive;
|
1997-08-14 18:11:41 +02:00
|
|
|
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2004-03-24 23:40:29 +01:00
|
|
|
/* in tcop/postgres.c */
|
Do stack-depth checking in all postmaster children.
We used to only initialize the stack base pointer when starting up a regular
backend, not in other processes. In particular, autovacuum workers can run
arbitrary user code, and without stack-depth checking, infinite recursion
in e.g an index expression will bring down the whole cluster.
The comment about PL/Java using set_stack_base() is not yet true. As the
code stands, PL/java still modifies the stack_base_ptr variable directly.
However, it's been discussed in the PL/Java mailing list that it should be
changed to use the function, because PL/Java is currently oblivious to the
register stack used on Itanium. There's another issues with PL/Java, namely
that the stack base pointer it sets is not really the base of the stack, it
could be something close to the bottom of the stack. That's a separate issue
that might need some further changes to this code, but that's a different
story.
Backpatch to all supported releases.
2012-04-08 17:28:12 +02:00
|
|
|
|
|
|
|
typedef char *pg_stack_base_t;
|
|
|
|
|
|
|
|
extern pg_stack_base_t set_stack_base(void);
|
|
|
|
extern void restore_stack_base(pg_stack_base_t base);
|
2004-03-24 23:40:29 +01:00
|
|
|
extern void check_stack_depth(void);
|
2015-10-02 20:51:58 +02:00
|
|
|
extern bool stack_is_too_deep(void);
|
2004-03-24 23:40:29 +01:00
|
|
|
|
Allow read only connections during recovery, known as Hot Standby.
Enabled by recovery_connections = on (default) and forcing archive recovery using a recovery.conf. Recovery processing now emulates the original transactions as they are replayed, providing full locking and MVCC behaviour for read only queries. Recovery must enter consistent state before connections are allowed, so there is a delay, typically short, before connections succeed. Replay of recovering transactions can conflict and in some cases deadlock with queries during recovery; these result in query cancellation after max_standby_delay seconds have expired. Infrastructure changes have minor effects on normal running, though introduce four new types of WAL record.
New test mode "make standbycheck" allows regression tests of static command behaviour on a standby server while in recovery. Typical and extreme dynamic behaviours have been checked via code inspection and manual testing. Few port specific behaviours have been utilised, though primary testing has been on Linux only so far.
This commit is the basic patch. Additional changes will follow in this release to enhance some aspects of behaviour, notably improved handling of conflicts, deadlock detection and query cancellation. Changes to VACUUM FULL are also required.
Simon Riggs, with significant and lengthy review by Heikki Linnakangas, including streamlined redesign of snapshot creation and two-phase commit.
Important contributions from Florian Pflug, Mark Kirkwood, Merlin Moncure, Greg Stark, Gianni Ciolli, Gabriele Bartolini, Hannu Krosing, Robert Haas, Tatsuo Ishii, Hiroyuki Yamada plus support and feedback from many other community members.
2009-12-19 02:32:45 +01:00
|
|
|
/* in tcop/utility.c */
|
2010-02-20 22:24:02 +01:00
|
|
|
extern void PreventCommandIfReadOnly(const char *cmdname);
|
Create an infrastructure for parallel computation in PostgreSQL.
This does four basic things. First, it provides convenience routines
to coordinate the startup and shutdown of parallel workers. Second,
it synchronizes various pieces of state (e.g. GUCs, combo CID
mappings, transaction snapshot) from the parallel group leader to the
worker processes. Third, it prohibits various operations that would
result in unsafe changes to that state while parallelism is active.
Finally, it propagates events that would result in an ErrorResponse,
NoticeResponse, or NotifyResponse message being sent to the client
from the parallel workers back to the master, from which they can then
be sent on to the client.
Robert Haas, Amit Kapila, Noah Misch, Rushabh Lathia, Jeevan Chalke.
Suggestions and review from Andres Freund, Heikki Linnakangas, Noah
Misch, Simon Riggs, Euler Taveira, and Jim Nasby.
2015-04-30 21:02:14 +02:00
|
|
|
extern void PreventCommandIfParallelMode(const char *cmdname);
|
2010-02-20 22:24:02 +01:00
|
|
|
extern void PreventCommandDuringRecovery(const char *cmdname);
|
Allow read only connections during recovery, known as Hot Standby.
Enabled by recovery_connections = on (default) and forcing archive recovery using a recovery.conf. Recovery processing now emulates the original transactions as they are replayed, providing full locking and MVCC behaviour for read only queries. Recovery must enter consistent state before connections are allowed, so there is a delay, typically short, before connections succeed. Replay of recovering transactions can conflict and in some cases deadlock with queries during recovery; these result in query cancellation after max_standby_delay seconds have expired. Infrastructure changes have minor effects on normal running, though introduce four new types of WAL record.
New test mode "make standbycheck" allows regression tests of static command behaviour on a standby server while in recovery. Typical and extreme dynamic behaviours have been checked via code inspection and manual testing. Few port specific behaviours have been utilised, though primary testing has been on Linux only so far.
This commit is the basic patch. Additional changes will follow in this release to enhance some aspects of behaviour, notably improved handling of conflicts, deadlock detection and query cancellation. Changes to VACUUM FULL are also required.
Simon Riggs, with significant and lengthy review by Heikki Linnakangas, including streamlined redesign of snapshot creation and two-phase commit.
Important contributions from Florian Pflug, Mark Kirkwood, Merlin Moncure, Greg Stark, Gianni Ciolli, Gabriele Bartolini, Hannu Krosing, Robert Haas, Tatsuo Ishii, Hiroyuki Yamada plus support and feedback from many other community members.
2009-12-19 02:32:45 +01:00
|
|
|
|
|
|
|
/* in utils/misc/guc.c */
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT int trace_recovery_messages;
|
2010-06-17 19:44:40 +02:00
|
|
|
extern int trace_recovery(int trace_level);
|
2004-03-24 23:40:29 +01:00
|
|
|
|
1996-10-31 08:10:14 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
* pdir.h -- *
|
|
|
|
* POSTGRES directory path definitions. *
|
|
|
|
*****************************************************************************/
|
|
|
|
|
Prevent indirect security attacks via changing session-local state within
an allegedly immutable index function. It was previously recognized that
we had to prevent such a function from executing SET/RESET ROLE/SESSION
AUTHORIZATION, or it could trivially obtain the privileges of the session
user. However, since there is in general no privilege checking for changes
of session-local state, it is also possible for such a function to change
settings in a way that might subvert later operations in the same session.
Examples include changing search_path to cause an unexpected function to
be called, or replacing an existing prepared statement with another one
that will execute a function of the attacker's choosing.
The present patch secures VACUUM, ANALYZE, and CREATE INDEX/REINDEX against
these threats, which are the same places previously deemed to need protection
against the SET ROLE issue. GUC changes are still allowed, since there are
many useful cases for that, but we prevent security problems by forcing a
rollback of any GUC change after completing the operation. Other cases are
handled by throwing an error if any change is attempted; these include temp
table creation, closing a cursor, and creating or deleting a prepared
statement. (In 7.4, the infrastructure to roll back GUC changes doesn't
exist, so we settle for rejecting changes of "search_path" in these contexts.)
Original report and patch by Gurjeet Singh, additional analysis by
Tom Lane.
Security: CVE-2009-4136
2009-12-09 22:57:51 +01:00
|
|
|
/* flags to be OR'd to form sec_context */
|
|
|
|
#define SECURITY_LOCAL_USERID_CHANGE 0x0001
|
|
|
|
#define SECURITY_RESTRICTED_OPERATION 0x0002
|
2015-10-05 03:05:08 +02:00
|
|
|
#define SECURITY_NOFORCE_RLS 0x0004
|
Prevent indirect security attacks via changing session-local state within
an allegedly immutable index function. It was previously recognized that
we had to prevent such a function from executing SET/RESET ROLE/SESSION
AUTHORIZATION, or it could trivially obtain the privileges of the session
user. However, since there is in general no privilege checking for changes
of session-local state, it is also possible for such a function to change
settings in a way that might subvert later operations in the same session.
Examples include changing search_path to cause an unexpected function to
be called, or replacing an existing prepared statement with another one
that will execute a function of the attacker's choosing.
The present patch secures VACUUM, ANALYZE, and CREATE INDEX/REINDEX against
these threats, which are the same places previously deemed to need protection
against the SET ROLE issue. GUC changes are still allowed, since there are
many useful cases for that, but we prevent security problems by forcing a
rollback of any GUC change after completing the operation. Other cases are
handled by throwing an error if any change is attempted; these include temp
table creation, closing a cursor, and creating or deleting a prepared
statement. (In 7.4, the infrastructure to roll back GUC changes doesn't
exist, so we settle for rejecting changes of "search_path" in these contexts.)
Original report and patch by Gurjeet Singh, additional analysis by
Tom Lane.
Security: CVE-2009-4136
2009-12-09 22:57:51 +01:00
|
|
|
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT char *DatabasePath;
|
1998-04-05 23:04:50 +02:00
|
|
|
|
1996-10-31 08:10:14 +01:00
|
|
|
/* now in utils/init/miscinit.c */
|
2015-01-13 13:12:37 +01:00
|
|
|
extern void InitPostmasterChild(void);
|
|
|
|
extern void InitStandaloneProcess(const char *argv0);
|
2020-03-11 13:51:55 +01:00
|
|
|
extern void SwitchToSharedLatch(void);
|
|
|
|
extern void SwitchBackToLocalLatch(void);
|
2015-01-13 13:12:37 +01:00
|
|
|
|
2020-03-11 16:36:40 +01:00
|
|
|
typedef enum BackendType
|
|
|
|
{
|
|
|
|
B_INVALID = 0,
|
2022-08-23 05:22:50 +02:00
|
|
|
B_ARCHIVER,
|
2020-03-11 16:36:40 +01:00
|
|
|
B_AUTOVAC_LAUNCHER,
|
|
|
|
B_AUTOVAC_WORKER,
|
|
|
|
B_BACKEND,
|
|
|
|
B_BG_WORKER,
|
|
|
|
B_BG_WRITER,
|
|
|
|
B_CHECKPOINTER,
|
2022-08-23 05:22:50 +02:00
|
|
|
B_LOGGER,
|
|
|
|
B_STANDALONE_BACKEND,
|
2020-03-11 16:36:40 +01:00
|
|
|
B_STARTUP,
|
|
|
|
B_WAL_RECEIVER,
|
|
|
|
B_WAL_SENDER,
|
|
|
|
B_WAL_WRITER,
|
|
|
|
} BackendType;
|
|
|
|
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT BackendType MyBackendType;
|
2020-03-11 16:36:40 +01:00
|
|
|
|
|
|
|
extern const char *GetBackendTypeDesc(BackendType backendType);
|
|
|
|
|
2000-01-13 19:26:18 +01:00
|
|
|
extern void SetDatabasePath(const char *path);
|
2020-03-11 13:51:55 +01:00
|
|
|
extern void checkDataDir(void);
|
|
|
|
extern void SetDataDir(const char *dir);
|
|
|
|
extern void ChangeToDataDir(void);
|
1998-09-01 06:40:42 +02:00
|
|
|
|
2015-05-09 19:06:49 +02:00
|
|
|
extern char *GetUserNameFromId(Oid roleid, bool noerr);
|
2005-06-28 07:09:14 +02:00
|
|
|
extern Oid GetUserId(void);
|
2005-07-26 00:12:34 +02:00
|
|
|
extern Oid GetOuterUserId(void);
|
2005-06-28 07:09:14 +02:00
|
|
|
extern Oid GetSessionUserId(void);
|
2014-10-23 14:18:45 +02:00
|
|
|
extern Oid GetAuthenticatedUserId(void);
|
Prevent indirect security attacks via changing session-local state within
an allegedly immutable index function. It was previously recognized that
we had to prevent such a function from executing SET/RESET ROLE/SESSION
AUTHORIZATION, or it could trivially obtain the privileges of the session
user. However, since there is in general no privilege checking for changes
of session-local state, it is also possible for such a function to change
settings in a way that might subvert later operations in the same session.
Examples include changing search_path to cause an unexpected function to
be called, or replacing an existing prepared statement with another one
that will execute a function of the attacker's choosing.
The present patch secures VACUUM, ANALYZE, and CREATE INDEX/REINDEX against
these threats, which are the same places previously deemed to need protection
against the SET ROLE issue. GUC changes are still allowed, since there are
many useful cases for that, but we prevent security problems by forcing a
rollback of any GUC change after completing the operation. Other cases are
handled by throwing an error if any change is attempted; these include temp
table creation, closing a cursor, and creating or deleting a prepared
statement. (In 7.4, the infrastructure to roll back GUC changes doesn't
exist, so we settle for rejecting changes of "search_path" in these contexts.)
Original report and patch by Gurjeet Singh, additional analysis by
Tom Lane.
Security: CVE-2009-4136
2009-12-09 22:57:51 +01:00
|
|
|
extern void GetUserIdAndSecContext(Oid *userid, int *sec_context);
|
|
|
|
extern void SetUserIdAndSecContext(Oid userid, int sec_context);
|
|
|
|
extern bool InLocalUserIdChange(void);
|
|
|
|
extern bool InSecurityRestrictedOperation(void);
|
2015-10-05 03:05:08 +02:00
|
|
|
extern bool InNoForceRLSOperation(void);
|
2008-01-03 22:23:15 +01:00
|
|
|
extern void GetUserIdAndContext(Oid *userid, bool *sec_def_context);
|
|
|
|
extern void SetUserIdAndContext(Oid userid, bool sec_def_context);
|
2015-02-02 22:23:59 +01:00
|
|
|
extern void InitializeSessionUserId(const char *rolename, Oid useroid);
|
2001-09-08 17:24:00 +02:00
|
|
|
extern void InitializeSessionUserIdStandalone(void);
|
2005-07-26 00:12:34 +02:00
|
|
|
extern void SetSessionAuthorization(Oid userid, bool is_superuser);
|
|
|
|
extern Oid GetCurrentRoleId(void);
|
|
|
|
extern void SetCurrentRoleId(Oid roleid, bool is_superuser);
|
2000-09-19 20:18:04 +02:00
|
|
|
|
2001-06-13 23:44:41 +02:00
|
|
|
/* in utils/misc/superuser.c */
|
|
|
|
extern bool superuser(void); /* current user is superuser */
|
2005-06-28 07:09:14 +02:00
|
|
|
extern bool superuser_arg(Oid roleid); /* given user is superuser */
|
2001-06-13 23:44:41 +02:00
|
|
|
|
|
|
|
|
1996-10-31 08:10:14 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
* pmod.h -- *
|
|
|
|
* POSTGRES processing mode definitions. *
|
|
|
|
*****************************************************************************/
|
2001-09-27 18:29:13 +02:00
|
|
|
|
1996-10-31 08:10:14 +01:00
|
|
|
/*
|
|
|
|
* Description:
|
1999-10-06 23:58:18 +02:00
|
|
|
* There are three processing modes in POSTGRES. They are
|
2001-01-14 06:08:17 +01:00
|
|
|
* BootstrapProcessing or "bootstrap," InitProcessing or
|
1996-10-31 08:10:14 +01:00
|
|
|
* "initialization," and NormalProcessing or "normal."
|
|
|
|
*
|
1999-10-06 23:58:18 +02:00
|
|
|
* The first two processing modes are used during special times. When the
|
1996-10-31 08:10:14 +01:00
|
|
|
* system state indicates bootstrap processing, transactions are all given
|
2001-01-14 06:08:17 +01:00
|
|
|
* transaction id "one" and are consequently guaranteed to commit. This mode
|
1996-10-31 08:10:14 +01:00
|
|
|
* is used during the initial generation of template databases.
|
|
|
|
*
|
2001-01-14 06:08:17 +01:00
|
|
|
* Initialization mode: used while starting a backend, until all normal
|
|
|
|
* initialization is complete. Some code behaves differently when executed
|
|
|
|
* in this mode to enable system bootstrapping.
|
1999-10-06 23:58:18 +02:00
|
|
|
*
|
Fix management of pendingOpsTable in auxiliary processes.
mdinit() was misusing IsBootstrapProcessingMode() to decide whether to
create an fsync pending-operations table in the current process. This led
to creating a table not only in the startup and checkpointer processes as
intended, but also in the bgwriter process, not to mention other auxiliary
processes such as walwriter and walreceiver. Creation of the table in the
bgwriter is fatal, because it absorbs fsync requests that should have gone
to the checkpointer; instead they just sit in bgwriter local memory and are
never acted on. So writes performed by the bgwriter were not being fsync'd
which could result in data loss after an OS crash. I think there is no
live bug with respect to walwriter and walreceiver because those never
perform any writes of shared buffers; but the potential is there for
future breakage in those processes too.
To fix, make AuxiliaryProcessMain() export the current process's
AuxProcType as a global variable, and then make mdinit() test directly for
the types of aux process that should have a pendingOpsTable. Having done
that, we might as well also get rid of the random bool flags such as
am_walreceiver that some of the aux processes had grown. (Note that we
could not have fixed the bug by examining those variables in mdinit(),
because it's called from BaseInit() which is run by AuxiliaryProcessMain()
before entering any of the process-type-specific code.)
Back-patch to 9.2, where the problem was introduced by the split-up of
bgwriter and checkpointer processes. The bogus pendingOpsTable exists
in walwriter and walreceiver processes in earlier branches, but absent
any evidence that it causes actual problems there, I'll leave the older
branches alone.
2012-07-18 21:28:10 +02:00
|
|
|
* If a POSTGRES backend process is in normal mode, then all code may be
|
|
|
|
* executed normally.
|
1996-10-31 08:10:14 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
typedef enum ProcessingMode
|
|
|
|
{
|
|
|
|
BootstrapProcessing, /* bootstrap creation of template database */
|
|
|
|
InitProcessing, /* initializing system */
|
|
|
|
NormalProcessing /* normal processing */
|
|
|
|
} ProcessingMode;
|
|
|
|
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT ProcessingMode Mode;
|
2000-01-13 19:26:18 +01:00
|
|
|
|
Fix management of pendingOpsTable in auxiliary processes.
mdinit() was misusing IsBootstrapProcessingMode() to decide whether to
create an fsync pending-operations table in the current process. This led
to creating a table not only in the startup and checkpointer processes as
intended, but also in the bgwriter process, not to mention other auxiliary
processes such as walwriter and walreceiver. Creation of the table in the
bgwriter is fatal, because it absorbs fsync requests that should have gone
to the checkpointer; instead they just sit in bgwriter local memory and are
never acted on. So writes performed by the bgwriter were not being fsync'd
which could result in data loss after an OS crash. I think there is no
live bug with respect to walwriter and walreceiver because those never
perform any writes of shared buffers; but the potential is there for
future breakage in those processes too.
To fix, make AuxiliaryProcessMain() export the current process's
AuxProcType as a global variable, and then make mdinit() test directly for
the types of aux process that should have a pendingOpsTable. Having done
that, we might as well also get rid of the random bool flags such as
am_walreceiver that some of the aux processes had grown. (Note that we
could not have fixed the bug by examining those variables in mdinit(),
because it's called from BaseInit() which is run by AuxiliaryProcessMain()
before entering any of the process-type-specific code.)
Back-patch to 9.2, where the problem was introduced by the split-up of
bgwriter and checkpointer processes. The bogus pendingOpsTable exists
in walwriter and walreceiver processes in earlier branches, but absent
any evidence that it causes actual problems there, I'll leave the older
branches alone.
2012-07-18 21:28:10 +02:00
|
|
|
#define IsBootstrapProcessingMode() (Mode == BootstrapProcessing)
|
|
|
|
#define IsInitProcessingMode() (Mode == InitProcessing)
|
|
|
|
#define IsNormalProcessingMode() (Mode == NormalProcessing)
|
|
|
|
|
|
|
|
#define GetProcessingMode() Mode
|
2000-01-13 19:26:18 +01:00
|
|
|
|
|
|
|
#define SetProcessingMode(mode) \
|
|
|
|
do { \
|
2001-01-14 06:08:17 +01:00
|
|
|
AssertArg((mode) == BootstrapProcessing || \
|
|
|
|
(mode) == InitProcessing || \
|
|
|
|
(mode) == NormalProcessing); \
|
|
|
|
Mode = (mode); \
|
2000-01-13 19:26:18 +01:00
|
|
|
} while(0)
|
1996-10-31 08:10:14 +01:00
|
|
|
|
Fix management of pendingOpsTable in auxiliary processes.
mdinit() was misusing IsBootstrapProcessingMode() to decide whether to
create an fsync pending-operations table in the current process. This led
to creating a table not only in the startup and checkpointer processes as
intended, but also in the bgwriter process, not to mention other auxiliary
processes such as walwriter and walreceiver. Creation of the table in the
bgwriter is fatal, because it absorbs fsync requests that should have gone
to the checkpointer; instead they just sit in bgwriter local memory and are
never acted on. So writes performed by the bgwriter were not being fsync'd
which could result in data loss after an OS crash. I think there is no
live bug with respect to walwriter and walreceiver because those never
perform any writes of shared buffers; but the potential is there for
future breakage in those processes too.
To fix, make AuxiliaryProcessMain() export the current process's
AuxProcType as a global variable, and then make mdinit() test directly for
the types of aux process that should have a pendingOpsTable. Having done
that, we might as well also get rid of the random bool flags such as
am_walreceiver that some of the aux processes had grown. (Note that we
could not have fixed the bug by examining those variables in mdinit(),
because it's called from BaseInit() which is run by AuxiliaryProcessMain()
before entering any of the process-type-specific code.)
Back-patch to 9.2, where the problem was introduced by the split-up of
bgwriter and checkpointer processes. The bogus pendingOpsTable exists
in walwriter and walreceiver processes in earlier branches, but absent
any evidence that it causes actual problems there, I'll leave the older
branches alone.
2012-07-18 21:28:10 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Auxiliary-process type identifiers. These used to be in bootstrap.h
|
|
|
|
* but it seems saner to have them here, with the ProcessingMode stuff.
|
2021-08-05 21:09:19 +02:00
|
|
|
* The MyAuxProcType global is defined and set in auxprocess.c.
|
2021-09-20 17:22:02 +02:00
|
|
|
*
|
|
|
|
* Make sure to list in the glossary any items you add here.
|
Fix management of pendingOpsTable in auxiliary processes.
mdinit() was misusing IsBootstrapProcessingMode() to decide whether to
create an fsync pending-operations table in the current process. This led
to creating a table not only in the startup and checkpointer processes as
intended, but also in the bgwriter process, not to mention other auxiliary
processes such as walwriter and walreceiver. Creation of the table in the
bgwriter is fatal, because it absorbs fsync requests that should have gone
to the checkpointer; instead they just sit in bgwriter local memory and are
never acted on. So writes performed by the bgwriter were not being fsync'd
which could result in data loss after an OS crash. I think there is no
live bug with respect to walwriter and walreceiver because those never
perform any writes of shared buffers; but the potential is there for
future breakage in those processes too.
To fix, make AuxiliaryProcessMain() export the current process's
AuxProcType as a global variable, and then make mdinit() test directly for
the types of aux process that should have a pendingOpsTable. Having done
that, we might as well also get rid of the random bool flags such as
am_walreceiver that some of the aux processes had grown. (Note that we
could not have fixed the bug by examining those variables in mdinit(),
because it's called from BaseInit() which is run by AuxiliaryProcessMain()
before entering any of the process-type-specific code.)
Back-patch to 9.2, where the problem was introduced by the split-up of
bgwriter and checkpointer processes. The bogus pendingOpsTable exists
in walwriter and walreceiver processes in earlier branches, but absent
any evidence that it causes actual problems there, I'll leave the older
branches alone.
2012-07-18 21:28:10 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
NotAnAuxProcess = -1,
|
2021-08-05 21:17:31 +02:00
|
|
|
StartupProcess = 0,
|
Fix management of pendingOpsTable in auxiliary processes.
mdinit() was misusing IsBootstrapProcessingMode() to decide whether to
create an fsync pending-operations table in the current process. This led
to creating a table not only in the startup and checkpointer processes as
intended, but also in the bgwriter process, not to mention other auxiliary
processes such as walwriter and walreceiver. Creation of the table in the
bgwriter is fatal, because it absorbs fsync requests that should have gone
to the checkpointer; instead they just sit in bgwriter local memory and are
never acted on. So writes performed by the bgwriter were not being fsync'd
which could result in data loss after an OS crash. I think there is no
live bug with respect to walwriter and walreceiver because those never
perform any writes of shared buffers; but the potential is there for
future breakage in those processes too.
To fix, make AuxiliaryProcessMain() export the current process's
AuxProcType as a global variable, and then make mdinit() test directly for
the types of aux process that should have a pendingOpsTable. Having done
that, we might as well also get rid of the random bool flags such as
am_walreceiver that some of the aux processes had grown. (Note that we
could not have fixed the bug by examining those variables in mdinit(),
because it's called from BaseInit() which is run by AuxiliaryProcessMain()
before entering any of the process-type-specific code.)
Back-patch to 9.2, where the problem was introduced by the split-up of
bgwriter and checkpointer processes. The bogus pendingOpsTable exists
in walwriter and walreceiver processes in earlier branches, but absent
any evidence that it causes actual problems there, I'll leave the older
branches alone.
2012-07-18 21:28:10 +02:00
|
|
|
BgWriterProcess,
|
Make archiver process an auxiliary process.
This commit changes WAL archiver process so that it's treated as
an auxiliary process and can use shared memory. This is an infrastructure
patch required for upcoming shared-memory based stats collector patch
series. These patch series basically need any processes including archiver
that can report the statistics to access to shared memory. Since this patch
itself is useful to simplify the code and when users monitor the status of
archiver, it's committed separately in advance.
This commit simplifies the code for WAL archiving. For example, previously
backends need to signal to archiver via postmaster when they notify
archiver that there are some WAL files to archive. On the other hand,
this commit removes that signal to postmaster and enables backends to
notify archier directly using shared latch.
Also, as the side of this change, the information about archiver process
becomes viewable at pg_stat_activity view.
Author: Kyotaro Horiguchi
Reviewed-by: Andres Freund, Álvaro Herrera, Julien Rouhaud, Tomas Vondra, Arthur Zakirov, Fujii Masao
Discussion: https://postgr.es/m/20180629.173418.190173462.horiguchi.kyotaro@lab.ntt.co.jp
2021-03-15 05:13:14 +01:00
|
|
|
ArchiverProcess,
|
Fix management of pendingOpsTable in auxiliary processes.
mdinit() was misusing IsBootstrapProcessingMode() to decide whether to
create an fsync pending-operations table in the current process. This led
to creating a table not only in the startup and checkpointer processes as
intended, but also in the bgwriter process, not to mention other auxiliary
processes such as walwriter and walreceiver. Creation of the table in the
bgwriter is fatal, because it absorbs fsync requests that should have gone
to the checkpointer; instead they just sit in bgwriter local memory and are
never acted on. So writes performed by the bgwriter were not being fsync'd
which could result in data loss after an OS crash. I think there is no
live bug with respect to walwriter and walreceiver because those never
perform any writes of shared buffers; but the potential is there for
future breakage in those processes too.
To fix, make AuxiliaryProcessMain() export the current process's
AuxProcType as a global variable, and then make mdinit() test directly for
the types of aux process that should have a pendingOpsTable. Having done
that, we might as well also get rid of the random bool flags such as
am_walreceiver that some of the aux processes had grown. (Note that we
could not have fixed the bug by examining those variables in mdinit(),
because it's called from BaseInit() which is run by AuxiliaryProcessMain()
before entering any of the process-type-specific code.)
Back-patch to 9.2, where the problem was introduced by the split-up of
bgwriter and checkpointer processes. The bogus pendingOpsTable exists
in walwriter and walreceiver processes in earlier branches, but absent
any evidence that it causes actual problems there, I'll leave the older
branches alone.
2012-07-18 21:28:10 +02:00
|
|
|
CheckpointerProcess,
|
|
|
|
WalWriterProcess,
|
|
|
|
WalReceiverProcess,
|
|
|
|
|
|
|
|
NUM_AUXPROCTYPES /* Must be last! */
|
|
|
|
} AuxProcType;
|
|
|
|
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT AuxProcType MyAuxProcType;
|
Fix management of pendingOpsTable in auxiliary processes.
mdinit() was misusing IsBootstrapProcessingMode() to decide whether to
create an fsync pending-operations table in the current process. This led
to creating a table not only in the startup and checkpointer processes as
intended, but also in the bgwriter process, not to mention other auxiliary
processes such as walwriter and walreceiver. Creation of the table in the
bgwriter is fatal, because it absorbs fsync requests that should have gone
to the checkpointer; instead they just sit in bgwriter local memory and are
never acted on. So writes performed by the bgwriter were not being fsync'd
which could result in data loss after an OS crash. I think there is no
live bug with respect to walwriter and walreceiver because those never
perform any writes of shared buffers; but the potential is there for
future breakage in those processes too.
To fix, make AuxiliaryProcessMain() export the current process's
AuxProcType as a global variable, and then make mdinit() test directly for
the types of aux process that should have a pendingOpsTable. Having done
that, we might as well also get rid of the random bool flags such as
am_walreceiver that some of the aux processes had grown. (Note that we
could not have fixed the bug by examining those variables in mdinit(),
because it's called from BaseInit() which is run by AuxiliaryProcessMain()
before entering any of the process-type-specific code.)
Back-patch to 9.2, where the problem was introduced by the split-up of
bgwriter and checkpointer processes. The bogus pendingOpsTable exists
in walwriter and walreceiver processes in earlier branches, but absent
any evidence that it causes actual problems there, I'll leave the older
branches alone.
2012-07-18 21:28:10 +02:00
|
|
|
|
|
|
|
#define AmStartupProcess() (MyAuxProcType == StartupProcess)
|
|
|
|
#define AmBackgroundWriterProcess() (MyAuxProcType == BgWriterProcess)
|
Make archiver process an auxiliary process.
This commit changes WAL archiver process so that it's treated as
an auxiliary process and can use shared memory. This is an infrastructure
patch required for upcoming shared-memory based stats collector patch
series. These patch series basically need any processes including archiver
that can report the statistics to access to shared memory. Since this patch
itself is useful to simplify the code and when users monitor the status of
archiver, it's committed separately in advance.
This commit simplifies the code for WAL archiving. For example, previously
backends need to signal to archiver via postmaster when they notify
archiver that there are some WAL files to archive. On the other hand,
this commit removes that signal to postmaster and enables backends to
notify archier directly using shared latch.
Also, as the side of this change, the information about archiver process
becomes viewable at pg_stat_activity view.
Author: Kyotaro Horiguchi
Reviewed-by: Andres Freund, Álvaro Herrera, Julien Rouhaud, Tomas Vondra, Arthur Zakirov, Fujii Masao
Discussion: https://postgr.es/m/20180629.173418.190173462.horiguchi.kyotaro@lab.ntt.co.jp
2021-03-15 05:13:14 +01:00
|
|
|
#define AmArchiverProcess() (MyAuxProcType == ArchiverProcess)
|
Fix management of pendingOpsTable in auxiliary processes.
mdinit() was misusing IsBootstrapProcessingMode() to decide whether to
create an fsync pending-operations table in the current process. This led
to creating a table not only in the startup and checkpointer processes as
intended, but also in the bgwriter process, not to mention other auxiliary
processes such as walwriter and walreceiver. Creation of the table in the
bgwriter is fatal, because it absorbs fsync requests that should have gone
to the checkpointer; instead they just sit in bgwriter local memory and are
never acted on. So writes performed by the bgwriter were not being fsync'd
which could result in data loss after an OS crash. I think there is no
live bug with respect to walwriter and walreceiver because those never
perform any writes of shared buffers; but the potential is there for
future breakage in those processes too.
To fix, make AuxiliaryProcessMain() export the current process's
AuxProcType as a global variable, and then make mdinit() test directly for
the types of aux process that should have a pendingOpsTable. Having done
that, we might as well also get rid of the random bool flags such as
am_walreceiver that some of the aux processes had grown. (Note that we
could not have fixed the bug by examining those variables in mdinit(),
because it's called from BaseInit() which is run by AuxiliaryProcessMain()
before entering any of the process-type-specific code.)
Back-patch to 9.2, where the problem was introduced by the split-up of
bgwriter and checkpointer processes. The bogus pendingOpsTable exists
in walwriter and walreceiver processes in earlier branches, but absent
any evidence that it causes actual problems there, I'll leave the older
branches alone.
2012-07-18 21:28:10 +02:00
|
|
|
#define AmCheckpointerProcess() (MyAuxProcType == CheckpointerProcess)
|
|
|
|
#define AmWalWriterProcess() (MyAuxProcType == WalWriterProcess)
|
|
|
|
#define AmWalReceiverProcess() (MyAuxProcType == WalReceiverProcess)
|
1997-09-08 04:41:22 +02:00
|
|
|
|
2001-09-27 18:29:13 +02:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* pinit.h -- *
|
|
|
|
* POSTGRES initialization and cleanup definitions. *
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/* in utils/init/postinit.c */
|
2015-06-29 18:42:52 +02:00
|
|
|
extern void pg_split_opts(char **argv, int *argcp, const char *optstr);
|
2013-01-02 18:39:11 +01:00
|
|
|
extern void InitializeMaxBackends(void);
|
Process session_preload_libraries within InitPostgres's transaction.
Previously we did this after InitPostgres, at a somewhat randomly chosen
place within PostgresMain. However, since commit a0ffa885e doing this
outside a transaction can cause a crash, if we need to check permissions
while replacing a placeholder GUC. (Besides which, a preloaded library
could itself want to do database access within _PG_init.)
To avoid needing an additional transaction start/end in every session,
move the process_session_preload_libraries call to within InitPostgres's
transaction. That requires teaching the code not to call it when
InitPostgres is called from somewhere other than PostgresMain, since
we don't want session_preload_libraries to affect background workers.
The most future-proof solution here seems to be to add an additional
flag parameter to InitPostgres; fortunately, we're not yet very worried
about API stability for v15.
Doing this also exposed the fact that we're currently honoring
session_preload_libraries in walsenders, even those not connected to
any database. This seems, at minimum, a POLA violation: walsenders
are not interactive sessions. Let's stop doing that.
(All these comments also apply to local_preload_libraries, of course.)
Per report from Gurjeet Singh (thanks also to Nathan Bossart and Kyotaro
Horiguchi for review). Backpatch to v15 where a0ffa885e came in.
Discussion: https://postgr.es/m/CABwTF4VEpwTHhRQ+q5MiC5ucngN-whN-PdcKeufX7eLSoAfbZA@mail.gmail.com
2022-07-25 16:27:43 +02:00
|
|
|
extern void InitPostgres(const char *in_dbname, Oid dboid,
|
|
|
|
const char *username, Oid useroid,
|
|
|
|
bool load_session_libraries,
|
|
|
|
bool override_allow_connections,
|
|
|
|
char *out_dbname);
|
2001-09-27 18:29:13 +02:00
|
|
|
extern void BaseInit(void);
|
|
|
|
|
|
|
|
/* in utils/init/miscinit.c */
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT bool IgnoreSystemIndexes;
|
2009-01-03 21:03:08 +01:00
|
|
|
extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress;
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT bool process_shared_preload_libraries_done;
|
2022-05-13 15:31:06 +02:00
|
|
|
extern PGDLLIMPORT bool process_shmem_requests_in_progress;
|
2022-04-08 14:16:38 +02:00
|
|
|
extern PGDLLIMPORT char *session_preload_libraries_string;
|
|
|
|
extern PGDLLIMPORT char *shared_preload_libraries_string;
|
|
|
|
extern PGDLLIMPORT char *local_preload_libraries_string;
|
2006-08-08 21:15:09 +02:00
|
|
|
|
2005-07-04 06:51:52 +02:00
|
|
|
extern void CreateDataDirLockFile(bool amPostmaster);
|
2012-08-10 23:26:44 +02:00
|
|
|
extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster,
|
|
|
|
const char *socketDir);
|
|
|
|
extern void TouchSocketLockFiles(void);
|
2011-01-14 01:01:28 +01:00
|
|
|
extern void AddToDataDirLockFile(int target_line, const char *str);
|
Perform an immediate shutdown if the postmaster.pid file is removed.
The postmaster now checks every minute or so (worst case, at most two
minutes) that postmaster.pid is still there and still contains its own PID.
If not, it performs an immediate shutdown, as though it had received
SIGQUIT.
The original goal behind this change was to ensure that failed buildfarm
runs would get fully cleaned up, even if the test scripts had left a
postmaster running, which is not an infrequent occurrence. When the
buildfarm script removes a test postmaster's $PGDATA directory, its next
check on postmaster.pid will fail and cause it to exit. Previously, manual
intervention was often needed to get rid of such orphaned postmasters,
since they'd block new test postmasters from obtaining the expected socket
address.
However, by checking postmaster.pid and not something else, we can provide
additional robustness: manual removal of postmaster.pid is a frequent DBA
mistake, and now we can at least limit the damage that will ensue if a new
postmaster is started while the old one is still alive.
Back-patch to all supported branches, since we won't get the desired
improvement in buildfarm reliability otherwise.
2015-10-06 23:15:27 +02:00
|
|
|
extern bool RecheckDataDirLockFile(void);
|
2000-07-02 17:21:27 +02:00
|
|
|
extern void ValidatePgVersion(const char *path);
|
2006-08-15 20:26:59 +02:00
|
|
|
extern void process_shared_preload_libraries(void);
|
2013-06-13 04:28:24 +02:00
|
|
|
extern void process_session_preload_libraries(void);
|
2022-05-13 15:31:06 +02:00
|
|
|
extern void process_shmem_requests(void);
|
2008-12-11 08:34:09 +01:00
|
|
|
extern void pg_bindtextdomain(const char *domain);
|
2013-04-01 19:09:24 +02:00
|
|
|
extern bool has_rolreplication(Oid roleid);
|
2000-07-02 17:21:27 +02:00
|
|
|
|
2022-05-13 15:31:06 +02:00
|
|
|
typedef void (*shmem_request_hook_type) (void);
|
|
|
|
extern PGDLLIMPORT shmem_request_hook_type shmem_request_hook;
|
|
|
|
|
Allow parallel workers to retrieve some data from Port
This commit moves authn_id into a new global structure called
ClientConnectionInfo (mapping to a MyClientConnectionInfo for each
backend) which is intended to hold all the client information that
should be shared between the backend and any of its parallel workers,
access for extensions and triggers being the primary use case. There is
no need to push all the data of Port to the workers, and authn_id is
quite a generic concept so using a separate structure provides the best
balance (the name of the structure has been suggested by Robert Haas).
While on it, and per discussion as this would be useful for a potential
SYSTEM_USER that can be accessed through parallel workers, a second
field is added for the authentication method, copied directly from
Port.
ClientConnectionInfo is serialized and restored using a new parallel
key and a structure tracks the length of the authn_id, making the
addition of more fields straight-forward.
Author: Jacob Champion
Reviewed-by: Bertrand Drouvot, Stephen Frost, Robert Haas, Tom Lane,
Michael Paquier, Julien Rouhaud
Discussion: https://postgr.es/m/793d990837ae5c06a558d58d62de9378ab525d83.camel@vmware.com
2022-08-24 05:57:13 +02:00
|
|
|
extern Size EstimateClientConnectionInfoSpace(void);
|
|
|
|
extern void SerializeClientConnectionInfo(Size maxsize, char *start_address);
|
|
|
|
extern void RestoreClientConnectionInfo(char *conninfo);
|
|
|
|
|
2020-07-29 23:14:58 +02:00
|
|
|
/* in executor/nodeHash.c */
|
Get rid of artificial restriction on hash table sizes on Windows.
The point of introducing the hash_mem_multiplier GUC was to let users
reproduce the old behavior of hash aggregation, i.e. that it could use
more than work_mem at need. However, the implementation failed to get
the job done on Win64, where work_mem is clamped to 2GB to protect
various places that calculate memory sizes using "long int". As
written, the same clamp was applied to hash_mem. This resulted in
severe performance regressions for queries requiring a bit more than
2GB for hash aggregation, as they now spill to disk and there's no
way to stop that.
Getting rid of the work_mem restriction seems like a good idea, but
it's a big job and could not conceivably be back-patched. However,
there's only a fairly small number of places that are concerned with
the hash_mem value, and it turns out to be possible to remove the
restriction there without too much code churn or any ABI breaks.
So, let's do that for now to fix the regression, and leave the
larger task for another day.
This patch does introduce a bit more infrastructure that should help
with the larger task, namely pg_bitutils.h support for working with
size_t values.
Per gripe from Laurent Hasson. Back-patch to v13 where the
behavior change came in.
Discussion: https://postgr.es/m/997817.1627074924@sss.pgh.pa.us
Discussion: https://postgr.es/m/MN2PR15MB25601E80A9B6D1BA6F592B1985E39@MN2PR15MB2560.namprd15.prod.outlook.com
2021-07-25 20:02:27 +02:00
|
|
|
extern size_t get_hash_memory_limit(void);
|
2020-07-29 23:14:58 +02:00
|
|
|
|
1996-10-31 08:10:14 +01:00
|
|
|
#endif /* MISCADMIN_H */
|