#include "nodes/params.h"#include "nodes/parsenodes.h"#include "nodes/plannodes.h"#include "storage/procsignal.h"#include "utils/guc.h"

Go to the source code of this file.
Defines | |
| #define | STACK_DEPTH_SLOP (512 * 1024L) |
Enumerations | |
| enum | LogStmtLevel { LOGSTMT_NONE, LOGSTMT_DDL, LOGSTMT_MOD, LOGSTMT_ALL } |
Functions | |
| List * | pg_parse_query (const char *query_string) |
| List * | pg_analyze_and_rewrite (Node *parsetree, const char *query_string, Oid *paramTypes, int numParams) |
| List * | pg_analyze_and_rewrite_params (Node *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg) |
| PlannedStmt * | pg_plan_query (Query *querytree, int cursorOptions, ParamListInfo boundParams) |
| List * | pg_plan_queries (List *querytrees, int cursorOptions, ParamListInfo boundParams) |
| bool | check_max_stack_depth (int *newval, void **extra, GucSource source) |
| void | assign_max_stack_depth (int newval, void *extra) |
| void | die (SIGNAL_ARGS) |
| void | quickdie (SIGNAL_ARGS) __attribute__((noreturn)) |
| void | StatementCancelHandler (SIGNAL_ARGS) |
| void | FloatExceptionHandler (SIGNAL_ARGS) __attribute__((noreturn)) |
| void | RecoveryConflictInterrupt (ProcSignalReason reason) |
| void | prepare_for_client_read (void) |
| void | client_read_ended (void) |
| void | process_postgres_switches (int argc, char *argv[], GucContext ctx, const char **dbname) |
| void | PostgresMain (int argc, char *argv[], const char *dbname, const char *username) __attribute__((noreturn)) |
| long | get_stack_depth_rlimit (void) |
| void | ResetUsage (void) |
| void | ShowUsage (const char *title) |
| int | check_log_duration (char *msec_str, bool was_logged) |
| void | set_debug_options (int debug_flag, GucContext context, GucSource source) |
| bool | set_plan_disabling_options (const char *arg, GucContext context, GucSource source) |
| const char * | get_stats_option_name (const char *arg) |
Variables | |
| CommandDest | whereToSendOutput |
| PGDLLIMPORT const char * | debug_query_string |
| int | max_stack_depth |
| int | PostAuthDelay |
| int | log_statement |
| #define STACK_DEPTH_SLOP (512 * 1024L) |
Definition at line 30 of file tcopprot.h.
Referenced by check_max_stack_depth().
| enum LogStmtLevel |
Definition at line 39 of file tcopprot.h.
{
LOGSTMT_NONE, /* log no statements */
LOGSTMT_DDL, /* log data definition statements */
LOGSTMT_MOD, /* log modification statements, plus DDL */
LOGSTMT_ALL /* log all statements */
} LogStmtLevel;
| void assign_max_stack_depth | ( | int | newval, | |
| void * | extra | |||
| ) |
Definition at line 3129 of file postgres.c.
References max_stack_depth_bytes.
{
long newval_bytes = newval * 1024L;
max_stack_depth_bytes = newval_bytes;
}
| int check_log_duration | ( | char * | msec_str, | |
| bool | was_logged | |||
| ) |
Definition at line 2046 of file postgres.c.
References GetCurrentStatementStartTimestamp(), GetCurrentTimestamp(), log_duration, log_min_duration_statement, snprintf(), and TimestampDifference().
Referenced by exec_bind_message(), exec_execute_message(), exec_parse_message(), exec_simple_query(), and HandleFunctionRequest().
{
if (log_duration || log_min_duration_statement >= 0)
{
long secs;
int usecs;
int msecs;
bool exceeded;
TimestampDifference(GetCurrentStatementStartTimestamp(),
GetCurrentTimestamp(),
&secs, &usecs);
msecs = usecs / 1000;
/*
* This odd-looking test for log_min_duration_statement being exceeded
* is designed to avoid integer overflow with very long durations:
* don't compute secs * 1000 until we've verified it will fit in int.
*/
exceeded = (log_min_duration_statement == 0 ||
(log_min_duration_statement > 0 &&
(secs > log_min_duration_statement / 1000 ||
secs * 1000 + msecs >= log_min_duration_statement)));
if (exceeded || log_duration)
{
snprintf(msec_str, 32, "%ld.%03d",
secs * 1000 + msecs, usecs % 1000);
if (exceeded && !was_logged)
return 2;
else
return 1;
}
}
return 0;
}
Definition at line 3112 of file postgres.c.
References get_stack_depth_rlimit(), GUC_check_errdetail, GUC_check_errhint, and STACK_DEPTH_SLOP.
{
long newval_bytes = *newval * 1024L;
long stack_rlimit = get_stack_depth_rlimit();
if (stack_rlimit > 0 && newval_bytes > stack_rlimit - STACK_DEPTH_SLOP)
{
GUC_check_errdetail("\"max_stack_depth\" must not exceed %ldkB.",
(stack_rlimit - STACK_DEPTH_SLOP) / 1024L);
GUC_check_errhint("Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent.");
return false;
}
return true;
}
| void client_read_ended | ( | void | ) |
Definition at line 531 of file postgres.c.
References DisableCatchupInterrupt(), DisableNotifyInterrupt(), DoingCommandRead, and ImmediateInterruptOK.
Referenced by interactive_getc(), and secure_read().
{
if (DoingCommandRead)
{
ImmediateInterruptOK = false;
DisableNotifyInterrupt();
DisableCatchupInterrupt();
}
}
| void die | ( | SIGNAL_ARGS | ) |
Definition at line 2576 of file postgres.c.
References CritSectionCount, DisableCatchupInterrupt(), DisableNotifyInterrupt(), ImmediateInterruptOK, InterruptHoldoffCount, InterruptPending, LockErrorCleanup(), MyProc, proc_exit_inprogress, ProcDiePending, ProcessInterrupts(), PGPROC::procLatch, and SetLatch().
{
int save_errno = errno;
/* Don't joggle the elbow of proc_exit */
if (!proc_exit_inprogress)
{
InterruptPending = true;
ProcDiePending = true;
/*
* If it's safe to interrupt, and we're waiting for input or a lock,
* service the interrupt immediately
*/
if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
CritSectionCount == 0)
{
/* bump holdoff count to make ProcessInterrupts() a no-op */
/* until we are done getting ready for it */
InterruptHoldoffCount++;
LockErrorCleanup(); /* prevent CheckDeadLock from running */
DisableNotifyInterrupt();
DisableCatchupInterrupt();
InterruptHoldoffCount--;
ProcessInterrupts();
}
}
/* If we're still here, waken anything waiting on the process latch */
if (MyProc)
SetLatch(&MyProc->procLatch);
errno = save_errno;
}
| void FloatExceptionHandler | ( | SIGNAL_ARGS | ) |
Definition at line 2655 of file postgres.c.
References ereport, errcode(), errdetail(), errmsg(), and ERROR.
Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), do_start_bgworker(), plperl_init_interp(), and PostgresMain().
{
/* We're not returning, so no need to save errno */
ereport(ERROR,
(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
errmsg("floating-point exception"),
errdetail("An invalid floating-point operation was signaled. "
"This probably means an out-of-range result or an "
"invalid operation, such as division by zero.")));
}
| long get_stack_depth_rlimit | ( | void | ) |
Definition at line 4259 of file postgres.c.
References val.
Referenced by check_max_stack_depth(), and InitializeGUCOptionsFromEnvironment().
{
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_STACK)
static long val = 0;
/* This won't change after process launch, so check just once */
if (val == 0)
{
struct rlimit rlim;
if (getrlimit(RLIMIT_STACK, &rlim) < 0)
val = -1;
else if (rlim.rlim_cur == RLIM_INFINITY)
val = LONG_MAX;
/* rlim_cur is probably of an unsigned type, so check for overflow */
else if (rlim.rlim_cur >= LONG_MAX)
val = LONG_MAX;
else
val = rlim.rlim_cur;
}
return val;
#else /* no getrlimit */
#if defined(WIN32) || defined(__CYGWIN__)
/* On Windows we set the backend stack size in src/backend/Makefile */
return WIN32_STACK_RLIMIT;
#else /* not windows ... give up */
return -1;
#endif
#endif
}
| const char* get_stats_option_name | ( | const char * | arg | ) |
Definition at line 3215 of file postgres.c.
References optarg.
Referenced by PostmasterMain(), and process_postgres_switches().
| List* pg_analyze_and_rewrite | ( | Node * | parsetree, | |
| const char * | query_string, | |||
| Oid * | paramTypes, | |||
| int | numParams | |||
| ) |
Definition at line 599 of file postgres.c.
References log_parser_stats, parse_analyze(), pg_rewrite_query(), ResetUsage(), and ShowUsage().
Referenced by _SPI_execute_plan(), _SPI_prepare_plan(), BeginCopy(), exec_simple_query(), execute_sql_string(), and RevalidateCachedQuery().
{
Query *query;
List *querytree_list;
TRACE_POSTGRESQL_QUERY_REWRITE_START(query_string);
/*
* (1) Perform parse analysis.
*/
if (log_parser_stats)
ResetUsage();
query = parse_analyze(parsetree, query_string, paramTypes, numParams);
if (log_parser_stats)
ShowUsage("PARSE ANALYSIS STATISTICS");
/*
* (2) Rewrite the queries, as necessary
*/
querytree_list = pg_rewrite_query(query);
TRACE_POSTGRESQL_QUERY_REWRITE_DONE(query_string);
return querytree_list;
}
| List* pg_analyze_and_rewrite_params | ( | Node * | parsetree, | |
| const char * | query_string, | |||
| ParserSetupHook | parserSetup, | |||
| void * | parserSetupArg | |||
| ) |
Definition at line 634 of file postgres.c.
References Assert, free_parsestate(), log_parser_stats, make_parsestate(), NULL, ParseState::p_sourcetext, pg_rewrite_query(), post_parse_analyze_hook, ResetUsage(), ShowUsage(), and transformTopLevelStmt().
Referenced by _SPI_execute_plan(), _SPI_prepare_plan(), fmgr_sql_validator(), init_sql_fcache(), inline_set_returning_function(), and RevalidateCachedQuery().
{
ParseState *pstate;
Query *query;
List *querytree_list;
Assert(query_string != NULL); /* required as of 8.4 */
TRACE_POSTGRESQL_QUERY_REWRITE_START(query_string);
/*
* (1) Perform parse analysis.
*/
if (log_parser_stats)
ResetUsage();
pstate = make_parsestate(NULL);
pstate->p_sourcetext = query_string;
(*parserSetup) (pstate, parserSetupArg);
query = transformTopLevelStmt(pstate, parsetree);
if (post_parse_analyze_hook)
(*post_parse_analyze_hook) (pstate, query);
free_parsestate(pstate);
if (log_parser_stats)
ShowUsage("PARSE ANALYSIS STATISTICS");
/*
* (2) Rewrite the queries, as necessary
*/
querytree_list = pg_rewrite_query(query);
TRACE_POSTGRESQL_QUERY_REWRITE_DONE(query_string);
return querytree_list;
}
| List* pg_parse_query | ( | const char * | query_string | ) |
Definition at line 557 of file postgres.c.
References copyObject(), elog, equal(), log_parser_stats, new_list(), raw_parser(), ResetUsage(), ShowUsage(), and WARNING.
Referenced by _SPI_prepare_oneshot_plan(), _SPI_prepare_plan(), exec_parse_message(), exec_simple_query(), execute_sql_string(), fmgr_sql_validator(), init_sql_fcache(), inline_function(), and inline_set_returning_function().
{
List *raw_parsetree_list;
TRACE_POSTGRESQL_QUERY_PARSE_START(query_string);
if (log_parser_stats)
ResetUsage();
raw_parsetree_list = raw_parser(query_string);
if (log_parser_stats)
ShowUsage("PARSER STATISTICS");
#ifdef COPY_PARSE_PLAN_TREES
/* Optional debugging check: pass raw parsetrees through copyObject() */
{
List *new_list = (List *) copyObject(raw_parsetree_list);
/* This checks both copyObject() and the equal() routines... */
if (!equal(new_list, raw_parsetree_list))
elog(WARNING, "copyObject() failed to produce an equal raw parse tree");
else
raw_parsetree_list = new_list;
}
#endif
TRACE_POSTGRESQL_QUERY_PARSE_DONE(query_string);
return raw_parsetree_list;
}
| List* pg_plan_queries | ( | List * | querytrees, | |
| int | cursorOptions, | |||
| ParamListInfo | boundParams | |||
| ) |
Definition at line 795 of file postgres.c.
References CMD_UTILITY, Query::commandType, lappend(), lfirst, pg_plan_query(), and Query::utilityStmt.
Referenced by BuildCachedPlan(), exec_simple_query(), and execute_sql_string().
{
List *stmt_list = NIL;
ListCell *query_list;
foreach(query_list, querytrees)
{
Query *query = (Query *) lfirst(query_list);
Node *stmt;
if (query->commandType == CMD_UTILITY)
{
/* Utility commands have no plans. */
stmt = query->utilityStmt;
}
else
{
stmt = (Node *) pg_plan_query(query, cursorOptions, boundParams);
}
stmt_list = lappend(stmt_list, stmt);
}
return stmt_list;
}
| PlannedStmt* pg_plan_query | ( | Query * | querytree, | |
| int | cursorOptions, | |||
| ParamListInfo | boundParams | |||
| ) |
Definition at line 736 of file postgres.c.
References ActiveSnapshotSet(), Assert, CMD_UTILITY, Query::commandType, copyObject(), Debug_pretty_print, Debug_print_plan, elog, elog_node_display(), equal(), LOG, log_planner_stats, planner(), ResetUsage(), ShowUsage(), and WARNING.
Referenced by ExecCreateTableAs(), ExplainOneQuery(), init_execution_state(), pg_plan_queries(), and refresh_matview_datafill().
{
PlannedStmt *plan;
/* Utility commands have no plans. */
if (querytree->commandType == CMD_UTILITY)
return NULL;
/* Planner must have a snapshot in case it calls user-defined functions. */
Assert(ActiveSnapshotSet());
TRACE_POSTGRESQL_QUERY_PLAN_START();
if (log_planner_stats)
ResetUsage();
/* call the optimizer */
plan = planner(querytree, cursorOptions, boundParams);
if (log_planner_stats)
ShowUsage("PLANNER STATISTICS");
#ifdef COPY_PARSE_PLAN_TREES
/* Optional debugging check: pass plan output through copyObject() */
{
PlannedStmt *new_plan = (PlannedStmt *) copyObject(plan);
/*
* equal() currently does not have routines to compare Plan nodes, so
* don't try to test equality here. Perhaps fix someday?
*/
#ifdef NOT_USED
/* This checks both copyObject() and the equal() routines... */
if (!equal(new_plan, plan))
elog(WARNING, "copyObject() failed to produce an equal plan tree");
else
#endif
plan = new_plan;
}
#endif
/*
* Print plan if debugging.
*/
if (Debug_print_plan)
elog_node_display(LOG, "plan", plan, Debug_pretty_print);
TRACE_POSTGRESQL_QUERY_PLAN_DONE();
return plan;
}
| void PostgresMain | ( | int | argc, | |
| char * | argv[], | |||
| const char * | dbname, | |||
| const char * | username | |||
| ) |
Definition at line 3518 of file postgres.c.
References AbortCurrentTransaction(), ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, AllocSetContextCreate(), am_walsender, Assert, BaseInit(), BeginReportingGUCOptions(), BlockSig, buf, ChangeToDataDir(), CreateDataDirLockFile(), DataDir, debug_query_string, DestDebug, DestRemote, die(), disable_all_timeouts(), DisableCatchupInterrupt(), DisableNotifyInterrupt(), doing_extended_query_message, DoingCommandRead, drop_unnamed_stmt(), DropPreparedStatement(), elog, EmitErrorReport(), ereport, errcode(), errmsg(), ERROR, error_context_stack, exec_bind_message(), exec_describe_portal_message(), exec_describe_statement_message(), exec_execute_message(), exec_parse_message(), exec_replication_command(), exec_simple_query(), FATAL, find_my_exec(), finish_xact_command(), FloatExceptionHandler(), FlushErrorState(), forbidden_in_wal_sender(), FrontendProtocol, get_pkglib_path(), GetCurrentTimestamp(), GetPortalByName(), got_SIGHUP, HandleFunctionRequest(), HOLD_INTERRUPTS, i, ignore_till_sync, InitializeGUCOptions(), InitializeMaxBackends(), InitializeTimeouts(), InitPostgres(), InitProcess(), InitProcessing, initStringInfo(), InitWalSender(), InvalidOid, IsAbortedTransactionBlockState(), IsTransactionOrTransactionBlock(), IsUnderPostmaster, log_disconnections(), Log_disconnections, MemoryContextDelete(), MemoryContextInit(), MemoryContextResetAndDeleteChildren(), MemoryContextSwitchTo(), MessageContext, my_exec_path, MyCancelKey, MyProcPid, MyStartTime, NormalProcessing, NULL, on_proc_exit(), palloc(), PG_exception_stack, PG_PROTOCOL_MAJOR, PG_SETMASK, PGC_POSTMASTER, PGC_SIGHUP, PgStartTime, pgstat_report_activity(), pgstat_report_stat(), pkglib_path, PortalDrop(), PortalIsValid, PostmasterContext, pq_beginmessage(), pq_comm_reset(), pq_endmessage(), pq_flush(), pq_getmsgbyte(), pq_getmsgend(), pq_getmsgint(), pq_getmsgstring(), pq_putemptymessage(), pq_sendint(), pqinitmask(), pqsignal(), proc_exit(), process_local_preload_libraries(), process_postgres_switches(), ProcessCompletedNotifies(), ProcessConfigFile(), procsignal_sigusr1_handler(), progname, QueryCancelPending, quickdie(), ReadCommand(), ReadyForQuery(), RESUME_INTERRUPTS, SelectConfigFiles(), set_ps_display(), SetCurrentStatementStartTimestamp(), SetProcessingMode, SIG_DFL, SIG_IGN, SIGCHLD, sigdelset, SIGHUP, SigHupHandler(), sigjmp_buf, SIGPIPE, SIGQUIT, sigsetjmp, SIGUSR1, SIGUSR2, start_xact_command(), STATE_FASTPATH, STATE_IDLE, STATE_IDLEINTRANSACTION, STATE_IDLEINTRANSACTION_ABORTED, StatementCancelHandler(), TopMemoryContext, UnBlockSig, userDoption, ValidatePgVersion(), WalSndErrorCleanup(), WalSndSignals(), whereToSendOutput, and xact_started.
Referenced by BackendRun(), and main().
{
int firstchar;
StringInfoData input_message;
sigjmp_buf local_sigjmp_buf;
volatile bool send_ready_for_query = true;
/*
* Initialize globals (already done if under postmaster, but not if
* standalone).
*/
if (!IsUnderPostmaster)
{
MyProcPid = getpid();
MyStartTime = time(NULL);
}
/*
* Fire up essential subsystems: error and memory management
*
* If we are running under the postmaster, this is done already.
*/
if (!IsUnderPostmaster)
MemoryContextInit();
SetProcessingMode(InitProcessing);
/* Compute paths, if we didn't inherit them from postmaster */
if (my_exec_path[0] == '\0')
{
if (find_my_exec(argv[0], my_exec_path) < 0)
elog(FATAL, "%s: could not locate my own executable path",
argv[0]);
}
if (pkglib_path[0] == '\0')
get_pkglib_path(my_exec_path, pkglib_path);
/*
* Set default values for command-line options.
*/
if (!IsUnderPostmaster)
InitializeGUCOptions();
/*
* Parse command-line options.
*/
process_postgres_switches(argc, argv, PGC_POSTMASTER, &dbname);
/* Must have gotten a database name, or have a default (the username) */
if (dbname == NULL)
{
dbname = username;
if (dbname == NULL)
ereport(FATAL,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("%s: no database nor user name specified",
progname)));
}
/* Acquire configuration parameters, unless inherited from postmaster */
if (!IsUnderPostmaster)
{
if (!SelectConfigFiles(userDoption, progname))
proc_exit(1);
}
/*
* You might expect to see a setsid() call here, but it's not needed,
* because if we are under a postmaster then BackendInitialize() did it.
*/
/*
* Set up signal handlers and masks.
*
* Note that postmaster blocked all signals before forking child process,
* so there is no race condition whereby we might receive a signal before
* we have set up the handler.
*
* Also note: it's best not to use any signals that are SIG_IGNored in the
* postmaster. If such a signal arrives before we are able to change the
* handler to non-SIG_IGN, it'll get dropped. Instead, make a dummy
* handler in the postmaster to reserve the signal. (Of course, this isn't
* an issue for signals that are locally generated, such as SIGALRM and
* SIGPIPE.)
*/
if (am_walsender)
WalSndSignals();
else
{
pqsignal(SIGHUP, SigHupHandler); /* set flag to read config
* file */
pqsignal(SIGINT, StatementCancelHandler); /* cancel current query */
pqsignal(SIGTERM, die); /* cancel current query and exit */
/*
* In a standalone backend, SIGQUIT can be generated from the keyboard
* easily, while SIGTERM cannot, so we make both signals do die()
* rather than quickdie().
*/
if (IsUnderPostmaster)
pqsignal(SIGQUIT, quickdie); /* hard crash time */
else
pqsignal(SIGQUIT, die); /* cancel current query and exit */
InitializeTimeouts(); /* establishes SIGALRM handler */
/*
* Ignore failure to write to frontend. Note: if frontend closes
* connection, we will notice it and exit cleanly when control next
* returns to outer loop. This seems safer than forcing exit in the
* midst of output during who-knows-what operation...
*/
pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, procsignal_sigusr1_handler);
pqsignal(SIGUSR2, SIG_IGN);
pqsignal(SIGFPE, FloatExceptionHandler);
/*
* Reset some signals that are accepted by postmaster but not by
* backend
*/
pqsignal(SIGCHLD, SIG_DFL); /* system() requires this on some
* platforms */
}
pqinitmask();
if (IsUnderPostmaster)
{
/* We allow SIGQUIT (quickdie) at all times */
sigdelset(&BlockSig, SIGQUIT);
}
PG_SETMASK(&BlockSig); /* block everything except SIGQUIT */
if (!IsUnderPostmaster)
{
/*
* Validate we have been given a reasonable-looking DataDir (if under
* postmaster, assume postmaster did this already).
*/
Assert(DataDir);
ValidatePgVersion(DataDir);
/* Change into DataDir (if under postmaster, was done already) */
ChangeToDataDir();
/*
* Create lockfile for data directory.
*/
CreateDataDirLockFile(false);
/* Initialize MaxBackends (if under postmaster, was done already) */
InitializeMaxBackends();
}
/* Early initialization */
BaseInit();
/*
* Create a per-backend PGPROC struct in shared memory, except in the
* EXEC_BACKEND case where this was done in SubPostmasterMain. We must do
* this before we can use LWLocks (and in the EXEC_BACKEND case we already
* had to do some stuff with LWLocks).
*/
#ifdef EXEC_BACKEND
if (!IsUnderPostmaster)
InitProcess();
#else
InitProcess();
#endif
/* We need to allow SIGINT, etc during the initial transaction */
PG_SETMASK(&UnBlockSig);
/*
* General initialization.
*
* NOTE: if you are tempted to add code in this vicinity, consider putting
* it inside InitPostgres() instead. In particular, anything that
* involves database access should be there, not here.
*/
InitPostgres(dbname, InvalidOid, username, NULL);
/*
* If the PostmasterContext is still around, recycle the space; we don't
* need it anymore after InitPostgres completes. Note this does not trash
* *MyProcPort, because ConnCreate() allocated that space with malloc()
* ... else we'd need to copy the Port data first. Also, subsidiary data
* such as the username isn't lost either; see ProcessStartupPacket().
*/
if (PostmasterContext)
{
MemoryContextDelete(PostmasterContext);
PostmasterContext = NULL;
}
SetProcessingMode(NormalProcessing);
/*
* Now all GUC states are fully set up. Report them to client if
* appropriate.
*/
BeginReportingGUCOptions();
/*
* Also set up handler to log session end; we have to wait till now to be
* sure Log_disconnections has its final value.
*/
if (IsUnderPostmaster && Log_disconnections)
on_proc_exit(log_disconnections, 0);
/* Perform initialization specific to a WAL sender process. */
if (am_walsender)
InitWalSender();
/*
* process any libraries that should be preloaded at backend start (this
* likewise can't be done until GUC settings are complete)
*/
process_local_preload_libraries();
/*
* Send this backend's cancellation info to the frontend.
*/
if (whereToSendOutput == DestRemote &&
PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
{
StringInfoData buf;
pq_beginmessage(&buf, 'K');
pq_sendint(&buf, (int32) MyProcPid, sizeof(int32));
pq_sendint(&buf, (int32) MyCancelKey, sizeof(int32));
pq_endmessage(&buf);
/* Need not flush since ReadyForQuery will do it. */
}
/* Welcome banner for standalone case */
if (whereToSendOutput == DestDebug)
printf("\nPostgreSQL stand-alone backend %s\n", PG_VERSION);
/*
* Create the memory context we will use in the main loop.
*
* MessageContext is reset once per iteration of the main loop, ie, upon
* completion of processing of each command message from the client.
*/
MessageContext = AllocSetContextCreate(TopMemoryContext,
"MessageContext",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
/*
* Remember stand-alone backend startup time
*/
if (!IsUnderPostmaster)
PgStartTime = GetCurrentTimestamp();
/*
* POSTGRES main processing loop begins here
*
* If an exception is encountered, processing resumes here so we abort the
* current transaction and start a new one.
*
* You might wonder why this isn't coded as an infinite loop around a
* PG_TRY construct. The reason is that this is the bottom of the
* exception stack, and so with PG_TRY there would be no exception handler
* in force at all during the CATCH part. By leaving the outermost setjmp
* always active, we have at least some chance of recovering from an error
* during error recovery. (If we get into an infinite loop thereby, it
* will soon be stopped by overflow of elog.c's internal state stack.)
*/
if (sigsetjmp(local_sigjmp_buf, 1) != 0)
{
/*
* NOTE: if you are tempted to add more code in this if-block,
* consider the high probability that it should be in
* AbortTransaction() instead. The only stuff done directly here
* should be stuff that is guaranteed to apply *only* for outer-level
* error recovery, such as adjusting the FE/BE protocol status.
*/
/* Since not using PG_TRY, must reset error stack by hand */
error_context_stack = NULL;
/* Prevent interrupts while cleaning up */
HOLD_INTERRUPTS();
/*
* Forget any pending QueryCancel request, since we're returning to
* the idle loop anyway, and cancel any active timeout requests.
*/
QueryCancelPending = false;
disable_all_timeouts(false);
QueryCancelPending = false; /* again in case timeout occurred */
/*
* Turn off these interrupts too. This is only needed here and not in
* other exception-catching places since these interrupts are only
* enabled while we wait for client input.
*/
DoingCommandRead = false;
DisableNotifyInterrupt();
DisableCatchupInterrupt();
/* Make sure libpq is in a good state */
pq_comm_reset();
/* Report the error to the client and/or server log */
EmitErrorReport();
/*
* Make sure debug_query_string gets reset before we possibly clobber
* the storage it points at.
*/
debug_query_string = NULL;
/*
* Abort the current transaction in order to recover.
*/
AbortCurrentTransaction();
if (am_walsender)
WalSndErrorCleanup();
/*
* Now return to normal top-level context and clear ErrorContext for
* next time.
*/
MemoryContextSwitchTo(TopMemoryContext);
FlushErrorState();
/*
* If we were handling an extended-query-protocol message, initiate
* skip till next Sync. This also causes us not to issue
* ReadyForQuery (until we get Sync).
*/
if (doing_extended_query_message)
ignore_till_sync = true;
/* We don't have a transaction command open anymore */
xact_started = false;
/* Now we can allow interrupts again */
RESUME_INTERRUPTS();
}
/* We can now handle ereport(ERROR) */
PG_exception_stack = &local_sigjmp_buf;
if (!ignore_till_sync)
send_ready_for_query = true; /* initially, or after error */
/*
* Non-error queries loop here.
*/
for (;;)
{
/*
* At top of loop, reset extended-query-message flag, so that any
* errors encountered in "idle" state don't provoke skip.
*/
doing_extended_query_message = false;
/*
* Release storage left over from prior query cycle, and create a new
* query input buffer in the cleared MessageContext.
*/
MemoryContextSwitchTo(MessageContext);
MemoryContextResetAndDeleteChildren(MessageContext);
initStringInfo(&input_message);
/*
* (1) If we've reached idle state, tell the frontend we're ready for
* a new query.
*
* Note: this includes fflush()'ing the last of the prior output.
*
* This is also a good time to send collected statistics to the
* collector, and to update the PS stats display. We avoid doing
* those every time through the message loop because it'd slow down
* processing of batched messages, and because we don't want to report
* uncommitted updates (that confuses autovacuum). The notification
* processor wants a call too, if we are not in a transaction block.
*/
if (send_ready_for_query)
{
if (IsAbortedTransactionBlockState())
{
set_ps_display("idle in transaction (aborted)", false);
pgstat_report_activity(STATE_IDLEINTRANSACTION_ABORTED, NULL);
}
else if (IsTransactionOrTransactionBlock())
{
set_ps_display("idle in transaction", false);
pgstat_report_activity(STATE_IDLEINTRANSACTION, NULL);
}
else
{
ProcessCompletedNotifies();
pgstat_report_stat(false);
set_ps_display("idle", false);
pgstat_report_activity(STATE_IDLE, NULL);
}
ReadyForQuery(whereToSendOutput);
send_ready_for_query = false;
}
/*
* (2) Allow asynchronous signals to be executed immediately if they
* come in while we are waiting for client input. (This must be
* conditional since we don't want, say, reads on behalf of COPY FROM
* STDIN doing the same thing.)
*/
DoingCommandRead = true;
/*
* (3) read a command (loop blocks here)
*/
firstchar = ReadCommand(&input_message);
/*
* (4) disable async signal conditions again.
*/
DoingCommandRead = false;
/*
* (5) check for any other interesting events that happened while we
* slept.
*/
if (got_SIGHUP)
{
got_SIGHUP = false;
ProcessConfigFile(PGC_SIGHUP);
}
/*
* (6) process the command. But ignore it if we're skipping till
* Sync.
*/
if (ignore_till_sync && firstchar != EOF)
continue;
switch (firstchar)
{
case 'Q': /* simple query */
{
const char *query_string;
/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();
query_string = pq_getmsgstring(&input_message);
pq_getmsgend(&input_message);
if (am_walsender)
exec_replication_command(query_string);
else
exec_simple_query(query_string);
send_ready_for_query = true;
}
break;
case 'P': /* parse */
{
const char *stmt_name;
const char *query_string;
int numParams;
Oid *paramTypes = NULL;
forbidden_in_wal_sender(firstchar);
/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();
stmt_name = pq_getmsgstring(&input_message);
query_string = pq_getmsgstring(&input_message);
numParams = pq_getmsgint(&input_message, 2);
if (numParams > 0)
{
int i;
paramTypes = (Oid *) palloc(numParams * sizeof(Oid));
for (i = 0; i < numParams; i++)
paramTypes[i] = pq_getmsgint(&input_message, 4);
}
pq_getmsgend(&input_message);
exec_parse_message(query_string, stmt_name,
paramTypes, numParams);
}
break;
case 'B': /* bind */
forbidden_in_wal_sender(firstchar);
/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();
/*
* this message is complex enough that it seems best to put
* the field extraction out-of-line
*/
exec_bind_message(&input_message);
break;
case 'E': /* execute */
{
const char *portal_name;
int max_rows;
forbidden_in_wal_sender(firstchar);
/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();
portal_name = pq_getmsgstring(&input_message);
max_rows = pq_getmsgint(&input_message, 4);
pq_getmsgend(&input_message);
exec_execute_message(portal_name, max_rows);
}
break;
case 'F': /* fastpath function call */
forbidden_in_wal_sender(firstchar);
/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();
/* Report query to various monitoring facilities. */
pgstat_report_activity(STATE_FASTPATH, NULL);
set_ps_display("<FASTPATH>", false);
/* start an xact for this function invocation */
start_xact_command();
/*
* Note: we may at this point be inside an aborted
* transaction. We can't throw error for that until we've
* finished reading the function-call message, so
* HandleFunctionRequest() must check for it after doing so.
* Be careful not to do anything that assumes we're inside a
* valid transaction here.
*/
/* switch back to message context */
MemoryContextSwitchTo(MessageContext);
if (HandleFunctionRequest(&input_message) == EOF)
{
/* lost frontend connection during F message input */
/*
* Reset whereToSendOutput to prevent ereport from
* attempting to send any more messages to client.
*/
if (whereToSendOutput == DestRemote)
whereToSendOutput = DestNone;
proc_exit(0);
}
/* commit the function-invocation transaction */
finish_xact_command();
send_ready_for_query = true;
break;
case 'C': /* close */
{
int close_type;
const char *close_target;
forbidden_in_wal_sender(firstchar);
close_type = pq_getmsgbyte(&input_message);
close_target = pq_getmsgstring(&input_message);
pq_getmsgend(&input_message);
switch (close_type)
{
case 'S':
if (close_target[0] != '\0')
DropPreparedStatement(close_target, false);
else
{
/* special-case the unnamed statement */
drop_unnamed_stmt();
}
break;
case 'P':
{
Portal portal;
portal = GetPortalByName(close_target);
if (PortalIsValid(portal))
PortalDrop(portal, false);
}
break;
default:
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("invalid CLOSE message subtype %d",
close_type)));
break;
}
if (whereToSendOutput == DestRemote)
pq_putemptymessage('3'); /* CloseComplete */
}
break;
case 'D': /* describe */
{
int describe_type;
const char *describe_target;
forbidden_in_wal_sender(firstchar);
/* Set statement_timestamp() (needed for xact) */
SetCurrentStatementStartTimestamp();
describe_type = pq_getmsgbyte(&input_message);
describe_target = pq_getmsgstring(&input_message);
pq_getmsgend(&input_message);
switch (describe_type)
{
case 'S':
exec_describe_statement_message(describe_target);
break;
case 'P':
exec_describe_portal_message(describe_target);
break;
default:
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("invalid DESCRIBE message subtype %d",
describe_type)));
break;
}
}
break;
case 'H': /* flush */
pq_getmsgend(&input_message);
if (whereToSendOutput == DestRemote)
pq_flush();
break;
case 'S': /* sync */
pq_getmsgend(&input_message);
finish_xact_command();
send_ready_for_query = true;
break;
/*
* 'X' means that the frontend is closing down the socket. EOF
* means unexpected loss of frontend connection. Either way,
* perform normal shutdown.
*/
case 'X':
case EOF:
/*
* Reset whereToSendOutput to prevent ereport from attempting
* to send any more messages to client.
*/
if (whereToSendOutput == DestRemote)
whereToSendOutput = DestNone;
/*
* NOTE: if you are tempted to add more code here, DON'T!
* Whatever you had in mind to do should be set up as an
* on_proc_exit or on_shmem_exit callback, instead. Otherwise
* it will fail to be called during other backend-shutdown
* scenarios.
*/
proc_exit(0);
case 'd': /* copy data */
case 'c': /* copy done */
case 'f': /* copy fail */
/*
* Accept but ignore these messages, per protocol spec; we
* probably got here because a COPY failed, and the frontend
* is still sending data.
*/
break;
default:
ereport(FATAL,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("invalid frontend message type %d",
firstchar)));
}
} /* end of input-reading loop */
}
| void prepare_for_client_read | ( | void | ) |
Definition at line 511 of file postgres.c.
References CHECK_FOR_INTERRUPTS, DoingCommandRead, EnableCatchupInterrupt(), EnableNotifyInterrupt(), and ImmediateInterruptOK.
Referenced by interactive_getc(), and secure_read().
{
if (DoingCommandRead)
{
/* Enable immediate processing of asynchronous signals */
EnableNotifyInterrupt();
EnableCatchupInterrupt();
/* Allow cancel/die interrupts to be processed while waiting */
ImmediateInterruptOK = true;
/* And don't forget to detect one that already arrived */
CHECK_FOR_INTERRUPTS();
}
}
| void process_postgres_switches | ( | int | argc, | |
| char * | argv[], | |||
| GucContext | ctx, | |||
| const char ** | dbname | |||
| ) |
Definition at line 3255 of file postgres.c.
References EchoQuery, ereport, errcode(), errhint(), errmsg(), ERROR, FATAL, free, FrontendProtocol, get_stats_option_name(), getopt(), IsBinaryUpgrade, IsUnderPostmaster, MAXPGPATH, name, NULL, optarg, opterr, optind, OutputFileName, ParseLongOption(), progname, set_debug_options(), set_plan_disabling_options(), SetConfigOption(), strlcpy(), UseNewLine, userDoption, and value.
Referenced by PostgresMain(), and process_startup_options().
{
bool secure = (ctx == PGC_POSTMASTER);
int errs = 0;
GucSource gucsource;
int flag;
if (secure)
{
gucsource = PGC_S_ARGV; /* switches came from command line */
/* Ignore the initial --single argument, if present */
if (argc > 1 && strcmp(argv[1], "--single") == 0)
{
argv++;
argc--;
}
}
else
{
gucsource = PGC_S_CLIENT; /* switches came from client */
}
#ifdef HAVE_INT_OPTERR
/*
* Turn this off because it's either printed to stderr and not the log
* where we'd want it, or argv[0] is now "--single", which would make for
* a weird error message. We print our own error message below.
*/
opterr = 0;
#endif
/*
* Parse command-line options. CAUTION: keep this in sync with
* postmaster/postmaster.c (the option sets should not conflict) and with
* the common help() function in main/main.c.
*/
while ((flag = getopt(argc, argv, "A:B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:v:W:-:")) != -1)
{
switch (flag)
{
case 'A':
SetConfigOption("debug_assertions", optarg, ctx, gucsource);
break;
case 'B':
SetConfigOption("shared_buffers", optarg, ctx, gucsource);
break;
case 'b':
/* Undocumented flag used for binary upgrades */
if (secure)
IsBinaryUpgrade = true;
break;
case 'C':
/* ignored for consistency with the postmaster */
break;
case 'D':
if (secure)
userDoption = strdup(optarg);
break;
case 'd':
set_debug_options(atoi(optarg), ctx, gucsource);
break;
case 'E':
if (secure)
EchoQuery = true;
break;
case 'e':
SetConfigOption("datestyle", "euro", ctx, gucsource);
break;
case 'F':
SetConfigOption("fsync", "false", ctx, gucsource);
break;
case 'f':
if (!set_plan_disabling_options(optarg, ctx, gucsource))
errs++;
break;
case 'h':
SetConfigOption("listen_addresses", optarg, ctx, gucsource);
break;
case 'i':
SetConfigOption("listen_addresses", "*", ctx, gucsource);
break;
case 'j':
if (secure)
UseNewLine = 0;
break;
case 'k':
SetConfigOption("unix_socket_directories", optarg, ctx, gucsource);
break;
case 'l':
SetConfigOption("ssl", "true", ctx, gucsource);
break;
case 'N':
SetConfigOption("max_connections", optarg, ctx, gucsource);
break;
case 'n':
/* ignored for consistency with postmaster */
break;
case 'O':
SetConfigOption("allow_system_table_mods", "true", ctx, gucsource);
break;
case 'o':
errs++;
break;
case 'P':
SetConfigOption("ignore_system_indexes", "true", ctx, gucsource);
break;
case 'p':
SetConfigOption("port", optarg, ctx, gucsource);
break;
case 'r':
/* send output (stdout and stderr) to the given file */
if (secure)
strlcpy(OutputFileName, optarg, MAXPGPATH);
break;
case 'S':
SetConfigOption("work_mem", optarg, ctx, gucsource);
break;
case 's':
SetConfigOption("log_statement_stats", "true", ctx, gucsource);
break;
case 'T':
/* ignored for consistency with the postmaster */
break;
case 't':
{
const char *tmp = get_stats_option_name(optarg);
if (tmp)
SetConfigOption(tmp, "true", ctx, gucsource);
else
errs++;
break;
}
case 'v':
/*
* -v is no longer used in normal operation, since
* FrontendProtocol is already set before we get here. We keep
* the switch only for possible use in standalone operation,
* in case we ever support using normal FE/BE protocol with a
* standalone backend.
*/
if (secure)
FrontendProtocol = (ProtocolVersion) atoi(optarg);
break;
case 'W':
SetConfigOption("post_auth_delay", optarg, ctx, gucsource);
break;
case 'c':
case '-':
{
char *name,
*value;
ParseLongOption(optarg, &name, &value);
if (!value)
{
if (flag == '-')
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("--%s requires a value",
optarg)));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("-c %s requires a value",
optarg)));
}
SetConfigOption(name, value, ctx, gucsource);
free(name);
if (value)
free(value);
break;
}
default:
errs++;
break;
}
if (errs)
break;
}
/*
* Optional database name should be there only if *dbname is NULL.
*/
if (!errs && dbname && *dbname == NULL && argc - optind >= 1)
*dbname = strdup(argv[optind++]);
if (errs || argc != optind)
{
if (errs)
optind--; /* complain about the previous argument */
/* spell the error message a bit differently depending on context */
if (IsUnderPostmaster)
ereport(FATAL,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid command-line argument for server process: %s", argv[optind]),
errhint("Try \"%s --help\" for more information.", progname)));
else
ereport(FATAL,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("%s: invalid command-line argument: %s",
progname, argv[optind]),
errhint("Try \"%s --help\" for more information.", progname)));
}
/*
* Reset getopt(3) library so that it will work correctly in subprocesses
* or when this function is called a second time with another array.
*/
optind = 1;
#ifdef HAVE_INT_OPTRESET
optreset = 1; /* some systems need this too */
#endif
}
| void quickdie | ( | SIGNAL_ARGS | ) |
Definition at line 2522 of file postgres.c.
References BlockSig, ClientAuthInProgress, DestRemote, ereport, errcode(), errdetail(), errhint(), errmsg(), on_exit_reset(), PG_SETMASK, sigaddset, SIGQUIT, WARNING, and whereToSendOutput.
Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), bootstrap_signals(), PostgresMain(), and WalSndSignals().
{
sigaddset(&BlockSig, SIGQUIT); /* prevent nested calls */
PG_SETMASK(&BlockSig);
/*
* If we're aborting out of client auth, don't risk trying to send
* anything to the client; we will likely violate the protocol, not to
* mention that we may have interrupted the guts of OpenSSL or some
* authentication library.
*/
if (ClientAuthInProgress && whereToSendOutput == DestRemote)
whereToSendOutput = DestNone;
/*
* Ideally this should be ereport(FATAL), but then we'd not get control
* back...
*/
ereport(WARNING,
(errcode(ERRCODE_CRASH_SHUTDOWN),
errmsg("terminating connection because of crash of another server process"),
errdetail("The postmaster has commanded this server process to roll back"
" the current transaction and exit, because another"
" server process exited abnormally and possibly corrupted"
" shared memory."),
errhint("In a moment you should be able to reconnect to the"
" database and repeat your command.")));
/*
* We DO NOT want to run proc_exit() callbacks -- we're here because
* shared memory may be corrupted, so we don't want to try to clean up our
* transaction. Just nail the windows shut and get out of town. Now that
* there's an atexit callback to prevent third-party code from breaking
* things by calling exit() directly, we have to reset the callbacks
* explicitly to make this work as intended.
*/
on_exit_reset();
/*
* Note we do exit(2) not exit(0). This is to force the postmaster into a
* system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
* backend. This is necessary precisely because we don't clean up our
* shared memory state. (The "dead man switch" mechanism in pmsignal.c
* should ensure the postmaster sees this as a crash, too, but no harm in
* being doubly sure.)
*/
exit(2);
}
| void RecoveryConflictInterrupt | ( | ProcSignalReason | reason | ) |
Definition at line 2686 of file postgres.c.
References Assert, CritSectionCount, DisableCatchupInterrupt(), DisableNotifyInterrupt(), elog, FATAL, HoldingBufferPinThatDelaysRecovery(), ImmediateInterruptOK, InterruptHoldoffCount, InterruptPending, IsAbortedTransactionBlockState(), IsSubTransaction(), IsTransactionOrTransactionBlock(), IsWaitingForLock(), LockErrorCleanup(), MyProc, proc_exit_inprogress, ProcDiePending, ProcessInterrupts(), PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, PROCSIG_RECOVERY_CONFLICT_DATABASE, PROCSIG_RECOVERY_CONFLICT_LOCK, PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK, PROCSIG_RECOVERY_CONFLICT_TABLESPACE, QueryCancelPending, RecoveryConflictPending, PGPROC::recoveryConflictPending, RecoveryConflictReason, and RecoveryConflictRetryable.
Referenced by procsignal_sigusr1_handler().
{
int save_errno = errno;
/*
* Don't joggle the elbow of proc_exit
*/
if (!proc_exit_inprogress)
{
RecoveryConflictReason = reason;
switch (reason)
{
case PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK:
/*
* If we aren't waiting for a lock we can never deadlock.
*/
if (!IsWaitingForLock())
return;
/* Intentional drop through to check wait for pin */
case PROCSIG_RECOVERY_CONFLICT_BUFFERPIN:
/*
* If we aren't blocking the Startup process there is nothing
* more to do.
*/
if (!HoldingBufferPinThatDelaysRecovery())
return;
MyProc->recoveryConflictPending = true;
/* Intentional drop through to error handling */
case PROCSIG_RECOVERY_CONFLICT_LOCK:
case PROCSIG_RECOVERY_CONFLICT_TABLESPACE:
case PROCSIG_RECOVERY_CONFLICT_SNAPSHOT:
/*
* If we aren't in a transaction any longer then ignore.
*/
if (!IsTransactionOrTransactionBlock())
return;
/*
* If we can abort just the current subtransaction then we are
* OK to throw an ERROR to resolve the conflict. Otherwise
* drop through to the FATAL case.
*
* XXX other times that we can throw just an ERROR *may* be
* PROCSIG_RECOVERY_CONFLICT_LOCK if no locks are held in
* parent transactions
*
* PROCSIG_RECOVERY_CONFLICT_SNAPSHOT if no snapshots are held
* by parent transactions and the transaction is not
* transaction-snapshot mode
*
* PROCSIG_RECOVERY_CONFLICT_TABLESPACE if no temp files or
* cursors open in parent transactions
*/
if (!IsSubTransaction())
{
/*
* If we already aborted then we no longer need to cancel.
* We do this here since we do not wish to ignore aborted
* subtransactions, which must cause FATAL, currently.
*/
if (IsAbortedTransactionBlockState())
return;
RecoveryConflictPending = true;
QueryCancelPending = true;
InterruptPending = true;
break;
}
/* Intentional drop through to session cancel */
case PROCSIG_RECOVERY_CONFLICT_DATABASE:
RecoveryConflictPending = true;
ProcDiePending = true;
InterruptPending = true;
break;
default:
elog(FATAL, "unrecognized conflict mode: %d",
(int) reason);
}
Assert(RecoveryConflictPending && (QueryCancelPending || ProcDiePending));
/*
* All conflicts apart from database cause dynamic errors where the
* command or transaction can be retried at a later point with some
* potential for success. No need to reset this, since non-retryable
* conflict errors are currently FATAL.
*/
if (reason == PROCSIG_RECOVERY_CONFLICT_DATABASE)
RecoveryConflictRetryable = false;
/*
* If it's safe to interrupt, and we're waiting for input or a lock,
* service the interrupt immediately
*/
if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
CritSectionCount == 0)
{
/* bump holdoff count to make ProcessInterrupts() a no-op */
/* until we are done getting ready for it */
InterruptHoldoffCount++;
LockErrorCleanup(); /* prevent CheckDeadLock from running */
DisableNotifyInterrupt();
DisableCatchupInterrupt();
InterruptHoldoffCount--;
ProcessInterrupts();
}
}
errno = save_errno;
}
| void ResetUsage | ( | void | ) |
Definition at line 4295 of file postgres.c.
References getrusage(), gettimeofday(), NULL, RUSAGE_SELF, Save_r, and Save_t.
Referenced by _bt_leafbuild(), _SPI_pquery(), btbuild(), exec_bind_message(), exec_execute_message(), exec_parse_message(), exec_simple_query(), pg_analyze_and_rewrite(), pg_analyze_and_rewrite_params(), pg_parse_query(), pg_plan_query(), pg_rewrite_query(), PortalRun(), and PortalRunMulti().
{
getrusage(RUSAGE_SELF, &Save_r);
gettimeofday(&Save_t, NULL);
}
| void set_debug_options | ( | int | debug_flag, | |
| GucContext | context, | |||
| GucSource | source | |||
| ) |
Definition at line 3144 of file postgres.c.
References PGC_POSTMASTER, and SetConfigOption().
Referenced by PostmasterMain(), and process_postgres_switches().
{
if (debug_flag > 0)
{
char debugstr[64];
sprintf(debugstr, "debug%d", debug_flag);
SetConfigOption("log_min_messages", debugstr, context, source);
}
else
SetConfigOption("log_min_messages", "notice", context, source);
if (debug_flag >= 1 && context == PGC_POSTMASTER)
{
SetConfigOption("log_connections", "true", context, source);
SetConfigOption("log_disconnections", "true", context, source);
}
if (debug_flag >= 2)
SetConfigOption("log_statement", "all", context, source);
if (debug_flag >= 3)
SetConfigOption("debug_print_parse", "true", context, source);
if (debug_flag >= 4)
SetConfigOption("debug_print_plan", "true", context, source);
if (debug_flag >= 5)
SetConfigOption("debug_print_rewritten", "true", context, source);
}
| bool set_plan_disabling_options | ( | const char * | arg, | |
| GucContext | context, | |||
| GucSource | source | |||
| ) |
Definition at line 3173 of file postgres.c.
References SetConfigOption().
Referenced by PostmasterMain(), and process_postgres_switches().
{
const char *tmp = NULL;
switch (arg[0])
{
case 's': /* seqscan */
tmp = "enable_seqscan";
break;
case 'i': /* indexscan */
tmp = "enable_indexscan";
break;
case 'o': /* indexonlyscan */
tmp = "enable_indexonlyscan";
break;
case 'b': /* bitmapscan */
tmp = "enable_bitmapscan";
break;
case 't': /* tidscan */
tmp = "enable_tidscan";
break;
case 'n': /* nestloop */
tmp = "enable_nestloop";
break;
case 'm': /* mergejoin */
tmp = "enable_mergejoin";
break;
case 'h': /* hashjoin */
tmp = "enable_hashjoin";
break;
}
if (tmp)
{
SetConfigOption(tmp, "false", context, source);
return true;
}
else
return false;
}
| void ShowUsage | ( | const char * | title | ) |
Definition at line 4302 of file postgres.c.
References appendStringInfo(), StringInfoData::data, ereport, errdetail_internal(), errmsg_internal(), getrusage(), gettimeofday(), initStringInfo(), StringInfoData::len, LOG, NULL, pfree(), rusage::ru_stime, rusage::ru_utime, RUSAGE_SELF, Save_r, and Save_t.
Referenced by _bt_leafbuild(), _SPI_pquery(), btbuild(), exec_bind_message(), exec_execute_message(), exec_parse_message(), exec_simple_query(), pg_analyze_and_rewrite(), pg_analyze_and_rewrite_params(), pg_parse_query(), pg_plan_query(), pg_rewrite_query(), PortalRun(), and PortalRunMulti().
{
StringInfoData str;
struct timeval user,
sys;
struct timeval elapse_t;
struct rusage r;
getrusage(RUSAGE_SELF, &r);
gettimeofday(&elapse_t, NULL);
memcpy((char *) &user, (char *) &r.ru_utime, sizeof(user));
memcpy((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
if (elapse_t.tv_usec < Save_t.tv_usec)
{
elapse_t.tv_sec--;
elapse_t.tv_usec += 1000000;
}
if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec)
{
r.ru_utime.tv_sec--;
r.ru_utime.tv_usec += 1000000;
}
if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec)
{
r.ru_stime.tv_sec--;
r.ru_stime.tv_usec += 1000000;
}
/*
* the only stats we don't show here are for memory usage -- i can't
* figure out how to interpret the relevant fields in the rusage struct,
* and they change names across o/s platforms, anyway. if you can figure
* out what the entries mean, you can somehow extract resident set size,
* shared text size, and unshared data and stack sizes.
*/
initStringInfo(&str);
appendStringInfo(&str, "! system usage stats:\n");
appendStringInfo(&str,
"!\t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system sec\n",
(long) (elapse_t.tv_sec - Save_t.tv_sec),
(long) (elapse_t.tv_usec - Save_t.tv_usec),
(long) (r.ru_utime.tv_sec - Save_r.ru_utime.tv_sec),
(long) (r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec),
(long) (r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec),
(long) (r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec));
appendStringInfo(&str,
"!\t[%ld.%06ld user %ld.%06ld sys total]\n",
(long) user.tv_sec,
(long) user.tv_usec,
(long) sys.tv_sec,
(long) sys.tv_usec);
#if defined(HAVE_GETRUSAGE)
appendStringInfo(&str,
"!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
r.ru_inblock - Save_r.ru_inblock,
/* they only drink coffee at dec */
r.ru_oublock - Save_r.ru_oublock,
r.ru_inblock, r.ru_oublock);
appendStringInfo(&str,
"!\t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swaps\n",
r.ru_majflt - Save_r.ru_majflt,
r.ru_minflt - Save_r.ru_minflt,
r.ru_majflt, r.ru_minflt,
r.ru_nswap - Save_r.ru_nswap,
r.ru_nswap);
appendStringInfo(&str,
"!\t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sent\n",
r.ru_nsignals - Save_r.ru_nsignals,
r.ru_nsignals,
r.ru_msgrcv - Save_r.ru_msgrcv,
r.ru_msgsnd - Save_r.ru_msgsnd,
r.ru_msgrcv, r.ru_msgsnd);
appendStringInfo(&str,
"!\t%ld/%ld [%ld/%ld] voluntary/involuntary context switches\n",
r.ru_nvcsw - Save_r.ru_nvcsw,
r.ru_nivcsw - Save_r.ru_nivcsw,
r.ru_nvcsw, r.ru_nivcsw);
#endif /* HAVE_GETRUSAGE */
/* remove trailing newline */
if (str.data[str.len - 1] == '\n')
str.data[--str.len] = '\0';
ereport(LOG,
(errmsg_internal("%s", title),
errdetail_internal("%s", str.data)));
pfree(str.data);
}
| void StatementCancelHandler | ( | SIGNAL_ARGS | ) |
Definition at line 2616 of file postgres.c.
References CritSectionCount, DisableCatchupInterrupt(), DisableNotifyInterrupt(), ImmediateInterruptOK, InterruptHoldoffCount, InterruptPending, LockErrorCleanup(), MyProc, proc_exit_inprogress, ProcessInterrupts(), PGPROC::procLatch, QueryCancelPending, and SetLatch().
Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), do_start_bgworker(), and PostgresMain().
{
int save_errno = errno;
/*
* Don't joggle the elbow of proc_exit
*/
if (!proc_exit_inprogress)
{
InterruptPending = true;
QueryCancelPending = true;
/*
* If it's safe to interrupt, and we're waiting for input or a lock,
* service the interrupt immediately
*/
if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
CritSectionCount == 0)
{
/* bump holdoff count to make ProcessInterrupts() a no-op */
/* until we are done getting ready for it */
InterruptHoldoffCount++;
LockErrorCleanup(); /* prevent CheckDeadLock from running */
DisableNotifyInterrupt();
DisableCatchupInterrupt();
InterruptHoldoffCount--;
ProcessInterrupts();
}
}
/* If we're still here, waken anything waiting on the process latch */
if (MyProc)
SetLatch(&MyProc->procLatch);
errno = save_errno;
}
| PGDLLIMPORT const char* debug_query_string |
Definition at line 92 of file postgres.c.
Referenced by current_query(), errstart(), exec_bind_message(), exec_execute_message(), exec_parse_message(), exec_simple_query(), PostgresMain(), proc_exit_prepare(), send_message_to_server_log(), and write_csvlog().
| int log_statement |
Definition at line 100 of file postgres.c.
Referenced by check_log_statement(), and HandleFunctionRequest().
| int max_stack_depth |
Definition at line 103 of file postgres.c.
Referenced by check_stack_depth().
| int PostAuthDelay |
Definition at line 106 of file postgres.c.
Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), do_start_bgworker(), and InitPostgres().
Definition at line 95 of file postgres.c.
Referenced by BackendInitialize(), BeginCopyFrom(), BeginCopyTo(), BeginReportingGUCOptions(), DoCopyTo(), errfinish(), errstart(), exec_bind_message(), exec_describe_portal_message(), exec_describe_statement_message(), exec_execute_message(), exec_parse_message(), exec_simple_query(), HandleFunctionRequest(), NotifyMyFrontEnd(), pg_re_throw(), PostgresMain(), PostmasterMain(), ProcessInterrupts(), quickdie(), ReadCommand(), send_message_to_server_log(), SocketBackend(), SyncRepWaitForLSN(), and WalSndLoop().
1.7.1