|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* miscinit.c
|
|
|
|
* miscellaneous initialization support stuff
|
|
|
|
*
|
|
|
|
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
|
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
|
|
|
* src/backend/utils/init/miscinit.c
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <sys/file.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <grp.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <utime.h>
|
|
|
|
|
|
|
|
#include "access/htup_details.h"
|
|
|
|
#include "catalog/pg_authid.h"
|
|
|
|
#include "common/file_perm.h"
|
Introduce WaitEventSet API.
Commit ac1d794 ("Make idle backends exit if the postmaster dies.")
introduced a regression on, at least, large linux systems. Constantly
adding the same postmaster_alive_fds to the OSs internal datastructures
for implementing poll/select can cause significant contention; leading
to a performance regression of nearly 3x in one example.
This can be avoided by using e.g. linux' epoll, which avoids having to
add/remove file descriptors to the wait datastructures at a high rate.
Unfortunately the current latch interface makes it hard to allocate any
persistent per-backend resources.
Replace, with a backward compatibility layer, WaitLatchOrSocket with a
new WaitEventSet API. Users can allocate such a Set across multiple
calls, and add more than one file-descriptor to wait on. The latter has
been added because there's upcoming postgres features where that will be
helpful.
In addition to the previously existing poll(2), select(2),
WaitForMultipleObjects() implementations also provide an epoll_wait(2)
based implementation to address the aforementioned performance
problem. Epoll is only available on linux, but that is the most likely
OS for machines large enough (four sockets) to reproduce the problem.
To actually address the aforementioned regression, create and use a
long-lived WaitEventSet for FE/BE communication. There are additional
places that would benefit from a long-lived set, but that's a task for
another day.
Thanks to Amit Kapila, who helped make the windows code I blindly wrote
actually work.
Reported-By: Dmitry Vasilyev Discussion:
CAB-SwXZh44_2ybvS5Z67p_CDz=XFn4hNAD=CnMEF+QqkXwFrGg@mail.gmail.com
20160114143931.GG10941@awork2.anarazel.de
9 years ago
|
|
|
#include "libpq/libpq.h"
|
Centralize setup of SIGQUIT handling for postmaster child processes.
We decided that the policy established in commit 7634bd4f6 for
the bgwriter, checkpointer, walwriter, and walreceiver processes,
namely that they should accept SIGQUIT at all times, really ought
to apply uniformly to all postmaster children. Therefore, get
rid of the duplicative and inconsistent per-process code for
establishing that signal handler and removing SIGQUIT from BlockSig.
Instead, make InitPostmasterChild do it.
The handler set up by InitPostmasterChild is SignalHandlerForCrashExit,
which just summarily does _exit(2). In interactive backends, we
almost immediately replace that with quickdie, since we would prefer
to try to tell the client that we're dying. However, this patch is
changing the behavior of autovacuum (both launcher and workers), as
well as walsenders. Those processes formerly also used quickdie,
but AFAICS that was just mindless copy-and-paste: they don't have
any interactive client that's likely to benefit from being told this.
The stats collector continues to be an outlier, in that it thinks
SIGQUIT means normal exit. That should probably be changed for
consistency, but there's another patch set where that's being
dealt with, so I didn't do so here.
Discussion: https://postgr.es/m/644875.1599933441@sss.pgh.pa.us
5 years ago
|
|
|
#include "libpq/pqsignal.h"
|
|
|
|
#include "mb/pg_wchar.h"
|
|
|
|
#include "miscadmin.h"
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
#include "pgstat.h"
|
|
|
|
#include "postmaster/autovacuum.h"
|
Centralize setup of SIGQUIT handling for postmaster child processes.
We decided that the policy established in commit 7634bd4f6 for
the bgwriter, checkpointer, walwriter, and walreceiver processes,
namely that they should accept SIGQUIT at all times, really ought
to apply uniformly to all postmaster children. Therefore, get
rid of the duplicative and inconsistent per-process code for
establishing that signal handler and removing SIGQUIT from BlockSig.
Instead, make InitPostmasterChild do it.
The handler set up by InitPostmasterChild is SignalHandlerForCrashExit,
which just summarily does _exit(2). In interactive backends, we
almost immediately replace that with quickdie, since we would prefer
to try to tell the client that we're dying. However, this patch is
changing the behavior of autovacuum (both launcher and workers), as
well as walsenders. Those processes formerly also used quickdie,
but AFAICS that was just mindless copy-and-paste: they don't have
any interactive client that's likely to benefit from being told this.
The stats collector continues to be an outlier, in that it thinks
SIGQUIT means normal exit. That should probably be changed for
consistency, but there's another patch set where that's being
dealt with, so I didn't do so here.
Discussion: https://postgr.es/m/644875.1599933441@sss.pgh.pa.us
5 years ago
|
|
|
#include "postmaster/interrupt.h"
|
|
|
|
#include "postmaster/pgarch.h"
|
|
|
|
#include "postmaster/postmaster.h"
|
|
|
|
#include "storage/fd.h"
|
|
|
|
#include "storage/ipc.h"
|
|
|
|
#include "storage/latch.h"
|
|
|
|
#include "storage/pg_shmem.h"
|
|
|
|
#include "storage/pmsignal.h"
|
|
|
|
#include "storage/proc.h"
|
|
|
|
#include "storage/procarray.h"
|
|
|
|
#include "utils/builtins.h"
|
|
|
|
#include "utils/guc.h"
|
|
|
|
#include "utils/inval.h"
|
|
|
|
#include "utils/memutils.h"
|
Change pg_ctl to detect server-ready by watching status in postmaster.pid.
Traditionally, "pg_ctl start -w" has waited for the server to become
ready to accept connections by attempting a connection once per second.
That has the major problem that connection issues (for instance, a
kernel packet filter blocking traffic) can't be reliably told apart
from server startup issues, and the minor problem that if server startup
isn't quick, we accumulate "the database system is starting up" spam
in the server log. We've hacked around many of the possible connection
issues, but it resulted in ugly and complicated code in pg_ctl.c.
In commit c61559ec3, I changed the probe rate to every tenth of a second.
That prompted Jeff Janes to complain that the log-spam problem had become
much worse. In the ensuing discussion, Andres Freund pointed out that
we could dispense with connection attempts altogether if the postmaster
were changed to report its status in postmaster.pid, which "pg_ctl start"
already relies on being able to read. This patch implements that, teaching
postmaster.c to report a status string into the pidfile at the same
state-change points already identified as being of interest for systemd
status reporting (cf commit 7d17e683f). pg_ctl no longer needs to link
with libpq at all; all its functions now depend on reading server files.
In support of this, teach AddToDataDirLockFile() to allow addition of
postmaster.pid lines in not-necessarily-sequential order. This is needed
on Windows where the SHMEM_KEY line will never be written at all. We still
have the restriction that we don't want to truncate the pidfile; document
the reasons for that a bit better.
Also, fix the pg_ctl TAP tests so they'll notice if "start -w" mode
is broken --- before, they'd just wait out the sixty seconds until
the loop gives up, and then report success anyway. (Yes, I found that
out the hard way.)
While at it, arrange for pg_ctl to not need to #include miscadmin.h;
as a rather low-level backend header, requiring that to be compilable
client-side is pretty dubious. This requires moving the #define's
associated with the pidfile into a new header file, and moving
PG_BACKEND_VERSIONSTR someplace else. For lack of a clearly better
"someplace else", I put it into port.h, beside the declaration of
find_other_exec(), since most users of that macro are passing the value to
find_other_exec(). (initdb still depends on miscadmin.h, but at least
pg_ctl and pg_upgrade no longer do.)
In passing, fix main.c so that PG_BACKEND_VERSIONSTR actually defines the
output of "postgres -V", which remarkably it had never done before.
Discussion: https://postgr.es/m/CAMkU=1xJW8e+CTotojOMBd-yzUvD0e_JZu2xHo=MnuZ4__m7Pg@mail.gmail.com
8 years ago
|
|
|
#include "utils/pidfile.h"
|
|
|
|
#include "utils/syscache.h"
|
|
|
|
#include "utils/varlena.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define DIRECTORY_LOCK_FILE "postmaster.pid"
|
|
|
|
|
|
|
|
ProcessingMode Mode = InitProcessing;
|
|
|
|
|
|
|
|
BackendType MyBackendType;
|
|
|
|
|
|
|
|
/* List of lock files to be removed at proc exit */
|
|
|
|
static List *lock_files = NIL;
|
|
|
|
|
|
|
|
static Latch LocalLatchData;
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
|
|
|
* ignoring system indexes support stuff
|
|
|
|
*
|
|
|
|
* NOTE: "ignoring system indexes" means we do not use the system indexes
|
|
|
|
* for lookups (either in hardwired catalog accesses or in planner-generated
|
|
|
|
* plans). We do, however, still update the indexes when a catalog
|
|
|
|
* modification is made.
|
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool IgnoreSystemIndexes = false;
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
|
|
|
* common process startup code
|
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize the basic environment for a postmaster child
|
|
|
|
*
|
|
|
|
* Should be called as early as possible after the child's startup. However,
|
|
|
|
* on EXEC_BACKEND builds it does need to be after read_backend_variables().
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
InitPostmasterChild(void)
|
|
|
|
{
|
|
|
|
IsUnderPostmaster = true; /* we are a postmaster subprocess now */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Start our win32 signal implementation. This has to be done after we
|
|
|
|
* read the backend variables, because we need to pick up the signal pipe
|
|
|
|
* from the parent process.
|
|
|
|
*/
|
|
|
|
#ifdef WIN32
|
|
|
|
pgwin32_signal_initialize();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set reference point for stack-depth checking. This might seem
|
|
|
|
* redundant in !EXEC_BACKEND builds; but it's not because the postmaster
|
|
|
|
* launches its children from signal handlers, so we might be running on
|
|
|
|
* an alternative stack.
|
|
|
|
*/
|
|
|
|
(void) set_stack_base();
|
|
|
|
|
|
|
|
InitProcessGlobals();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* make sure stderr is in binary mode before anything can possibly be
|
|
|
|
* written to it, in case it's actually the syslogger pipe, so the pipe
|
|
|
|
* chunking protocol isn't disturbed. Non-logpipe data gets translated on
|
|
|
|
* redirection (e.g. via pg_ctl -l) anyway.
|
|
|
|
*/
|
|
|
|
#ifdef WIN32
|
|
|
|
_setmode(fileno(stderr), _O_BINARY);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* We don't want the postmaster's proc_exit() handlers */
|
|
|
|
on_exit_reset();
|
|
|
|
|
|
|
|
/* In EXEC_BACKEND case we will not have inherited BlockSig etc values */
|
|
|
|
#ifdef EXEC_BACKEND
|
|
|
|
pqinitmask();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Initialize process-local latch support */
|
|
|
|
InitializeLatchSupport();
|
|
|
|
MyLatch = &LocalLatchData;
|
|
|
|
InitLatch(MyLatch);
|
|
|
|
InitializeLatchWaitSet();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If possible, make this process a group leader, so that the postmaster
|
|
|
|
* can signal any child processes too. Not all processes will have
|
|
|
|
* children, but for consistency we make all postmaster child processes do
|
|
|
|
* this.
|
|
|
|
*/
|
|
|
|
#ifdef HAVE_SETSID
|
|
|
|
if (setsid() < 0)
|
|
|
|
elog(FATAL, "setsid() failed: %m");
|
|
|
|
#endif
|
|
|
|
|
Centralize setup of SIGQUIT handling for postmaster child processes.
We decided that the policy established in commit 7634bd4f6 for
the bgwriter, checkpointer, walwriter, and walreceiver processes,
namely that they should accept SIGQUIT at all times, really ought
to apply uniformly to all postmaster children. Therefore, get
rid of the duplicative and inconsistent per-process code for
establishing that signal handler and removing SIGQUIT from BlockSig.
Instead, make InitPostmasterChild do it.
The handler set up by InitPostmasterChild is SignalHandlerForCrashExit,
which just summarily does _exit(2). In interactive backends, we
almost immediately replace that with quickdie, since we would prefer
to try to tell the client that we're dying. However, this patch is
changing the behavior of autovacuum (both launcher and workers), as
well as walsenders. Those processes formerly also used quickdie,
but AFAICS that was just mindless copy-and-paste: they don't have
any interactive client that's likely to benefit from being told this.
The stats collector continues to be an outlier, in that it thinks
SIGQUIT means normal exit. That should probably be changed for
consistency, but there's another patch set where that's being
dealt with, so I didn't do so here.
Discussion: https://postgr.es/m/644875.1599933441@sss.pgh.pa.us
5 years ago
|
|
|
/*
|
|
|
|
* Every postmaster child process is expected to respond promptly to
|
|
|
|
* SIGQUIT at all times. Therefore we centrally remove SIGQUIT from
|
|
|
|
* BlockSig and install a suitable signal handler. (Client-facing
|
|
|
|
* processes may choose to replace this default choice of handler with
|
|
|
|
* quickdie().) All other blockable signals remain blocked for now.
|
|
|
|
*/
|
|
|
|
pqsignal(SIGQUIT, SignalHandlerForCrashExit);
|
|
|
|
|
|
|
|
sigdelset(&BlockSig, SIGQUIT);
|
|
|
|
PG_SETMASK(&BlockSig);
|
|
|
|
|
|
|
|
/* Request a signal if the postmaster dies, if possible. */
|
|
|
|
PostmasterDeathSignalInit();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize the basic environment for a standalone process.
|
|
|
|
*
|
|
|
|
* argv0 has to be suitable to find the program's executable.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
InitStandaloneProcess(const char *argv0)
|
|
|
|
{
|
|
|
|
Assert(!IsPostmasterEnvironment);
|
|
|
|
|
|
|
|
MyBackendType = B_STANDALONE_BACKEND;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Start our win32 signal implementation
|
|
|
|
*/
|
|
|
|
#ifdef WIN32
|
|
|
|
pgwin32_signal_initialize();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
InitProcessGlobals();
|
|
|
|
|
|
|
|
/* Initialize process-local latch support */
|
|
|
|
InitializeLatchSupport();
|
|
|
|
MyLatch = &LocalLatchData;
|
|
|
|
InitLatch(MyLatch);
|
|
|
|
InitializeLatchWaitSet();
|
|
|
|
|
Centralize setup of SIGQUIT handling for postmaster child processes.
We decided that the policy established in commit 7634bd4f6 for
the bgwriter, checkpointer, walwriter, and walreceiver processes,
namely that they should accept SIGQUIT at all times, really ought
to apply uniformly to all postmaster children. Therefore, get
rid of the duplicative and inconsistent per-process code for
establishing that signal handler and removing SIGQUIT from BlockSig.
Instead, make InitPostmasterChild do it.
The handler set up by InitPostmasterChild is SignalHandlerForCrashExit,
which just summarily does _exit(2). In interactive backends, we
almost immediately replace that with quickdie, since we would prefer
to try to tell the client that we're dying. However, this patch is
changing the behavior of autovacuum (both launcher and workers), as
well as walsenders. Those processes formerly also used quickdie,
but AFAICS that was just mindless copy-and-paste: they don't have
any interactive client that's likely to benefit from being told this.
The stats collector continues to be an outlier, in that it thinks
SIGQUIT means normal exit. That should probably be changed for
consistency, but there's another patch set where that's being
dealt with, so I didn't do so here.
Discussion: https://postgr.es/m/644875.1599933441@sss.pgh.pa.us
5 years ago
|
|
|
/*
|
|
|
|
* For consistency with InitPostmasterChild, initialize signal mask here.
|
|
|
|
* But we don't unblock SIGQUIT or provide a default handler for it.
|
|
|
|
*/
|
|
|
|
pqinitmask();
|
|
|
|
PG_SETMASK(&BlockSig);
|
|
|
|
|
|
|
|
/* Compute paths, no postmaster to inherit from */
|
|
|
|
if (my_exec_path[0] == '\0')
|
|
|
|
{
|
|
|
|
if (find_my_exec(argv0, my_exec_path) < 0)
|
|
|
|
elog(FATAL, "%s: could not locate my own executable path",
|
|
|
|
argv0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pkglib_path[0] == '\0')
|
|
|
|
get_pkglib_path(my_exec_path, pkglib_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SwitchToSharedLatch(void)
|
|
|
|
{
|
|
|
|
Assert(MyLatch == &LocalLatchData);
|
|
|
|
Assert(MyProc != NULL);
|
|
|
|
|
|
|
|
MyLatch = &MyProc->procLatch;
|
|
|
|
|
|
|
|
if (FeBeWaitSet)
|
|
|
|
ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetLatchPos, WL_LATCH_SET,
|
|
|
|
MyLatch);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the shared latch as the local one might have been set. This
|
|
|
|
* shouldn't normally be necessary as code is supposed to check the
|
|
|
|
* condition before waiting for the latch, but a bit care can't hurt.
|
|
|
|
*/
|
|
|
|
SetLatch(MyLatch);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SwitchBackToLocalLatch(void)
|
|
|
|
{
|
|
|
|
Assert(MyLatch != &LocalLatchData);
|
|
|
|
Assert(MyProc != NULL && MyLatch == &MyProc->procLatch);
|
|
|
|
|
|
|
|
MyLatch = &LocalLatchData;
|
|
|
|
|
|
|
|
if (FeBeWaitSet)
|
|
|
|
ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetLatchPos, WL_LATCH_SET,
|
|
|
|
MyLatch);
|
|
|
|
|
|
|
|
SetLatch(MyLatch);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
GetBackendTypeDesc(BackendType backendType)
|
|
|
|
{
|
|
|
|
const char *backendDesc = "unknown process type";
|
|
|
|
|
|
|
|
switch (backendType)
|
|
|
|
{
|
|
|
|
case B_INVALID:
|
|
|
|
backendDesc = "not initialized";
|
|
|
|
break;
|
|
|
|
case B_ARCHIVER:
|
|
|
|
backendDesc = "archiver";
|
|
|
|
break;
|
|
|
|
case B_AUTOVAC_LAUNCHER:
|
|
|
|
backendDesc = "autovacuum launcher";
|
|
|
|
break;
|
|
|
|
case B_AUTOVAC_WORKER:
|
|
|
|
backendDesc = "autovacuum worker";
|
|
|
|
break;
|
|
|
|
case B_BACKEND:
|
|
|
|
backendDesc = "client backend";
|
|
|
|
break;
|
|
|
|
case B_BG_WORKER:
|
|
|
|
backendDesc = "background worker";
|
|
|
|
break;
|
|
|
|
case B_BG_WRITER:
|
|
|
|
backendDesc = "background writer";
|
|
|
|
break;
|
|
|
|
case B_CHECKPOINTER:
|
|
|
|
backendDesc = "checkpointer";
|
|
|
|
break;
|
|
|
|
case B_LOGGER:
|
|
|
|
backendDesc = "logger";
|
|
|
|
break;
|
|
|
|
case B_STANDALONE_BACKEND:
|
|
|
|
backendDesc = "standalone backend";
|
|
|
|
break;
|
|
|
|
case B_STARTUP:
|
|
|
|
backendDesc = "startup";
|
|
|
|
break;
|
|
|
|
case B_WAL_RECEIVER:
|
|
|
|
backendDesc = "walreceiver";
|
|
|
|
break;
|
|
|
|
case B_WAL_SENDER:
|
|
|
|
backendDesc = "walsender";
|
|
|
|
break;
|
|
|
|
case B_WAL_WRITER:
|
|
|
|
backendDesc = "walwriter";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return backendDesc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
|
|
|
* database path / name support stuff
|
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
SetDatabasePath(const char *path)
|
|
|
|
{
|
|
|
|
/* This should happen only once per process */
|
|
|
|
Assert(!DatabasePath);
|
|
|
|
DatabasePath = MemoryContextStrdup(TopMemoryContext, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Validate the proposed data directory.
|
|
|
|
*
|
|
|
|
* Also initialize file and directory create modes and mode mask.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
checkDataDir(void)
|
|
|
|
{
|
|
|
|
struct stat stat_buf;
|
|
|
|
|
|
|
|
Assert(DataDir);
|
|
|
|
|
|
|
|
if (stat(DataDir, &stat_buf) != 0)
|
|
|
|
{
|
|
|
|
if (errno == ENOENT)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("data directory \"%s\" does not exist",
|
|
|
|
DataDir)));
|
|
|
|
else
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not read permissions of directory \"%s\": %m",
|
|
|
|
DataDir)));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* eventual chdir would fail anyway, but let's test ... */
|
|
|
|
if (!S_ISDIR(stat_buf.st_mode))
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
|
|
|
errmsg("specified data directory \"%s\" is not a directory",
|
|
|
|
DataDir)));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check that the directory belongs to my userid; if not, reject.
|
|
|
|
*
|
|
|
|
* This check is an essential part of the interlock that prevents two
|
|
|
|
* postmasters from starting in the same directory (see CreateLockFile()).
|
|
|
|
* Do not remove or weaken it.
|
|
|
|
*
|
|
|
|
* XXX can we safely enable this check on Windows?
|
|
|
|
*/
|
|
|
|
#if !defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
if (stat_buf.st_uid != geteuid())
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
|
|
|
errmsg("data directory \"%s\" has wrong ownership",
|
|
|
|
DataDir),
|
|
|
|
errhint("The server must be started by the user that owns the data directory.")));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if the directory has correct permissions. If not, reject.
|
|
|
|
*
|
|
|
|
* Only two possible modes are allowed, 0700 and 0750. The latter mode
|
|
|
|
* indicates that group read/execute should be allowed on all newly
|
|
|
|
* created files and directories.
|
|
|
|
*
|
|
|
|
* XXX temporarily suppress check when on Windows, because there may not
|
|
|
|
* be proper support for Unix-y file permissions. Need to think of a
|
|
|
|
* reasonable check to apply on Windows.
|
|
|
|
*/
|
|
|
|
#if !defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
if (stat_buf.st_mode & PG_MODE_MASK_GROUP)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
|
|
|
errmsg("data directory \"%s\" has invalid permissions",
|
|
|
|
DataDir),
|
|
|
|
errdetail("Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).")));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reset creation modes and mask based on the mode of the data directory.
|
|
|
|
*
|
|
|
|
* The mask was set earlier in startup to disallow group permissions on
|
|
|
|
* newly created files and directories. However, if group read/execute
|
|
|
|
* are present on the data directory then modify the create modes and mask
|
|
|
|
* to allow group read/execute on newly created files and directories and
|
|
|
|
* set the data_directory_mode GUC.
|
|
|
|
*
|
|
|
|
* Suppress when on Windows, because there may not be proper support for
|
|
|
|
* Unix-y file permissions.
|
|
|
|
*/
|
|
|
|
#if !defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
SetDataDirectoryCreatePerm(stat_buf.st_mode);
|
|
|
|
|
|
|
|
umask(pg_mode_mask);
|
|
|
|
data_directory_mode = pg_dir_create_mode;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Check for PG_VERSION */
|
|
|
|
ValidatePgVersion(DataDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set data directory, but make sure it's an absolute path. Use this,
|
|
|
|
* never set DataDir directly.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
SetDataDir(const char *dir)
|
|
|
|
{
|
|
|
|
char *new;
|
|
|
|
|
|
|
|
AssertArg(dir);
|
|
|
|
|
|
|
|
/* If presented path is relative, convert to absolute */
|
|
|
|
new = make_absolute_path(dir);
|
|
|
|
|
|
|
|
free(DataDir);
|
|
|
|
DataDir = new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Change working directory to DataDir. Most of the postmaster and backend
|
|
|
|
* code assumes that we are in DataDir so it can use relative paths to access
|
|
|
|
* stuff in and under the data directory. For convenience during path
|
|
|
|
* setup, however, we don't force the chdir to occur during SetDataDir.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ChangeToDataDir(void)
|
|
|
|
{
|
|
|
|
AssertState(DataDir);
|
|
|
|
|
|
|
|
if (chdir(DataDir) < 0)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not change directory to \"%s\": %m",
|
|
|
|
DataDir)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------
|
|
|
|
* User ID state
|
|
|
|
*
|
|
|
|
* We have to track several different values associated with the concept
|
|
|
|
* of "user ID".
|
|
|
|
*
|
|
|
|
* AuthenticatedUserId is determined at connection start and never changes.
|
|
|
|
*
|
|
|
|
* SessionUserId is initially the same as AuthenticatedUserId, but can be
|
|
|
|
* changed by SET SESSION AUTHORIZATION (if AuthenticatedUserIsSuperuser).
|
|
|
|
* This is the ID reported by the SESSION_USER SQL function.
|
|
|
|
*
|
|
|
|
* OuterUserId is the current user ID in effect at the "outer level" (outside
|
|
|
|
* any transaction or function). This is initially the same as SessionUserId,
|
|
|
|
* but can be changed by SET ROLE to any role that SessionUserId is a
|
|
|
|
* member of. (XXX rename to something like CurrentRoleId?)
|
|
|
|
*
|
|
|
|
* CurrentUserId is the current effective user ID; this is the one to use
|
|
|
|
* for all normal permissions-checking purposes. At outer level this will
|
|
|
|
* be the same as OuterUserId, but it changes during calls to SECURITY
|
|
|
|
* DEFINER functions, as well as locally in some specialized commands.
|
|
|
|
*
|
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
16 years ago
|
|
|
* SecurityRestrictionContext holds flags indicating reason(s) for changing
|
|
|
|
* CurrentUserId. In some cases we need to lock down operations that are
|
|
|
|
* not directly controlled by privilege settings, and this provides a
|
|
|
|
* convenient way to do it.
|
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
static Oid AuthenticatedUserId = InvalidOid;
|
|
|
|
static Oid SessionUserId = InvalidOid;
|
|
|
|
static Oid OuterUserId = InvalidOid;
|
|
|
|
static Oid CurrentUserId = InvalidOid;
|
Introduce SYSTEM_USER
SYSTEM_USER is a reserved keyword of the SQL specification that,
roughly described, is aimed at reporting some information about the
system user who has connected to the database server. It may include
implementation-specific information about the means by the user
connected, like an authentication method.
This commit implements SYSTEM_USER as of auth_method:identity, where
"auth_method" is a keyword about the authentication method used to log
into the server (like peer, md5, scram-sha-256, gss, etc.) and
"identity" is the authentication identity as introduced by 9afffcb (peer
sets authn to the OS user name, gss to the user principal, etc.). This
format has been suggested by Tom Lane.
Note that thanks to d951052, SYSTEM_USER is available to parallel
workers.
Bump catalog version.
Author: Bertrand Drouvot
Reviewed-by: Jacob Champion, Joe Conway, Álvaro Herrera, Michael Paquier
Discussion: https://postgr.es/m/7e692b8c-0b11-45db-1cad-3afc5b57409f@amazon.com
3 years ago
|
|
|
static const char *SystemUser = NULL;
|
|
|
|
|
|
|
|
/* We also have to remember the superuser state of some of these levels */
|
|
|
|
static bool AuthenticatedUserIsSuperuser = false;
|
|
|
|
static bool SessionUserIsSuperuser = false;
|
|
|
|
|
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
16 years ago
|
|
|
static int SecurityRestrictionContext = 0;
|
|
|
|
|
|
|
|
/* We also remember if a SET ROLE is currently active */
|
|
|
|
static bool SetRoleIsActive = false;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GetUserId - get the current effective user ID.
|
|
|
|
*
|
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
16 years ago
|
|
|
* Note: there's no SetUserId() anymore; use SetUserIdAndSecContext().
|
|
|
|
*/
|
|
|
|
Oid
|
|
|
|
GetUserId(void)
|
|
|
|
{
|
|
|
|
AssertState(OidIsValid(CurrentUserId));
|
|
|
|
return CurrentUserId;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GetOuterUserId/SetOuterUserId - get/set the outer-level user ID.
|
|
|
|
*/
|
|
|
|
Oid
|
|
|
|
GetOuterUserId(void)
|
|
|
|
{
|
|
|
|
AssertState(OidIsValid(OuterUserId));
|
|
|
|
return OuterUserId;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
SetOuterUserId(Oid userid)
|
|
|
|
{
|
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
16 years ago
|
|
|
AssertState(SecurityRestrictionContext == 0);
|
|
|
|
AssertArg(OidIsValid(userid));
|
|
|
|
OuterUserId = userid;
|
|
|
|
|
|
|
|
/* We force the effective user ID to match, too */
|
|
|
|
CurrentUserId = userid;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GetSessionUserId/SetSessionUserId - get/set the session user ID.
|
|
|
|
*/
|
|
|
|
Oid
|
|
|
|
GetSessionUserId(void)
|
|
|
|
{
|
|
|
|
AssertState(OidIsValid(SessionUserId));
|
|
|
|
return SessionUserId;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
SetSessionUserId(Oid userid, bool is_superuser)
|
|
|
|
{
|
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
16 years ago
|
|
|
AssertState(SecurityRestrictionContext == 0);
|
|
|
|
AssertArg(OidIsValid(userid));
|
|
|
|
SessionUserId = userid;
|
|
|
|
SessionUserIsSuperuser = is_superuser;
|
|
|
|
SetRoleIsActive = false;
|
|
|
|
|
|
|
|
/* We force the effective user IDs to match, too */
|
|
|
|
OuterUserId = userid;
|
|
|
|
CurrentUserId = userid;
|
|
|
|
}
|
|
|
|
|
Introduce SYSTEM_USER
SYSTEM_USER is a reserved keyword of the SQL specification that,
roughly described, is aimed at reporting some information about the
system user who has connected to the database server. It may include
implementation-specific information about the means by the user
connected, like an authentication method.
This commit implements SYSTEM_USER as of auth_method:identity, where
"auth_method" is a keyword about the authentication method used to log
into the server (like peer, md5, scram-sha-256, gss, etc.) and
"identity" is the authentication identity as introduced by 9afffcb (peer
sets authn to the OS user name, gss to the user principal, etc.). This
format has been suggested by Tom Lane.
Note that thanks to d951052, SYSTEM_USER is available to parallel
workers.
Bump catalog version.
Author: Bertrand Drouvot
Reviewed-by: Jacob Champion, Joe Conway, Álvaro Herrera, Michael Paquier
Discussion: https://postgr.es/m/7e692b8c-0b11-45db-1cad-3afc5b57409f@amazon.com
3 years ago
|
|
|
/*
|
|
|
|
* Return the system user representing the authenticated identity.
|
|
|
|
* It is defined in InitializeSystemUser() as auth_method:authn_id.
|
|
|
|
*/
|
|
|
|
const char *
|
|
|
|
GetSystemUser(void)
|
|
|
|
{
|
|
|
|
return SystemUser;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GetAuthenticatedUserId - get the authenticated user ID
|
|
|
|
*/
|
|
|
|
Oid
|
|
|
|
GetAuthenticatedUserId(void)
|
|
|
|
{
|
|
|
|
AssertState(OidIsValid(AuthenticatedUserId));
|
|
|
|
return AuthenticatedUserId;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
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
16 years ago
|
|
|
* GetUserIdAndSecContext/SetUserIdAndSecContext - get/set the current user ID
|
|
|
|
* and the SecurityRestrictionContext flags.
|
|
|
|
*
|
|
|
|
* Currently there are three valid bits in SecurityRestrictionContext:
|
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
16 years ago
|
|
|
*
|
|
|
|
* SECURITY_LOCAL_USERID_CHANGE indicates that we are inside an operation
|
|
|
|
* that is temporarily changing CurrentUserId via these functions. This is
|
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
16 years ago
|
|
|
* needed to indicate that the actual value of CurrentUserId is not in sync
|
|
|
|
* with guc.c's internal state, so SET ROLE has to be disallowed.
|
|
|
|
*
|
|
|
|
* SECURITY_RESTRICTED_OPERATION indicates that we are inside an operation
|
|
|
|
* that does not wish to trust called user-defined functions at all. The
|
|
|
|
* policy is to use this before operations, e.g. autovacuum and REINDEX, that
|
|
|
|
* enumerate relations of a database or schema and run functions associated
|
|
|
|
* with each found relation. The relation owner is the new user ID. Set this
|
|
|
|
* as soon as possible after locking the relation. Restore the old user ID as
|
|
|
|
* late as possible before closing the relation; restoring it shortly after
|
|
|
|
* close is also tolerable. If a command has both relation-enumerating and
|
|
|
|
* non-enumerating modes, e.g. ANALYZE, both modes set this bit. This bit
|
|
|
|
* prevents not only SET ROLE, but various other changes of session state that
|
|
|
|
* normally is unprotected but might possibly be used to subvert the calling
|
|
|
|
* session later. An example is replacing an existing prepared statement with
|
|
|
|
* new code, which will then be executed with the outer session's permissions
|
|
|
|
* when the prepared statement is next used. These restrictions are fairly
|
|
|
|
* draconian, but the functions called in relation-enumerating operations are
|
|
|
|
* really supposed to be side-effect-free anyway.
|
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
16 years ago
|
|
|
*
|
|
|
|
* SECURITY_NOFORCE_RLS indicates that we are inside an operation which should
|
|
|
|
* ignore the FORCE ROW LEVEL SECURITY per-table indication. This is used to
|
|
|
|
* ensure that FORCE RLS does not mistakenly break referential integrity
|
|
|
|
* checks. Note that this is intentionally only checked when running as the
|
|
|
|
* owner of the table (which should always be the case for referential
|
|
|
|
* integrity checks).
|
|
|
|
*
|
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
16 years ago
|
|
|
* Unlike GetUserId, GetUserIdAndSecContext does *not* Assert that the current
|
|
|
|
* value of CurrentUserId is valid; nor does SetUserIdAndSecContext require
|
|
|
|
* the new value to be valid. In fact, these routines had better not
|
|
|
|
* ever throw any kind of error. This is because they are used by
|
|
|
|
* StartTransaction and AbortTransaction to save/restore the settings,
|
|
|
|
* and during the first transaction within a backend, the value to be saved
|
|
|
|
* and perhaps restored is indeed invalid. We have to be able to get
|
|
|
|
* through AbortTransaction without asserting in case InitPostgres fails.
|
|
|
|
*/
|
|
|
|
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
16 years ago
|
|
|
GetUserIdAndSecContext(Oid *userid, int *sec_context)
|
|
|
|
{
|
|
|
|
*userid = CurrentUserId;
|
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
16 years ago
|
|
|
*sec_context = SecurityRestrictionContext;
|
|
|
|
}
|
|
|
|
|
|
|
|
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
16 years ago
|
|
|
SetUserIdAndSecContext(Oid userid, int sec_context)
|
|
|
|
{
|
|
|
|
CurrentUserId = userid;
|
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
16 years ago
|
|
|
SecurityRestrictionContext = sec_context;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
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
16 years ago
|
|
|
* InLocalUserIdChange - are we inside a local change of CurrentUserId?
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
InLocalUserIdChange(void)
|
|
|
|
{
|
|
|
|
return (SecurityRestrictionContext & SECURITY_LOCAL_USERID_CHANGE) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* InSecurityRestrictedOperation - are we inside a security-restricted command?
|
|
|
|
*/
|
|
|
|
bool
|
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
16 years ago
|
|
|
InSecurityRestrictedOperation(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
16 years ago
|
|
|
return (SecurityRestrictionContext & SECURITY_RESTRICTED_OPERATION) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* InNoForceRLSOperation - are we ignoring FORCE ROW LEVEL SECURITY ?
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
InNoForceRLSOperation(void)
|
|
|
|
{
|
|
|
|
return (SecurityRestrictionContext & SECURITY_NOFORCE_RLS) != 0;
|
|
|
|
}
|
|
|
|
|
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
16 years ago
|
|
|
|
|
|
|
/*
|
|
|
|
* These are obsolete versions of Get/SetUserIdAndSecContext that are
|
|
|
|
* only provided for bug-compatibility with some rather dubious code in
|
|
|
|
* pljava. We allow the userid to be set, but only when not inside a
|
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
16 years ago
|
|
|
* security restriction context.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
GetUserIdAndContext(Oid *userid, bool *sec_def_context)
|
|
|
|
{
|
|
|
|
*userid = CurrentUserId;
|
|
|
|
*sec_def_context = InLocalUserIdChange();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SetUserIdAndContext(Oid userid, bool sec_def_context)
|
|
|
|
{
|
|
|
|
/* We throw the same error SET ROLE would. */
|
|
|
|
if (InSecurityRestrictedOperation())
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("cannot set parameter \"%s\" within security-restricted operation",
|
|
|
|
"role")));
|
|
|
|
CurrentUserId = userid;
|
|
|
|
if (sec_def_context)
|
|
|
|
SecurityRestrictionContext |= SECURITY_LOCAL_USERID_CHANGE;
|
|
|
|
else
|
|
|
|
SecurityRestrictionContext &= ~SECURITY_LOCAL_USERID_CHANGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check whether specified role has explicit REPLICATION privilege
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
has_rolreplication(Oid roleid)
|
|
|
|
{
|
|
|
|
bool result = false;
|
|
|
|
HeapTuple utup;
|
|
|
|
|
|
|
|
utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
|
|
|
|
if (HeapTupleIsValid(utup))
|
|
|
|
{
|
|
|
|
result = ((Form_pg_authid) GETSTRUCT(utup))->rolreplication;
|
|
|
|
ReleaseSysCache(utup);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize user identity during normal backend startup
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
InitializeSessionUserId(const char *rolename, Oid roleid)
|
|
|
|
{
|
|
|
|
HeapTuple roleTup;
|
|
|
|
Form_pg_authid rform;
|
|
|
|
char *rname;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't do scans if we're bootstrapping, none of the system catalogs
|
|
|
|
* exist yet, and they should be owned by postgres anyway.
|
|
|
|
*/
|
|
|
|
AssertState(!IsBootstrapProcessingMode());
|
|
|
|
|
|
|
|
/* call only once */
|
|
|
|
AssertState(!OidIsValid(AuthenticatedUserId));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure syscache entries are flushed for recent catalog changes. This
|
|
|
|
* allows us to find roles that were created on-the-fly during
|
|
|
|
* authentication.
|
|
|
|
*/
|
|
|
|
AcceptInvalidationMessages();
|
|
|
|
|
|
|
|
if (rolename != NULL)
|
|
|
|
{
|
|
|
|
roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(rolename));
|
|
|
|
if (!HeapTupleIsValid(roleTup))
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
|
|
|
errmsg("role \"%s\" does not exist", rolename)));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
roleTup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
|
|
|
|
if (!HeapTupleIsValid(roleTup))
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
|
|
|
errmsg("role with OID %u does not exist", roleid)));
|
|
|
|
}
|
|
|
|
|
|
|
|
rform = (Form_pg_authid) GETSTRUCT(roleTup);
|
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
7 years ago
|
|
|
roleid = rform->oid;
|
|
|
|
rname = NameStr(rform->rolname);
|
|
|
|
|
|
|
|
AuthenticatedUserId = roleid;
|
|
|
|
AuthenticatedUserIsSuperuser = rform->rolsuper;
|
|
|
|
|
|
|
|
/* This sets OuterUserId/CurrentUserId too */
|
|
|
|
SetSessionUserId(roleid, AuthenticatedUserIsSuperuser);
|
|
|
|
|
|
|
|
/* Also mark our PGPROC entry with the authenticated user id */
|
|
|
|
/* (We assume this is an atomic store so no lock is needed) */
|
|
|
|
MyProc->roleId = roleid;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These next checks are not enforced when in standalone mode, so that
|
|
|
|
* there is a way to recover from sillinesses like "UPDATE pg_authid SET
|
|
|
|
* rolcanlogin = false;".
|
|
|
|
*/
|
|
|
|
if (IsUnderPostmaster)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Is role allowed to login at all?
|
|
|
|
*/
|
|
|
|
if (!rform->rolcanlogin)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
|
|
|
|
errmsg("role \"%s\" is not permitted to log in",
|
|
|
|
rname)));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check connection limit for this role.
|
|
|
|
*
|
|
|
|
* There is a race condition here --- we create our PGPROC before
|
|
|
|
* checking for other PGPROCs. If two backends did this at about the
|
|
|
|
* same time, they might both think they were over the limit, while
|
|
|
|
* ideally one should succeed and one fail. Getting that to work
|
|
|
|
* exactly seems more trouble than it is worth, however; instead we
|
|
|
|
* just document that the connection limit is approximate.
|
|
|
|
*/
|
|
|
|
if (rform->rolconnlimit >= 0 &&
|
|
|
|
!AuthenticatedUserIsSuperuser &&
|
|
|
|
CountUserBackends(roleid) > rform->rolconnlimit)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
|
|
|
|
errmsg("too many connections for role \"%s\"",
|
|
|
|
rname)));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Record username and superuser status as GUC settings too */
|
|
|
|
SetConfigOption("session_authorization", rname,
|
|
|
|
PGC_BACKEND, PGC_S_OVERRIDE);
|
|
|
|
SetConfigOption("is_superuser",
|
|
|
|
AuthenticatedUserIsSuperuser ? "on" : "off",
|
|
|
|
PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
|
|
|
|
|
|
|
|
ReleaseSysCache(roleTup);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize user identity during special backend startup
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
InitializeSessionUserIdStandalone(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* This function should only be called in single-user mode, in autovacuum
|
|
|
|
* workers, and in background workers.
|
|
|
|
*/
|
Background worker processes
Background workers are postmaster subprocesses that run arbitrary
user-specified code. They can request shared memory access as well as
backend database connections; or they can just use plain libpq frontend
database connections.
Modules listed in shared_preload_libraries can register background
workers in their _PG_init() function; this is early enough that it's not
necessary to provide an extra GUC option, because the necessary extra
resources can be allocated early on. Modules can install more than one
bgworker, if necessary.
Care is taken that these extra processes do not interfere with other
postmaster tasks: only one such process is started on each ServerLoop
iteration. This means a large number of them could be waiting to be
started up and postmaster is still able to quickly service external
connection requests. Also, shutdown sequence should not be impacted by
a worker process that's reasonably well behaved (i.e. promptly responds
to termination signals.)
The current implementation lets worker processes specify their start
time, i.e. at what point in the server startup process they are to be
started: right after postmaster start (in which case they mustn't ask
for shared memory access), when consistent state has been reached
(useful during recovery in a HOT standby server), or when recovery has
terminated (i.e. when normal backends are allowed).
In case of a bgworker crash, actions to take depend on registration
data: if shared memory was requested, then all other connections are
taken down (as well as other bgworkers), just like it were a regular
backend crashing. The bgworker itself is restarted, too, within a
configurable timeframe (which can be configured to be never).
More features to add to this framework can be imagined without much
effort, and have been discussed, but this seems good enough as a useful
unit already.
An elementary sample module is supplied.
Author: Álvaro Herrera
This patch is loosely based on prior patches submitted by KaiGai Kohei,
and unsubmitted code by Simon Riggs.
Reviewed by: KaiGai Kohei, Markus Wanner, Andres Freund,
Heikki Linnakangas, Simon Riggs, Amit Kapila
13 years ago
|
|
|
AssertState(!IsUnderPostmaster || IsAutoVacuumWorkerProcess() || IsBackgroundWorker);
|
|
|
|
|
|
|
|
/* call only once */
|
|
|
|
AssertState(!OidIsValid(AuthenticatedUserId));
|
|
|
|
|
|
|
|
AuthenticatedUserId = BOOTSTRAP_SUPERUSERID;
|
|
|
|
AuthenticatedUserIsSuperuser = true;
|
|
|
|
|
|
|
|
SetSessionUserId(BOOTSTRAP_SUPERUSERID, true);
|
|
|
|
}
|
|
|
|
|
Introduce SYSTEM_USER
SYSTEM_USER is a reserved keyword of the SQL specification that,
roughly described, is aimed at reporting some information about the
system user who has connected to the database server. It may include
implementation-specific information about the means by the user
connected, like an authentication method.
This commit implements SYSTEM_USER as of auth_method:identity, where
"auth_method" is a keyword about the authentication method used to log
into the server (like peer, md5, scram-sha-256, gss, etc.) and
"identity" is the authentication identity as introduced by 9afffcb (peer
sets authn to the OS user name, gss to the user principal, etc.). This
format has been suggested by Tom Lane.
Note that thanks to d951052, SYSTEM_USER is available to parallel
workers.
Bump catalog version.
Author: Bertrand Drouvot
Reviewed-by: Jacob Champion, Joe Conway, Álvaro Herrera, Michael Paquier
Discussion: https://postgr.es/m/7e692b8c-0b11-45db-1cad-3afc5b57409f@amazon.com
3 years ago
|
|
|
/*
|
|
|
|
* Initialize the system user.
|
|
|
|
*
|
|
|
|
* This is built as auth_method:authn_id.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
InitializeSystemUser(const char *authn_id, const char *auth_method)
|
|
|
|
{
|
|
|
|
char *system_user;
|
|
|
|
|
|
|
|
/* call only once */
|
|
|
|
Assert(SystemUser == NULL);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* InitializeSystemUser should be called only when authn_id is not NULL,
|
|
|
|
* meaning that auth_method is valid.
|
|
|
|
*/
|
|
|
|
Assert(authn_id != NULL);
|
|
|
|
|
|
|
|
system_user = psprintf("%s:%s", auth_method, authn_id);
|
|
|
|
|
|
|
|
/* Store SystemUser in long-lived storage */
|
|
|
|
SystemUser = MemoryContextStrdup(TopMemoryContext, system_user);
|
|
|
|
pfree(system_user);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SQL-function SYSTEM_USER
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
system_user(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
const char *sysuser = GetSystemUser();
|
|
|
|
|
|
|
|
if (sysuser)
|
|
|
|
PG_RETURN_DATUM(CStringGetTextDatum(sysuser));
|
|
|
|
else
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Change session auth ID while running
|
|
|
|
*
|
|
|
|
* Only a superuser may set auth ID to something other than himself. Note
|
|
|
|
* that in case of multiple SETs in a single session, the original userid's
|
|
|
|
* superuserness is what matters. But we set the GUC variable is_superuser
|
|
|
|
* to indicate whether the *current* session userid is a superuser.
|
|
|
|
*
|
|
|
|
* Note: this is not an especially clean place to do the permission check.
|
|
|
|
* It's OK because the check does not require catalog access and can't
|
|
|
|
* fail during an end-of-transaction GUC reversion, but we may someday
|
|
|
|
* have to push it up into assign_session_authorization.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
SetSessionAuthorization(Oid userid, bool is_superuser)
|
|
|
|
{
|
|
|
|
/* Must have authenticated already, else can't make permission check */
|
|
|
|
AssertState(OidIsValid(AuthenticatedUserId));
|
|
|
|
|
|
|
|
if (userid != AuthenticatedUserId &&
|
|
|
|
!AuthenticatedUserIsSuperuser)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("permission denied to set session authorization")));
|
|
|
|
|
|
|
|
SetSessionUserId(userid, is_superuser);
|
|
|
|
|
|
|
|
SetConfigOption("is_superuser",
|
|
|
|
is_superuser ? "on" : "off",
|
|
|
|
PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Report current role id
|
|
|
|
* This follows the semantics of SET ROLE, ie return the outer-level ID
|
|
|
|
* not the current effective ID, and return InvalidOid when the setting
|
|
|
|
* is logically SET ROLE NONE.
|
|
|
|
*/
|
|
|
|
Oid
|
|
|
|
GetCurrentRoleId(void)
|
|
|
|
{
|
|
|
|
if (SetRoleIsActive)
|
|
|
|
return OuterUserId;
|
|
|
|
else
|
|
|
|
return InvalidOid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Change Role ID while running (SET ROLE)
|
|
|
|
*
|
|
|
|
* If roleid is InvalidOid, we are doing SET ROLE NONE: revert to the
|
|
|
|
* session user authorization. In this case the is_superuser argument
|
|
|
|
* is ignored.
|
|
|
|
*
|
|
|
|
* When roleid is not InvalidOid, the caller must have checked whether
|
|
|
|
* the session user has permission to become that role. (We cannot check
|
|
|
|
* here because this routine must be able to execute in a failed transaction
|
|
|
|
* to restore a prior value of the ROLE GUC variable.)
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
SetCurrentRoleId(Oid roleid, bool is_superuser)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Get correct info if it's SET ROLE NONE
|
|
|
|
*
|
|
|
|
* If SessionUserId hasn't been set yet, just do nothing --- the eventual
|
|
|
|
* SetSessionUserId call will fix everything. This is needed since we
|
|
|
|
* will get called during GUC initialization.
|
|
|
|
*/
|
|
|
|
if (!OidIsValid(roleid))
|
|
|
|
{
|
|
|
|
if (!OidIsValid(SessionUserId))
|
|
|
|
return;
|
|
|
|
|
|
|
|
roleid = SessionUserId;
|
|
|
|
is_superuser = SessionUserIsSuperuser;
|
|
|
|
|
|
|
|
SetRoleIsActive = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetRoleIsActive = true;
|
|
|
|
|
|
|
|
SetOuterUserId(roleid);
|
|
|
|
|
|
|
|
SetConfigOption("is_superuser",
|
|
|
|
is_superuser ? "on" : "off",
|
|
|
|
PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get user name from user oid, returns NULL for nonexistent roleid if noerr
|
|
|
|
* is true.
|
|
|
|
*/
|
|
|
|
char *
|
|
|
|
GetUserNameFromId(Oid roleid, bool noerr)
|
|
|
|
{
|
|
|
|
HeapTuple tuple;
|
|
|
|
char *result;
|
|
|
|
|
|
|
|
tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
|
|
|
|
if (!HeapTupleIsValid(tuple))
|
|
|
|
{
|
|
|
|
if (!noerr)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("invalid role OID: %u", roleid)));
|
|
|
|
result = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result = pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname));
|
|
|
|
ReleaseSysCache(tuple);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
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
3 years ago
|
|
|
/* ------------------------------------------------------------------------
|
|
|
|
* Client connection state shared with parallel workers
|
|
|
|
*
|
|
|
|
* ClientConnectionInfo contains pieces of information about the client that
|
|
|
|
* need to be synced to parallel workers when they initialize.
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
ClientConnectionInfo MyClientConnectionInfo;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Intermediate representation of ClientConnectionInfo for easier
|
|
|
|
* serialization. Variable-length fields are allocated right after this
|
|
|
|
* header.
|
|
|
|
*/
|
|
|
|
typedef struct SerializedClientConnectionInfo
|
|
|
|
{
|
|
|
|
int32 authn_id_len; /* strlen(authn_id), or -1 if NULL */
|
|
|
|
UserAuth auth_method;
|
|
|
|
} SerializedClientConnectionInfo;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Calculate the space needed to serialize MyClientConnectionInfo.
|
|
|
|
*/
|
|
|
|
Size
|
|
|
|
EstimateClientConnectionInfoSpace(void)
|
|
|
|
{
|
|
|
|
Size size = 0;
|
|
|
|
|
|
|
|
size = add_size(size, sizeof(SerializedClientConnectionInfo));
|
|
|
|
|
|
|
|
if (MyClientConnectionInfo.authn_id)
|
|
|
|
size = add_size(size, strlen(MyClientConnectionInfo.authn_id) + 1);
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Serialize MyClientConnectionInfo for use by parallel workers.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
SerializeClientConnectionInfo(Size maxsize, char *start_address)
|
|
|
|
{
|
|
|
|
SerializedClientConnectionInfo serialized = {0};
|
|
|
|
|
|
|
|
serialized.authn_id_len = -1;
|
|
|
|
serialized.auth_method = MyClientConnectionInfo.auth_method;
|
|
|
|
|
|
|
|
if (MyClientConnectionInfo.authn_id)
|
|
|
|
serialized.authn_id_len = strlen(MyClientConnectionInfo.authn_id);
|
|
|
|
|
|
|
|
/* Copy serialized representation to buffer */
|
|
|
|
Assert(maxsize >= sizeof(serialized));
|
|
|
|
memcpy(start_address, &serialized, sizeof(serialized));
|
|
|
|
|
|
|
|
maxsize -= sizeof(serialized);
|
|
|
|
start_address += sizeof(serialized);
|
|
|
|
|
|
|
|
/* Copy authn_id into the space after the struct */
|
|
|
|
if (serialized.authn_id_len >= 0)
|
|
|
|
{
|
|
|
|
Assert(maxsize >= (serialized.authn_id_len + 1));
|
|
|
|
memcpy(start_address,
|
|
|
|
MyClientConnectionInfo.authn_id,
|
|
|
|
/* include the NULL terminator to ease deserialization */
|
|
|
|
serialized.authn_id_len + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Restore MyClientConnectionInfo from its serialized representation.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
RestoreClientConnectionInfo(char *conninfo)
|
|
|
|
{
|
|
|
|
SerializedClientConnectionInfo serialized;
|
|
|
|
|
|
|
|
memcpy(&serialized, conninfo, sizeof(serialized));
|
|
|
|
|
|
|
|
/* Copy the fields back into place */
|
|
|
|
MyClientConnectionInfo.authn_id = NULL;
|
|
|
|
MyClientConnectionInfo.auth_method = serialized.auth_method;
|
|
|
|
|
|
|
|
if (serialized.authn_id_len >= 0)
|
|
|
|
{
|
|
|
|
char *authn_id;
|
|
|
|
|
|
|
|
authn_id = conninfo + sizeof(serialized);
|
|
|
|
MyClientConnectionInfo.authn_id = MemoryContextStrdup(TopMemoryContext,
|
|
|
|
authn_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Interlock-file support
|
|
|
|
*
|
|
|
|
* These routines are used to create both a data-directory lockfile
|
|
|
|
* ($DATADIR/postmaster.pid) and Unix-socket-file lockfiles ($SOCKFILE.lock).
|
|
|
|
* Both kinds of files contain the same info initially, although we can add
|
|
|
|
* more information to a data-directory lockfile after it's created, using
|
|
|
|
* AddToDataDirLockFile(). See pidfile.h for documentation of the contents
|
|
|
|
* of these lockfiles.
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
*
|
|
|
|
* On successful lockfile creation, a proc_exit callback to remove the
|
|
|
|
* lockfile is automatically created.
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* proc_exit callback to remove lockfiles.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
UnlinkLockFiles(int status, Datum arg)
|
|
|
|
{
|
|
|
|
ListCell *l;
|
|
|
|
|
|
|
|
foreach(l, lock_files)
|
|
|
|
{
|
|
|
|
char *curfile = (char *) lfirst(l);
|
|
|
|
|
|
|
|
unlink(curfile);
|
|
|
|
/* Should we complain if the unlink fails? */
|
|
|
|
}
|
|
|
|
/* Since we're about to exit, no need to reclaim storage */
|
|
|
|
lock_files = NIL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Lock file removal should always be the last externally visible action
|
|
|
|
* of a postmaster or standalone backend, while we won't come here at all
|
|
|
|
* when exiting postmaster child processes. Therefore, this is a good
|
|
|
|
* place to log completion of shutdown. We could alternatively teach
|
|
|
|
* proc_exit() to do it, but that seems uglier. In a standalone backend,
|
|
|
|
* use NOTICE elevel to be less chatty.
|
|
|
|
*/
|
|
|
|
ereport(IsPostmasterEnvironment ? LOG : NOTICE,
|
|
|
|
(errmsg("database system is shut down")));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a lockfile.
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
*
|
|
|
|
* filename is the path name of the lockfile to create.
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
* amPostmaster is used to determine how to encode the output PID.
|
|
|
|
* socketDir is the Unix socket directory path to include (possibly empty).
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
* isDDLock and refName are used to determine what error message to produce.
|
|
|
|
*/
|
|
|
|
static void
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
CreateLockFile(const char *filename, bool amPostmaster,
|
|
|
|
const char *socketDir,
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
bool isDDLock, const char *refName)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
char buffer[MAXPGPATH * 2 + 256];
|
|
|
|
int ntries;
|
|
|
|
int len;
|
|
|
|
int encoded_pid;
|
|
|
|
pid_t other_pid;
|
|
|
|
pid_t my_pid,
|
|
|
|
my_p_pid,
|
|
|
|
my_gp_pid;
|
|
|
|
const char *envvar;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the PID in the lockfile is our own PID or our parent's or
|
|
|
|
* grandparent's PID, then the file must be stale (probably left over from
|
|
|
|
* a previous system boot cycle). We need to check this because of the
|
|
|
|
* likelihood that a reboot will assign exactly the same PID as we had in
|
|
|
|
* the previous reboot, or one that's only one or two counts larger and
|
|
|
|
* hence the lockfile's PID now refers to an ancestor shell process. We
|
|
|
|
* allow pg_ctl to pass down its parent shell PID (our grandparent PID)
|
|
|
|
* via the environment variable PG_GRANDPARENT_PID; this is so that
|
|
|
|
* launching the postmaster via pg_ctl can be just as reliable as
|
|
|
|
* launching it directly. There is no provision for detecting
|
|
|
|
* further-removed ancestor processes, but if the init script is written
|
|
|
|
* carefully then all but the immediate parent shell will be root-owned
|
|
|
|
* processes and so the kill test will fail with EPERM. Note that we
|
|
|
|
* cannot get a false negative this way, because an existing postmaster
|
|
|
|
* would surely never launch a competing postmaster or pg_ctl process
|
|
|
|
* directly.
|
|
|
|
*/
|
|
|
|
my_pid = getpid();
|
|
|
|
|
|
|
|
#ifndef WIN32
|
|
|
|
my_p_pid = getppid();
|
|
|
|
#else
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Windows hasn't got getppid(), but doesn't need it since it's not using
|
|
|
|
* real kill() either...
|
|
|
|
*/
|
|
|
|
my_p_pid = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
envvar = getenv("PG_GRANDPARENT_PID");
|
|
|
|
if (envvar)
|
|
|
|
my_gp_pid = atoi(envvar);
|
|
|
|
else
|
|
|
|
my_gp_pid = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We need a loop here because of race conditions. But don't loop forever
|
|
|
|
* (for example, a non-writable $PGDATA directory might cause a failure
|
|
|
|
* that won't go away). 100 tries seems like plenty.
|
|
|
|
*/
|
|
|
|
for (ntries = 0;; ntries++)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Try to create the lock file --- O_EXCL makes this atomic.
|
|
|
|
*
|
|
|
|
* Think not to make the file protection weaker than 0600/0640. See
|
|
|
|
* comments below.
|
|
|
|
*/
|
|
|
|
fd = open(filename, O_RDWR | O_CREAT | O_EXCL, pg_file_create_mode);
|
|
|
|
if (fd >= 0)
|
|
|
|
break; /* Success; exit the retry loop */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Couldn't create the pid file. Probably it already exists.
|
|
|
|
*/
|
|
|
|
if ((errno != EEXIST && errno != EACCES) || ntries > 100)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not create lock file \"%s\": %m",
|
|
|
|
filename)));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read the file to get the old owner's PID. Note race condition
|
|
|
|
* here: file might have been deleted since we tried to create it.
|
|
|
|
*/
|
|
|
|
fd = open(filename, O_RDONLY, pg_file_create_mode);
|
|
|
|
if (fd < 0)
|
|
|
|
{
|
|
|
|
if (errno == ENOENT)
|
|
|
|
continue; /* race condition; try again */
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not open lock file \"%s\": %m",
|
|
|
|
filename)));
|
|
|
|
}
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_CREATE_READ);
|
|
|
|
if ((len = read(fd, buffer, sizeof(buffer) - 1)) < 0)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not read lock file \"%s\": %m",
|
|
|
|
filename)));
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_end();
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
if (len == 0)
|
|
|
|
{
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_LOCK_FILE_EXISTS),
|
|
|
|
errmsg("lock file \"%s\" is empty", filename),
|
|
|
|
errhint("Either another server is starting, or the lock file is the remnant of a previous server startup crash.")));
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer[len] = '\0';
|
|
|
|
encoded_pid = atoi(buffer);
|
|
|
|
|
|
|
|
/* if pid < 0, the pid is for postgres, not postmaster */
|
|
|
|
other_pid = (pid_t) (encoded_pid < 0 ? -encoded_pid : encoded_pid);
|
|
|
|
|
|
|
|
if (other_pid <= 0)
|
|
|
|
elog(FATAL, "bogus data in lock file \"%s\": \"%s\"",
|
|
|
|
filename, buffer);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check to see if the other process still exists
|
|
|
|
*
|
|
|
|
* Per discussion above, my_pid, my_p_pid, and my_gp_pid can be
|
|
|
|
* ignored as false matches.
|
|
|
|
*
|
|
|
|
* Normally kill() will fail with ESRCH if the given PID doesn't
|
|
|
|
* exist.
|
|
|
|
*
|
|
|
|
* We can treat the EPERM-error case as okay because that error
|
|
|
|
* implies that the existing process has a different userid than we
|
|
|
|
* do, which means it cannot be a competing postmaster. A postmaster
|
|
|
|
* cannot successfully attach to a data directory owned by a userid
|
|
|
|
* other than its own, as enforced in checkDataDir(). Also, since we
|
|
|
|
* create the lockfiles mode 0600/0640, we'd have failed above if the
|
|
|
|
* lockfile belonged to another userid --- which means that whatever
|
|
|
|
* process kill() is reporting about isn't the one that made the
|
|
|
|
* lockfile. (NOTE: this last consideration is the only one that
|
|
|
|
* keeps us from blowing away a Unix socket file belonging to an
|
|
|
|
* instance of Postgres being run by someone else, at least on
|
|
|
|
* machines where /tmp hasn't got a stickybit.)
|
|
|
|
*/
|
|
|
|
if (other_pid != my_pid && other_pid != my_p_pid &&
|
|
|
|
other_pid != my_gp_pid)
|
|
|
|
{
|
|
|
|
if (kill(other_pid, 0) == 0 ||
|
|
|
|
(errno != ESRCH && errno != EPERM))
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
{
|
|
|
|
/* lockfile belongs to a live process */
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_LOCK_FILE_EXISTS),
|
|
|
|
errmsg("lock file \"%s\" already exists",
|
|
|
|
filename),
|
|
|
|
isDDLock ?
|
|
|
|
(encoded_pid < 0 ?
|
|
|
|
errhint("Is another postgres (PID %d) running in data directory \"%s\"?",
|
|
|
|
(int) other_pid, refName) :
|
|
|
|
errhint("Is another postmaster (PID %d) running in data directory \"%s\"?",
|
|
|
|
(int) other_pid, refName)) :
|
|
|
|
(encoded_pid < 0 ?
|
|
|
|
errhint("Is another postgres (PID %d) using socket file \"%s\"?",
|
|
|
|
(int) other_pid, refName) :
|
|
|
|
errhint("Is another postmaster (PID %d) using socket file \"%s\"?",
|
|
|
|
(int) other_pid, refName))));
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* No, the creating process did not exist. However, it could be that
|
|
|
|
* the postmaster crashed (or more likely was kill -9'd by a clueless
|
|
|
|
* admin) but has left orphan backends behind. Check for this by
|
|
|
|
* looking to see if there is an associated shmem segment that is
|
|
|
|
* still in use.
|
|
|
|
*
|
|
|
|
* Note: because postmaster.pid is written in multiple steps, we might
|
|
|
|
* not find the shmem ID values in it; we can't treat that as an
|
|
|
|
* error.
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
*/
|
|
|
|
if (isDDLock)
|
|
|
|
{
|
|
|
|
char *ptr = buffer;
|
|
|
|
unsigned long id1,
|
|
|
|
id2;
|
|
|
|
int lineno;
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
|
|
|
|
for (lineno = 1; lineno < LOCK_FILE_LINE_SHMEM_KEY; lineno++)
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
{
|
|
|
|
if ((ptr = strchr(ptr, '\n')) == NULL)
|
|
|
|
break;
|
|
|
|
ptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ptr != NULL &&
|
|
|
|
sscanf(ptr, "%lu %lu", &id1, &id2) == 2)
|
|
|
|
{
|
|
|
|
if (PGSharedMemoryIsInUse(id1, id2))
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_LOCK_FILE_EXISTS),
|
|
|
|
errmsg("pre-existing shared memory block (key %lu, ID %lu) is still in use",
|
|
|
|
id1, id2),
|
|
|
|
errhint("Terminate any old server processes associated with data directory \"%s\".",
|
|
|
|
refName)));
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Looks like nobody's home. Unlink the file and try again to create
|
|
|
|
* it. Need a loop because of possible race condition against other
|
|
|
|
* would-be creators.
|
|
|
|
*/
|
|
|
|
if (unlink(filename) < 0)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not remove old lock file \"%s\": %m",
|
|
|
|
filename),
|
|
|
|
errhint("The file seems accidentally left over, but "
|
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
8 years ago
|
|
|
"it could not be removed. Please remove the file "
|
|
|
|
"by hand and try again.")));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Successfully created the file, now fill it. See comment in pidfile.h
|
|
|
|
* about the contents. Note that we write the same first five lines into
|
|
|
|
* both datadir and socket lockfiles; although more stuff may get added to
|
|
|
|
* the datadir lockfile later.
|
|
|
|
*/
|
|
|
|
snprintf(buffer, sizeof(buffer), "%d\n%s\n%ld\n%d\n%s\n",
|
|
|
|
amPostmaster ? (int) my_pid : -((int) my_pid),
|
|
|
|
DataDir,
|
|
|
|
(long) MyStartTime,
|
|
|
|
PostPortNumber,
|
|
|
|
socketDir);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In a standalone backend, the next line (LOCK_FILE_LINE_LISTEN_ADDR)
|
|
|
|
* will never receive data, so fill it in as empty now.
|
|
|
|
*/
|
|
|
|
if (isDDLock && !amPostmaster)
|
|
|
|
strlcat(buffer, "\n", sizeof(buffer));
|
|
|
|
|
|
|
|
errno = 0;
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_CREATE_WRITE);
|
|
|
|
if (write(fd, buffer, strlen(buffer)) != strlen(buffer))
|
|
|
|
{
|
|
|
|
int save_errno = errno;
|
|
|
|
|
|
|
|
close(fd);
|
|
|
|
unlink(filename);
|
|
|
|
/* if write didn't set errno, assume problem is no disk space */
|
|
|
|
errno = save_errno ? save_errno : ENOSPC;
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not write lock file \"%s\": %m", filename)));
|
|
|
|
}
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_end();
|
|
|
|
|
|
|
|
pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_CREATE_SYNC);
|
|
|
|
if (pg_fsync(fd) != 0)
|
|
|
|
{
|
|
|
|
int save_errno = errno;
|
|
|
|
|
|
|
|
close(fd);
|
|
|
|
unlink(filename);
|
|
|
|
errno = save_errno;
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not write lock file \"%s\": %m", filename)));
|
|
|
|
}
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_end();
|
|
|
|
if (close(fd) != 0)
|
|
|
|
{
|
|
|
|
int save_errno = errno;
|
|
|
|
|
|
|
|
unlink(filename);
|
|
|
|
errno = save_errno;
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not write lock file \"%s\": %m", filename)));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Arrange to unlink the lock file(s) at proc_exit. If this is the first
|
|
|
|
* one, set up the on_proc_exit function to do it; then add this lock file
|
|
|
|
* to the list of files to unlink.
|
|
|
|
*/
|
|
|
|
if (lock_files == NIL)
|
|
|
|
on_proc_exit(UnlinkLockFiles, 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Use lcons so that the lock files are unlinked in reverse order of
|
|
|
|
* creation; this is critical!
|
|
|
|
*/
|
|
|
|
lock_files = lcons(pstrdup(filename), lock_files);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create the data directory lockfile.
|
|
|
|
*
|
|
|
|
* When this is called, we must have already switched the working
|
|
|
|
* directory to DataDir, so we can just use a relative path. This
|
|
|
|
* helps ensure that we are locking the directory we should be.
|
|
|
|
*
|
|
|
|
* Note that the socket directory path line is initially written as empty.
|
|
|
|
* postmaster.c will rewrite it upon creating the first Unix socket.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
CreateDataDirLockFile(bool amPostmaster)
|
|
|
|
{
|
|
|
|
CreateLockFile(DIRECTORY_LOCK_FILE, amPostmaster, "", true, DataDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a lockfile for the specified Unix socket file.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
CreateSocketLockFile(const char *socketfile, bool amPostmaster,
|
|
|
|
const char *socketDir)
|
|
|
|
{
|
|
|
|
char lockfile[MAXPGPATH];
|
|
|
|
|
|
|
|
snprintf(lockfile, sizeof(lockfile), "%s.lock", socketfile);
|
|
|
|
CreateLockFile(lockfile, amPostmaster, socketDir, false, socketfile);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TouchSocketLockFiles -- mark socket lock files as recently accessed
|
|
|
|
*
|
|
|
|
* This routine should be called every so often to ensure that the socket
|
|
|
|
* lock files have a recent mod or access date. That saves them
|
|
|
|
* from being removed by overenthusiastic /tmp-directory-cleaner daemons.
|
|
|
|
* (Another reason we should never have put the socket file in /tmp...)
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
TouchSocketLockFiles(void)
|
|
|
|
{
|
|
|
|
ListCell *l;
|
|
|
|
|
|
|
|
foreach(l, lock_files)
|
|
|
|
{
|
|
|
|
char *socketLockFile = (char *) lfirst(l);
|
|
|
|
|
|
|
|
/* No need to touch the data directory lock file, we trust */
|
|
|
|
if (strcmp(socketLockFile, DIRECTORY_LOCK_FILE) == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* we just ignore any error here */
|
|
|
|
(void) utime(socketLockFile, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
/*
|
|
|
|
* Add (or replace) a line in the data directory lock file.
|
|
|
|
* The given string should not include a trailing newline.
|
|
|
|
*
|
|
|
|
* Note: because we don't truncate the file, if we were to rewrite a line
|
|
|
|
* with less data than it had before, there would be garbage after the last
|
Change pg_ctl to detect server-ready by watching status in postmaster.pid.
Traditionally, "pg_ctl start -w" has waited for the server to become
ready to accept connections by attempting a connection once per second.
That has the major problem that connection issues (for instance, a
kernel packet filter blocking traffic) can't be reliably told apart
from server startup issues, and the minor problem that if server startup
isn't quick, we accumulate "the database system is starting up" spam
in the server log. We've hacked around many of the possible connection
issues, but it resulted in ugly and complicated code in pg_ctl.c.
In commit c61559ec3, I changed the probe rate to every tenth of a second.
That prompted Jeff Janes to complain that the log-spam problem had become
much worse. In the ensuing discussion, Andres Freund pointed out that
we could dispense with connection attempts altogether if the postmaster
were changed to report its status in postmaster.pid, which "pg_ctl start"
already relies on being able to read. This patch implements that, teaching
postmaster.c to report a status string into the pidfile at the same
state-change points already identified as being of interest for systemd
status reporting (cf commit 7d17e683f). pg_ctl no longer needs to link
with libpq at all; all its functions now depend on reading server files.
In support of this, teach AddToDataDirLockFile() to allow addition of
postmaster.pid lines in not-necessarily-sequential order. This is needed
on Windows where the SHMEM_KEY line will never be written at all. We still
have the restriction that we don't want to truncate the pidfile; document
the reasons for that a bit better.
Also, fix the pg_ctl TAP tests so they'll notice if "start -w" mode
is broken --- before, they'd just wait out the sixty seconds until
the loop gives up, and then report success anyway. (Yes, I found that
out the hard way.)
While at it, arrange for pg_ctl to not need to #include miscadmin.h;
as a rather low-level backend header, requiring that to be compilable
client-side is pretty dubious. This requires moving the #define's
associated with the pidfile into a new header file, and moving
PG_BACKEND_VERSIONSTR someplace else. For lack of a clearly better
"someplace else", I put it into port.h, beside the declaration of
find_other_exec(), since most users of that macro are passing the value to
find_other_exec(). (initdb still depends on miscadmin.h, but at least
pg_ctl and pg_upgrade no longer do.)
In passing, fix main.c so that PG_BACKEND_VERSIONSTR actually defines the
output of "postgres -V", which remarkably it had never done before.
Discussion: https://postgr.es/m/CAMkU=1xJW8e+CTotojOMBd-yzUvD0e_JZu2xHo=MnuZ4__m7Pg@mail.gmail.com
8 years ago
|
|
|
* line. While we could fix that by adding a truncate call, that would make
|
|
|
|
* the file update non-atomic, which we'd rather avoid. Therefore, callers
|
|
|
|
* should endeavor never to shorten a line once it's been written.
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
*/
|
|
|
|
void
|
|
|
|
AddToDataDirLockFile(int target_line, const char *str)
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
int len;
|
|
|
|
int lineno;
|
|
|
|
char *srcptr;
|
|
|
|
char *destptr;
|
|
|
|
char srcbuffer[BLCKSZ];
|
|
|
|
char destbuffer[BLCKSZ];
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
|
|
|
|
fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0);
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
if (fd < 0)
|
|
|
|
{
|
|
|
|
ereport(LOG,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not open file \"%s\": %m",
|
|
|
|
DIRECTORY_LOCK_FILE)));
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
return;
|
|
|
|
}
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ);
|
|
|
|
len = read(fd, srcbuffer, sizeof(srcbuffer) - 1);
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_end();
|
|
|
|
if (len < 0)
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
{
|
|
|
|
ereport(LOG,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not read from file \"%s\": %m",
|
|
|
|
DIRECTORY_LOCK_FILE)));
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
close(fd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
srcbuffer[len] = '\0';
|
|
|
|
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
/*
|
|
|
|
* Advance over lines we are not supposed to rewrite, then copy them to
|
|
|
|
* destbuffer.
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
*/
|
|
|
|
srcptr = srcbuffer;
|
|
|
|
for (lineno = 1; lineno < target_line; lineno++)
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
{
|
Change pg_ctl to detect server-ready by watching status in postmaster.pid.
Traditionally, "pg_ctl start -w" has waited for the server to become
ready to accept connections by attempting a connection once per second.
That has the major problem that connection issues (for instance, a
kernel packet filter blocking traffic) can't be reliably told apart
from server startup issues, and the minor problem that if server startup
isn't quick, we accumulate "the database system is starting up" spam
in the server log. We've hacked around many of the possible connection
issues, but it resulted in ugly and complicated code in pg_ctl.c.
In commit c61559ec3, I changed the probe rate to every tenth of a second.
That prompted Jeff Janes to complain that the log-spam problem had become
much worse. In the ensuing discussion, Andres Freund pointed out that
we could dispense with connection attempts altogether if the postmaster
were changed to report its status in postmaster.pid, which "pg_ctl start"
already relies on being able to read. This patch implements that, teaching
postmaster.c to report a status string into the pidfile at the same
state-change points already identified as being of interest for systemd
status reporting (cf commit 7d17e683f). pg_ctl no longer needs to link
with libpq at all; all its functions now depend on reading server files.
In support of this, teach AddToDataDirLockFile() to allow addition of
postmaster.pid lines in not-necessarily-sequential order. This is needed
on Windows where the SHMEM_KEY line will never be written at all. We still
have the restriction that we don't want to truncate the pidfile; document
the reasons for that a bit better.
Also, fix the pg_ctl TAP tests so they'll notice if "start -w" mode
is broken --- before, they'd just wait out the sixty seconds until
the loop gives up, and then report success anyway. (Yes, I found that
out the hard way.)
While at it, arrange for pg_ctl to not need to #include miscadmin.h;
as a rather low-level backend header, requiring that to be compilable
client-side is pretty dubious. This requires moving the #define's
associated with the pidfile into a new header file, and moving
PG_BACKEND_VERSIONSTR someplace else. For lack of a clearly better
"someplace else", I put it into port.h, beside the declaration of
find_other_exec(), since most users of that macro are passing the value to
find_other_exec(). (initdb still depends on miscadmin.h, but at least
pg_ctl and pg_upgrade no longer do.)
In passing, fix main.c so that PG_BACKEND_VERSIONSTR actually defines the
output of "postgres -V", which remarkably it had never done before.
Discussion: https://postgr.es/m/CAMkU=1xJW8e+CTotojOMBd-yzUvD0e_JZu2xHo=MnuZ4__m7Pg@mail.gmail.com
8 years ago
|
|
|
char *eol = strchr(srcptr, '\n');
|
|
|
|
|
|
|
|
if (eol == NULL)
|
|
|
|
break; /* not enough lines in file yet */
|
|
|
|
srcptr = eol + 1;
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
}
|
|
|
|
memcpy(destbuffer, srcbuffer, srcptr - srcbuffer);
|
|
|
|
destptr = destbuffer + (srcptr - srcbuffer);
|
|
|
|
|
Change pg_ctl to detect server-ready by watching status in postmaster.pid.
Traditionally, "pg_ctl start -w" has waited for the server to become
ready to accept connections by attempting a connection once per second.
That has the major problem that connection issues (for instance, a
kernel packet filter blocking traffic) can't be reliably told apart
from server startup issues, and the minor problem that if server startup
isn't quick, we accumulate "the database system is starting up" spam
in the server log. We've hacked around many of the possible connection
issues, but it resulted in ugly and complicated code in pg_ctl.c.
In commit c61559ec3, I changed the probe rate to every tenth of a second.
That prompted Jeff Janes to complain that the log-spam problem had become
much worse. In the ensuing discussion, Andres Freund pointed out that
we could dispense with connection attempts altogether if the postmaster
were changed to report its status in postmaster.pid, which "pg_ctl start"
already relies on being able to read. This patch implements that, teaching
postmaster.c to report a status string into the pidfile at the same
state-change points already identified as being of interest for systemd
status reporting (cf commit 7d17e683f). pg_ctl no longer needs to link
with libpq at all; all its functions now depend on reading server files.
In support of this, teach AddToDataDirLockFile() to allow addition of
postmaster.pid lines in not-necessarily-sequential order. This is needed
on Windows where the SHMEM_KEY line will never be written at all. We still
have the restriction that we don't want to truncate the pidfile; document
the reasons for that a bit better.
Also, fix the pg_ctl TAP tests so they'll notice if "start -w" mode
is broken --- before, they'd just wait out the sixty seconds until
the loop gives up, and then report success anyway. (Yes, I found that
out the hard way.)
While at it, arrange for pg_ctl to not need to #include miscadmin.h;
as a rather low-level backend header, requiring that to be compilable
client-side is pretty dubious. This requires moving the #define's
associated with the pidfile into a new header file, and moving
PG_BACKEND_VERSIONSTR someplace else. For lack of a clearly better
"someplace else", I put it into port.h, beside the declaration of
find_other_exec(), since most users of that macro are passing the value to
find_other_exec(). (initdb still depends on miscadmin.h, but at least
pg_ctl and pg_upgrade no longer do.)
In passing, fix main.c so that PG_BACKEND_VERSIONSTR actually defines the
output of "postgres -V", which remarkably it had never done before.
Discussion: https://postgr.es/m/CAMkU=1xJW8e+CTotojOMBd-yzUvD0e_JZu2xHo=MnuZ4__m7Pg@mail.gmail.com
8 years ago
|
|
|
/*
|
|
|
|
* Fill in any missing lines before the target line, in case lines are
|
|
|
|
* added to the file out of order.
|
|
|
|
*/
|
|
|
|
for (; lineno < target_line; lineno++)
|
|
|
|
{
|
|
|
|
if (destptr < destbuffer + sizeof(destbuffer))
|
|
|
|
*destptr++ = '\n';
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write or rewrite the target line.
|
|
|
|
*/
|
|
|
|
snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s\n", str);
|
|
|
|
destptr += strlen(destptr);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If there are more lines in the old file, append them to destbuffer.
|
|
|
|
*/
|
|
|
|
if ((srcptr = strchr(srcptr, '\n')) != NULL)
|
|
|
|
{
|
|
|
|
srcptr++;
|
|
|
|
snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s",
|
|
|
|
srcptr);
|
|
|
|
}
|
|
|
|
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
/*
|
|
|
|
* And rewrite the data. Since we write in a single kernel call, this
|
|
|
|
* update should appear atomic to onlookers.
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
*/
|
|
|
|
len = strlen(destbuffer);
|
|
|
|
errno = 0;
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE);
|
|
|
|
if (pg_pwrite(fd, destbuffer, len, 0) != len)
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
{
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_end();
|
|
|
|
/* if write didn't set errno, assume problem is no disk space */
|
|
|
|
if (errno == 0)
|
|
|
|
errno = ENOSPC;
|
|
|
|
ereport(LOG,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not write to file \"%s\": %m",
|
|
|
|
DIRECTORY_LOCK_FILE)));
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
close(fd);
|
|
|
|
return;
|
|
|
|
}
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_end();
|
|
|
|
pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC);
|
|
|
|
if (pg_fsync(fd) != 0)
|
|
|
|
{
|
|
|
|
ereport(LOG,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not write to file \"%s\": %m",
|
|
|
|
DIRECTORY_LOCK_FILE)));
|
|
|
|
}
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_end();
|
|
|
|
if (close(fd) != 0)
|
|
|
|
{
|
|
|
|
ereport(LOG,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not write to file \"%s\": %m",
|
|
|
|
DIRECTORY_LOCK_FILE)));
|
|
|
|
}
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
25 years ago
|
|
|
}
|
|
|
|
|
|
|
|
|
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.
10 years ago
|
|
|
/*
|
|
|
|
* Recheck that the data directory lock file still exists with expected
|
|
|
|
* content. Return true if the lock file appears OK, false if it isn't.
|
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.
10 years ago
|
|
|
*
|
|
|
|
* We call this periodically in the postmaster. The idea is that if the
|
|
|
|
* lock file has been removed or replaced by another postmaster, we should
|
|
|
|
* do a panic database shutdown. Therefore, we should return true if there
|
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.
10 years ago
|
|
|
* is any doubt: we do not want to cause a panic shutdown unnecessarily.
|
|
|
|
* Transient failures like EINTR or ENFILE should not cause us to fail.
|
|
|
|
* (If there really is something wrong, we'll detect it on a future recheck.)
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
RecheckDataDirLockFile(void)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
int len;
|
|
|
|
long file_pid;
|
|
|
|
char buffer[BLCKSZ];
|
|
|
|
|
|
|
|
fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0);
|
|
|
|
if (fd < 0)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* There are many foreseeable false-positive error conditions. For
|
|
|
|
* safety, fail only on enumerated clearly-something-is-wrong
|
|
|
|
* conditions.
|
|
|
|
*/
|
|
|
|
switch (errno)
|
|
|
|
{
|
|
|
|
case ENOENT:
|
|
|
|
case ENOTDIR:
|
|
|
|
/* disaster */
|
|
|
|
ereport(LOG,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not open file \"%s\": %m",
|
|
|
|
DIRECTORY_LOCK_FILE)));
|
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
/* non-fatal, at least for now */
|
|
|
|
ereport(LOG,
|
|
|
|
(errcode_for_file_access(),
|
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
8 years ago
|
|
|
errmsg("could not open file \"%s\": %m; continuing anyway",
|
|
|
|
DIRECTORY_LOCK_FILE)));
|
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.
10 years ago
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ);
|
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.
10 years ago
|
|
|
len = read(fd, buffer, sizeof(buffer) - 1);
|
Create and use wait events for read, write, and fsync operations.
Previous commits, notably 53be0b1add7064ca5db3cd884302dfc3268d884e and
6f3bd98ebfc008cbd676da777bb0b2376c4c4bfa, made it possible to see from
pg_stat_activity when a backend was stuck waiting for another backend,
but it's also fairly common for a backend to be stuck waiting for an
I/O. Add wait events for those operations, too.
Rushabh Lathia, with further hacking by me. Reviewed and tested by
Michael Paquier, Amit Kapila, Rajkumar Raghuwanshi, and Rahila Syed.
Discussion: http://postgr.es/m/CAGPqQf0LsYHXREPAZqYGVkDqHSyjf=KsD=k0GTVPAuzyThh-VQ@mail.gmail.com
8 years ago
|
|
|
pgstat_report_wait_end();
|
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.
10 years ago
|
|
|
if (len < 0)
|
|
|
|
{
|
|
|
|
ereport(LOG,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not read from file \"%s\": %m",
|
|
|
|
DIRECTORY_LOCK_FILE)));
|
|
|
|
close(fd);
|
|
|
|
return true; /* treat read failure as nonfatal */
|
|
|
|
}
|
|
|
|
buffer[len] = '\0';
|
|
|
|
close(fd);
|
|
|
|
file_pid = atol(buffer);
|
|
|
|
if (file_pid == getpid())
|
|
|
|
return true; /* all is well */
|
|
|
|
|
|
|
|
/* Trouble: someone's overwritten the lock file */
|
|
|
|
ereport(LOG,
|
|
|
|
(errmsg("lock file \"%s\" contains wrong PID: %ld instead of %ld",
|
|
|
|
DIRECTORY_LOCK_FILE, file_pid, (long) getpid())));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Version checking support
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine whether the PG_VERSION file in directory `path' indicates
|
|
|
|
* a data version compatible with the version of this program.
|
|
|
|
*
|
|
|
|
* If compatible, return. Otherwise, ereport(FATAL).
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ValidatePgVersion(const char *path)
|
|
|
|
{
|
|
|
|
char full_path[MAXPGPATH];
|
|
|
|
FILE *file;
|
|
|
|
int ret;
|
|
|
|
long file_major;
|
|
|
|
long my_major;
|
|
|
|
char *endptr;
|
|
|
|
char file_version_string[64];
|
|
|
|
const char *my_version_string = PG_VERSION;
|
|
|
|
|
|
|
|
my_major = strtol(my_version_string, &endptr, 10);
|
|
|
|
|
|
|
|
snprintf(full_path, sizeof(full_path), "%s/PG_VERSION", path);
|
|
|
|
|
|
|
|
file = AllocateFile(full_path, "r");
|
|
|
|
if (!file)
|
|
|
|
{
|
|
|
|
if (errno == ENOENT)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("\"%s\" is not a valid data directory",
|
|
|
|
path),
|
|
|
|
errdetail("File \"%s\" is missing.", full_path)));
|
|
|
|
else
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
|
|
|
errmsg("could not open file \"%s\": %m", full_path)));
|
|
|
|
}
|
|
|
|
|
|
|
|
file_version_string[0] = '\0';
|
|
|
|
ret = fscanf(file, "%63s", file_version_string);
|
|
|
|
file_major = strtol(file_version_string, &endptr, 10);
|
|
|
|
|
|
|
|
if (ret != 1 || endptr == file_version_string)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("\"%s\" is not a valid data directory",
|
|
|
|
path),
|
|
|
|
errdetail("File \"%s\" does not contain valid data.",
|
|
|
|
full_path),
|
Wording cleanup for error messages. Also change can't -> cannot.
Standard English uses "may", "can", and "might" in different ways:
may - permission, "You may borrow my rake."
can - ability, "I can lift that log."
might - possibility, "It might rain today."
Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice. Similarly, "It may crash" is better stated, "It might crash".
19 years ago
|
|
|
errhint("You might need to initdb.")));
|
|
|
|
|
|
|
|
FreeFile(file);
|
|
|
|
|
|
|
|
if (my_major != file_major)
|
|
|
|
ereport(FATAL,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("database files are incompatible with server"),
|
|
|
|
errdetail("The data directory was initialized by PostgreSQL version %s, "
|
|
|
|
"which is not compatible with this version %s.",
|
|
|
|
file_version_string, my_version_string)));
|
|
|
|
}
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Library preload support
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GUC variables: lists of library names to be preloaded at postmaster
|
|
|
|
* start and at backend start
|
|
|
|
*/
|
|
|
|
char *session_preload_libraries_string = NULL;
|
|
|
|
char *shared_preload_libraries_string = NULL;
|
|
|
|
char *local_preload_libraries_string = NULL;
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
|
|
|
|
/* Flag telling that we are loading shared_preload_libraries */
|
|
|
|
bool process_shared_preload_libraries_in_progress = false;
|
|
|
|
bool process_shared_preload_libraries_done = false;
|
|
|
|
|
|
|
|
shmem_request_hook_type shmem_request_hook = NULL;
|
|
|
|
bool process_shmem_requests_in_progress = false;
|
|
|
|
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
/*
|
|
|
|
* load the shared libraries listed in 'libraries'
|
|
|
|
*
|
|
|
|
* 'gucname': name of GUC variable, for error reports
|
|
|
|
* 'restricted': if true, force libraries to be in $libdir/plugins/
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
*/
|
|
|
|
static void
|
|
|
|
load_libraries(const char *libraries, const char *gucname, bool restricted)
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
{
|
|
|
|
char *rawstring;
|
|
|
|
List *elemlist;
|
|
|
|
ListCell *l;
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
|
|
|
|
if (libraries == NULL || libraries[0] == '\0')
|
|
|
|
return; /* nothing to do */
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
|
|
|
|
/* Need a modifiable copy of string */
|
|
|
|
rawstring = pstrdup(libraries);
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
|
|
|
|
/* Parse string into list of filename paths */
|
|
|
|
if (!SplitDirectoriesString(rawstring, ',', &elemlist))
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
{
|
|
|
|
/* syntax error in list */
|
|
|
|
list_free_deep(elemlist);
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
pfree(rawstring);
|
|
|
|
ereport(LOG,
|
|
|
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
|
|
errmsg("invalid list syntax in parameter \"%s\"",
|
|
|
|
gucname)));
|
|
|
|
return;
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
}
|
|
|
|
|
|
|
|
foreach(l, elemlist)
|
|
|
|
{
|
|
|
|
/* Note that filename was already canonicalized */
|
|
|
|
char *filename = (char *) lfirst(l);
|
|
|
|
char *expanded = NULL;
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
|
|
|
|
/* If restricting, insert $libdir/plugins if not mentioned already */
|
|
|
|
if (restricted && first_dir_separator(filename) == NULL)
|
|
|
|
{
|
|
|
|
expanded = psprintf("$libdir/plugins/%s", filename);
|
|
|
|
filename = expanded;
|
|
|
|
}
|
|
|
|
load_file(filename, restricted);
|
|
|
|
ereport(DEBUG1,
|
|
|
|
(errmsg_internal("loaded library \"%s\"", filename)));
|
|
|
|
if (expanded)
|
|
|
|
pfree(expanded);
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
}
|
|
|
|
|
|
|
|
list_free_deep(elemlist);
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
23 years ago
|
|
|
pfree(rawstring);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* process any libraries that should be preloaded at postmaster start
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
process_shared_preload_libraries(void)
|
|
|
|
{
|
|
|
|
process_shared_preload_libraries_in_progress = true;
|
|
|
|
load_libraries(shared_preload_libraries_string,
|
|
|
|
"shared_preload_libraries",
|
|
|
|
false);
|
|
|
|
process_shared_preload_libraries_in_progress = false;
|
|
|
|
process_shared_preload_libraries_done = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* process any libraries that should be preloaded at backend start
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
process_session_preload_libraries(void)
|
|
|
|
{
|
|
|
|
load_libraries(session_preload_libraries_string,
|
|
|
|
"session_preload_libraries",
|
|
|
|
false);
|
|
|
|
load_libraries(local_preload_libraries_string,
|
|
|
|
"local_preload_libraries",
|
|
|
|
true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* process any shared memory requests from preloaded libraries
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
process_shmem_requests(void)
|
|
|
|
{
|
|
|
|
process_shmem_requests_in_progress = true;
|
|
|
|
if (shmem_request_hook)
|
|
|
|
shmem_request_hook();
|
|
|
|
process_shmem_requests_in_progress = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pg_bindtextdomain(const char *domain)
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_NLS
|
|
|
|
if (my_exec_path[0] != '\0')
|
|
|
|
{
|
|
|
|
char locale_path[MAXPGPATH];
|
|
|
|
|
|
|
|
get_locale_path(my_exec_path, locale_path);
|
|
|
|
bindtextdomain(domain, locale_path);
|
|
|
|
pg_bind_textdomain_codeset(domain);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|