diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index b1c0a1b..8b5b70e 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -929,6 +929,24 @@ postgres: user database host pg_stat_bgwriter. + + + pg_stat_reset_single_table(oid) + void + + Reset statistics for a single table or index in the current database to + zero (requires superuser privileges) + + + + + pg_stat_reset_single_function(oid) + void + + Reset statistics for a single function in the current database to + zero (requires superuser privileges) + + diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 36d0872..474e785 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -271,6 +271,7 @@ static void pgstat_recv_tabpurge(PgStat_MsgTabpurge *msg, int len); static void pgstat_recv_dropdb(PgStat_MsgDropdb *msg, int len); static void pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len); static void pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len); +static void pgstat_recv_resetsinglecounter(PgStat_MsgResetsinglecounter *msg, int len); static void pgstat_recv_autovac(PgStat_MsgAutovacStart *msg, int len); static void pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len); static void pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len); @@ -1188,6 +1189,32 @@ pgstat_reset_shared_counters(const char *target) } /* ---------- + * pgstat_reset_single_counter() - + * + * Tell the statistics collector to reset a single counter. + * ---------- + */ +void pgstat_reset_single_counter(Oid objoid, PgStat_Single_Reset_Type type) +{ + PgStat_MsgResetsinglecounter msg; + + if (pgStatSock < 0) + return; + + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to reset statistics counters"))); + + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSINGLECOUNTER); + msg.m_databaseid = MyDatabaseId; + msg.m_resettype = type; + msg.m_objectid = objoid; + + pgstat_send(&msg, sizeof(msg)); +} + +/* ---------- * pgstat_report_autovac() - * * Called from autovacuum.c to report startup of an autovacuum process. @@ -2954,6 +2981,12 @@ PgstatCollectorMain(int argc, char *argv[]) len); break; + case PGSTAT_MTYPE_RESETSINGLECOUNTER: + pgstat_recv_resetsinglecounter( + (PgStat_MsgResetsinglecounter *) &msg, + len); + break; + case PGSTAT_MTYPE_AUTOVAC_START: pgstat_recv_autovac((PgStat_MsgAutovacStart *) &msg, len); break; @@ -3929,6 +3962,30 @@ pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len) } /* ---------- + * pgstat_recv_resetsinglecounter() - + * + * Reset a statistics for a single object + * ---------- + */ +static void +pgstat_recv_resetsinglecounter(PgStat_MsgResetsinglecounter *msg, int len) +{ + PgStat_StatDBEntry *dbentry; + + dbentry = pgstat_get_db_entry(msg->m_databaseid, false); + + if (!dbentry) + return; + + + /* Remove object if it exists, ignore it if not */ + if (msg->m_resettype == RESET_TABLE) + (void) hash_search(dbentry->tables, (void *) &(msg->m_objectid), HASH_REMOVE, NULL); + else if (msg->m_resettype == RESET_FUNCTION) + (void) hash_search(dbentry->functions, (void *)&(msg->m_objectid), HASH_REMOVE, NULL); +} + +/* ---------- * pgstat_recv_autovac() - * * Process an autovacuum signalling message. diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index f6cf566..f6cb55d 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -79,6 +79,8 @@ extern Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS); extern Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS); extern Datum pg_stat_reset(PG_FUNCTION_ARGS); extern Datum pg_stat_reset_shared(PG_FUNCTION_ARGS); +extern Datum pg_stat_reset_single_table(PG_FUNCTION_ARGS); +extern Datum pg_stat_reset_single_function(PG_FUNCTION_ARGS); /* Global bgwriter statistics, from bgwriter.c */ extern PgStat_MsgBgWriter bgwriterStats; @@ -1120,3 +1122,20 @@ pg_stat_reset_shared(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } + +/* Reset a a single counter in the current database */ +Datum +pg_stat_reset_single_table(PG_FUNCTION_ARGS) +{ + pgstat_reset_single_counter(PG_GETARG_OID(0), RESET_TABLE); + + PG_RETURN_VOID(); +} + +Datum +pg_stat_reset_single_function(PG_FUNCTION_ARGS) +{ + pgstat_reset_single_counter(PG_GETARG_OID(0), RESET_FUNCTION); + + PG_RETURN_VOID(); +} diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index c4320e5..cc71aa6 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -3075,6 +3075,10 @@ DATA(insert OID = 2274 ( pg_stat_reset PGNSP PGUID 12 1 0 0 f f f f f v 0 0 DESCR("statistics: reset collected statistics for current database"); DATA(insert OID = 3775 ( pg_stat_reset_shared PGNSP PGUID 12 1 0 0 f f f f f v 1 0 2278 "25" _null_ _null_ _null_ _null_ pg_stat_reset_shared _null_ _null_ _null_ )); DESCR("statistics: reset collected statistics shared across the cluster"); +DATA(insert OID = 3776 ( pg_stat_reset_single_table PGNSP PGUID 12 1 0 0 f f f f f v 1 0 2278 "26" _null_ _null_ _null_ _null_ pg_stat_reset_single_table _null_ _null_ _null_ )); +DESCR("statistics: reset collected statistics for a single table or index in the current database"); +DATA(insert OID = 3777 ( pg_stat_reset_single_function PGNSP PGUID 12 1 0 0 f f f f f v 1 0 2278 "26" _null_ _null_ _null_ _null_ pg_stat_reset_single_function _null_ _null_ _null_ )); +DESCR("statistics: reset collected statistics for a single function in the current database"); DATA(insert OID = 1946 ( encode PGNSP PGUID 12 1 0 0 f f f t f i 2 0 25 "17 25" _null_ _null_ _null_ _null_ binary_encode _null_ _null_ _null_ )); DESCR("convert bytea value into some ascii-only text string"); diff --git a/src/include/pgstat.h b/src/include/pgstat.h index c3de665..90915a2 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -39,6 +39,7 @@ typedef enum StatMsgType PGSTAT_MTYPE_DROPDB, PGSTAT_MTYPE_RESETCOUNTER, PGSTAT_MTYPE_RESETSHAREDCOUNTER, + PGSTAT_MTYPE_RESETSINGLECOUNTER, PGSTAT_MTYPE_AUTOVAC_START, PGSTAT_MTYPE_VACUUM, PGSTAT_MTYPE_ANALYZE, @@ -100,6 +101,12 @@ typedef enum PgStat_Shared_Reset_Target RESET_BGWRITER } PgStat_Shared_Reset_Target; +/* Possible object types for resetting single counters */ +typedef enum PgStat_Single_Reset_Type +{ + RESET_TABLE, + RESET_FUNCTION +} PgStat_Single_Reset_Type; /* ------------------------------------------------------------ * Structures kept in backend local memory while accumulating counts @@ -279,6 +286,19 @@ typedef struct PgStat_MsgResetsharedcounter } PgStat_MsgResetsharedcounter; /* ---------- + * PgStat_MsgResetsinglecounter Sent by the backend to tell the collector + * to reset a single counter + * ---------- + */ +typedef struct PgStat_MsgResetsinglecounter +{ + PgStat_MsgHdr m_hdr; + Oid m_databaseid; + PgStat_Single_Reset_Type m_resettype; + Oid m_objectid; +} PgStat_MsgResetsinglecounter; + +/* ---------- * PgStat_MsgAutovacStart Sent by the autovacuum daemon to signal * that a database is going to be processed * ---------- @@ -432,6 +452,7 @@ typedef union PgStat_Msg PgStat_MsgDropdb msg_dropdb; PgStat_MsgResetcounter msg_resetcounter; PgStat_MsgResetsharedcounter msg_resetsharedcounter; + PgStat_MsgResetsinglecounter msg_resetsinglecounter; PgStat_MsgAutovacStart msg_autovacuum; PgStat_MsgVacuum msg_vacuum; PgStat_MsgAnalyze msg_analyze; @@ -654,6 +675,7 @@ extern void pgstat_drop_database(Oid databaseid); extern void pgstat_clear_snapshot(void); extern void pgstat_reset_counters(void); extern void pgstat_reset_shared_counters(const char *); +extern void pgstat_reset_single_counter(Oid objectid, PgStat_Single_Reset_Type type); extern void pgstat_report_autovac(Oid dboid); extern void pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts,