diff options
Diffstat (limited to 'src/include/pgstat.h')
-rw-r--r-- | src/include/pgstat.h | 136 |
1 files changed, 128 insertions, 8 deletions
diff --git a/src/include/pgstat.h b/src/include/pgstat.h index f9380983a5..bace5c6bd1 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -4,7 +4,7 @@ * Definitions for the PostgreSQL statistics collector daemon. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Copyright (c) 2001-2015, PostgreSQL Global Development Group + * Copyright (c) 2001-2016, PostgreSQL Global Development Group * * src/include/pgstat.h * ---------- @@ -18,6 +18,7 @@ #include "portability/instr_time.h" #include "postmaster/pgarch.h" #include "storage/barrier.h" +#include "storage/proc.h" #include "utils/hsearch.h" #include "utils/relcache.h" @@ -219,7 +220,20 @@ typedef struct PgStat_MsgDummy /* ---------- * PgStat_MsgInquiry Sent by a backend to ask the collector - * to write the stats file. + * to write the stats file(s). + * + * Ordinarily, an inquiry message prompts writing of the global stats file, + * the stats file for shared catalogs, and the stats file for the specified + * database. If databaseid is InvalidOid, only the first two are written. + * + * New file(s) will be written only if the existing file has a timestamp + * older than the specified cutoff_time; this prevents duplicated effort + * when multiple requests arrive at nearly the same time, assuming that + * backends send requests with cutoff_times a little bit in the past. + * + * clock_time should be the requestor's current local time; the collector + * uses this to check for the system clock going backward, but it has no + * effect unless that occurs. We assume clock_time >= cutoff_time, though. * ---------- */ @@ -228,7 +242,7 @@ typedef struct PgStat_MsgInquiry PgStat_MsgHdr m_hdr; TimestampTz clock_time; /* observed local clock time */ TimestampTz cutoff_time; /* minimum acceptable file timestamp */ - Oid databaseid; /* requested DB (InvalidOid => all DBs) */ + Oid databaseid; /* requested DB (InvalidOid => shared only) */ } PgStat_MsgInquiry; @@ -370,6 +384,7 @@ typedef struct PgStat_MsgAnalyze Oid m_databaseid; Oid m_tableoid; bool m_autovacuum; + bool m_resetcounter; TimestampTz m_analyzetime; PgStat_Counter m_live_tuples; PgStat_Counter m_dead_tuples; @@ -696,6 +711,33 @@ typedef enum BackendState STATE_DISABLED } BackendState; + +/* ---------- + * Wait Classes + * ---------- + */ +typedef enum WaitClass +{ + WAIT_UNDEFINED, + WAIT_LWLOCK_NAMED, + WAIT_LWLOCK_TRANCHE, + WAIT_LOCK, + WAIT_BUFFER_PIN +} WaitClass; + + +/* ---------- + * Command type for progress reporting purposes + * ---------- + */ +typedef enum ProgressCommandType +{ + PROGRESS_COMMAND_INVALID, + PROGRESS_COMMAND_VACUUM +} ProgressCommandType; + +#define PGSTAT_NUM_PROGRESS_PARAM 10 + /* ---------- * Shared-memory data structures * ---------- @@ -766,9 +808,6 @@ typedef struct PgBackendStatus bool st_ssl; PgBackendSSLStatus *st_sslstatus; - /* Is backend currently waiting on an lmgr lock? */ - bool st_waiting; - /* current state */ BackendState st_state; @@ -777,6 +816,19 @@ typedef struct PgBackendStatus /* current command string; MUST be null-terminated */ char *st_activity; + + /* + * Command progress reporting. Any command which wishes can advertise + * that it is running by setting st_progress_command, + * st_progress_command_target, and st_progress_command[]. + * st_progress_command_target should be the OID of the relation which the + * command targets (we assume there's just one, as this is meant for + * utility commands), but the meaning of each element in the + * st_progress_param array is command-specific. + */ + ProgressCommandType st_progress_command; + Oid st_progress_command_target; + int64 st_progress_param[PGSTAT_NUM_PROGRESS_PARAM]; } PgBackendStatus; /* @@ -920,7 +972,8 @@ extern void pgstat_report_autovac(Oid dboid); extern void pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter livetuples, PgStat_Counter deadtuples); extern void pgstat_report_analyze(Relation rel, - PgStat_Counter livetuples, PgStat_Counter deadtuples); + PgStat_Counter livetuples, PgStat_Counter deadtuples, + bool resetcounter); extern void pgstat_report_recovery_conflict(int reason); extern void pgstat_report_deadlock(void); @@ -932,16 +985,83 @@ extern void pgstat_report_activity(BackendState state, const char *cmd_str); extern void pgstat_report_tempfile(size_t filesize); extern void pgstat_report_appname(const char *appname); extern void pgstat_report_xact_timestamp(TimestampTz tstamp); -extern void pgstat_report_waiting(bool waiting); +extern const char *pgstat_get_wait_event(uint32 wait_event_info); +extern const char *pgstat_get_wait_event_type(uint32 wait_event_info); extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser); extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer, int buflen); +extern void pgstat_progress_start_command(ProgressCommandType cmdtype, + Oid relid); +extern void pgstat_progress_update_param(int index, int64 val); +extern void pgstat_progress_update_multi_param(int nparam, const int *index, + const int64 *val); +extern void pgstat_progress_end_command(void); + extern PgStat_TableStatus *find_tabstat_entry(Oid rel_id); extern PgStat_BackendFunctionEntry *find_funcstat_entry(Oid func_id); extern void pgstat_initstats(Relation rel); +/* ---------- + * pgstat_report_wait_start() - + * + * Called from places where server process needs to wait. This is called + * to report wait event information. The wait information is stored + * as 4-bytes where first byte repersents the wait event class (type of + * wait, for different types of wait, refer WaitClass) and the next + * 3-bytes repersent the actual wait event. Currently 2-bytes are used + * for wait event which is sufficient for current usage, 1-byte is + * reserved for future usage. + * + * NB: this *must* be able to survive being called before MyProc has been + * initialized. + * ---------- + */ +static inline void +pgstat_report_wait_start(uint8 classId, uint16 eventId) +{ + volatile PGPROC *proc = MyProc; + uint32 wait_event_val; + + if (!pgstat_track_activities || !proc) + return; + + wait_event_val = classId; + wait_event_val <<= 24; + wait_event_val |= eventId; + + /* + * Since this is a four-byte field which is always read and written as + * four-bytes, updates are atomic. + */ + proc->wait_event_info = wait_event_val; +} + +/* ---------- + * pgstat_report_wait_end() - + * + * Called to report end of a wait. + * + * NB: this *must* be able to survive being called before MyProc has been + * initialized. + * ---------- + */ +static inline void +pgstat_report_wait_end(void) +{ + volatile PGPROC *proc = MyProc; + + if (!pgstat_track_activities || !proc) + return; + + /* + * Since this is a four-byte field which is always read and written as + * four-bytes, updates are atomic. + */ + proc->wait_event_info = 0; +} + /* nontransactional event counts are simple enough to inline */ #define pgstat_count_heap_scan(rel) \ |