#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().