static bool pgstat_db_requested(Oid databaseid);
static PgStat_StatReplSlotEntry *pgstat_get_replslot_entry(NameData name, bool create_it);
-static void pgstat_reset_replslot(PgStat_StatReplSlotEntry *slotstats, TimestampTz ts);
+static void pgstat_reset_replslot_entry(PgStat_StatReplSlotEntry *slotstats, TimestampTz ts);
static HTAB *pgstat_collect_oids(Oid catalogid, AttrNumber anum_oid);
}
/*
- * Reset a single counter.
+ * Reset a single variable-numbered entry.
+ *
+ * If the stats kind is within a database, also reset the database's
+ * stat_reset_timestamp.
*
* Permission checking for this function is managed through the normal
* GRANT system.
*/
void
-pgstat_reset_single_counter(Oid objoid, PgStat_Single_Reset_Type type)
+pgstat_reset(PgStat_Kind kind, Oid dboid, Oid objoid)
{
- PgStat_MsgResetsinglecounter msg;
if (pgStatSock == PGINVALID_SOCKET)
return;
- pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSINGLECOUNTER);
- msg.m_databaseid = MyDatabaseId;
- msg.m_resettype = type;
- msg.m_objectid = objoid;
+ switch (kind)
+ {
+ case PGSTAT_KIND_FUNCTION:
+ case PGSTAT_KIND_RELATION:
+ {
+ PgStat_MsgResetsinglecounter msg;
- pgstat_send(&msg, sizeof(msg));
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSINGLECOUNTER);
+ msg.m_databaseid = dboid;
+ msg.m_resettype = kind;
+ msg.m_objectid = objoid;
+ pgstat_send(&msg, sizeof(msg));
+ }
+ break;
+
+ case PGSTAT_KIND_SUBSCRIPTION:
+ {
+ PgStat_MsgResetsubcounter msg;
+
+ Assert(dboid == InvalidOid);
+ msg.m_subid = objoid;
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSUBCOUNTER);
+ }
+ break;
+
+ default:
+ elog(ERROR, "unexpected");
+ }
}
/*
- * Reset cluster-wide shared counters.
+ * Reset stats for all entries of a kind.
*
* Permission checking for this function is managed through the normal
* GRANT system.
*/
void
-pgstat_reset_shared_counters(const char *target)
+pgstat_reset_of_kind(PgStat_Kind kind)
{
- PgStat_MsgResetsharedcounter msg;
-
if (pgStatSock == PGINVALID_SOCKET)
return;
- if (strcmp(target, "archiver") == 0)
- msg.m_resettarget = RESET_ARCHIVER;
- else if (strcmp(target, "bgwriter") == 0)
- msg.m_resettarget = RESET_BGWRITER;
- else if (strcmp(target, "wal") == 0)
- msg.m_resettarget = RESET_WAL;
- else
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("unrecognized reset target: \"%s\"", target),
- errhint("Target must be \"archiver\", \"bgwriter\", or \"wal\".")));
+ switch (kind)
+ {
+ case PGSTAT_KIND_ARCHIVER:
+ case PGSTAT_KIND_BGWRITER:
+ case PGSTAT_KIND_CHECKPOINTER:
+ case PGSTAT_KIND_WAL:
+ {
+ PgStat_MsgResetsharedcounter msg;
- pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSHAREDCOUNTER);
- pgstat_send(&msg, sizeof(msg));
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSHAREDCOUNTER);
+ msg.m_resettarget = kind;
+ pgstat_send(&msg, sizeof(msg));
+ }
+ break;
+ case PGSTAT_KIND_SLRU:
+ {
+ PgStat_MsgResetslrucounter msg;
+
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSLRUCOUNTER);
+ msg.m_index = -1;
+ pgstat_send(&msg, sizeof(msg));
+ }
+ break;
+ case PGSTAT_KIND_REPLSLOT:
+ {
+ PgStat_MsgResetreplslotcounter msg;
+
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETREPLSLOTCOUNTER);
+ msg.clearall = true;
+ pgstat_send(&msg, sizeof(msg));
+ }
+ break;
+
+ case PGSTAT_KIND_SUBSCRIPTION:
+ {
+ PgStat_MsgResetsubcounter msg;
+
+ msg.m_subid = InvalidOid;
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSUBCOUNTER);
+
+ pgstat_send(&msg, sizeof(msg));
+ }
+ break;
+
+ default:
+ elog(ERROR, "unexpected");
+ }
}
/*
if (create && !found)
{
namestrcpy(&(slotent->slotname), NameStr(name));
- pgstat_reset_replslot(slotent, 0);
+ pgstat_reset_replslot_entry(slotent, 0);
}
return slotent;
* Reset the given replication slot stats.
*/
static void
-pgstat_reset_replslot(PgStat_StatReplSlotEntry *slotent, TimestampTz ts)
+pgstat_reset_replslot_entry(PgStat_StatReplSlotEntry *slotent, TimestampTz ts)
{
/* reset only counters. Don't clear slot name */
slotent->spill_txns = 0;
static void
pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len)
{
- if (msg->m_resettarget == RESET_BGWRITER)
+ if (msg->m_resettarget == PGSTAT_KIND_BGWRITER ||
+ msg->m_resettarget == PGSTAT_KIND_CHECKPOINTER)
{
/*
* Reset the global, bgwriter and checkpointer statistics for the
memset(&globalStats, 0, sizeof(globalStats));
globalStats.bgwriter.stat_reset_timestamp = GetCurrentTimestamp();
}
- else if (msg->m_resettarget == RESET_ARCHIVER)
+ else if (msg->m_resettarget == PGSTAT_KIND_ARCHIVER)
{
/* Reset the archiver statistics for the cluster. */
memset(&archiverStats, 0, sizeof(archiverStats));
archiverStats.stat_reset_timestamp = GetCurrentTimestamp();
}
- else if (msg->m_resettarget == RESET_WAL)
+ else if (msg->m_resettarget == PGSTAT_KIND_WAL)
{
/* Reset the WAL statistics for the cluster. */
memset(&walStats, 0, sizeof(walStats));
dbentry->stat_reset_timestamp = GetCurrentTimestamp();
/* Remove object if it exists, ignore it if not */
- if (msg->m_resettype == RESET_TABLE)
+ if (msg->m_resettype == PGSTAT_KIND_RELATION)
(void) hash_search(dbentry->tables, (void *) &(msg->m_objectid),
HASH_REMOVE, NULL);
- else if (msg->m_resettype == RESET_FUNCTION)
+ else if (msg->m_resettype == PGSTAT_KIND_FUNCTION)
(void) hash_search(dbentry->functions, (void *) &(msg->m_objectid),
HASH_REMOVE, NULL);
}
hash_seq_init(&sstat, replSlotStatHash);
while ((slotent = (PgStat_StatReplSlotEntry *) hash_seq_search(&sstat)) != NULL)
- pgstat_reset_replslot(slotent, ts);
+ pgstat_reset_replslot_entry(slotent, ts);
}
else
{
return;
/* Reset the stats for the requested replication slot */
- pgstat_reset_replslot(slotent, ts);
+ pgstat_reset_replslot_entry(slotent, ts);
}
}
* lost, slotent has stats for the old slot. So we initialize all
* counters at slot creation.
*/
- pgstat_reset_replslot(slotent, 0);
+ pgstat_reset_replslot_entry(slotent, 0);
}
else
{
/*
- * Reset counters for a single replication slot, or all replication slots
- * (when name is null).
+ * Reset counters for a single replication slot.
*
* Permission checking for this function is managed through the normal
* GRANT system.
*/
void
-pgstat_reset_replslot_counter(const char *name)
+pgstat_reset_replslot(const char *name)
{
+ ReplicationSlot *slot;
PgStat_MsgResetreplslotcounter msg;
+ AssertArg(name != NULL);
+
if (pgStatSock == PGINVALID_SOCKET)
return;
- if (name)
- {
- namestrcpy(&msg.m_slotname, name);
- msg.clearall = false;
- }
- else
- msg.clearall = true;
+ /*
+ * Check if the slot exists with the given name. It is possible that by
+ * the time this message is executed the slot is dropped but at least this
+ * check will ensure that the given name is for a valid slot.
+ */
+ slot = SearchNamedReplicationSlot(name, true);
- pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETREPLSLOTCOUNTER);
+ if (!slot)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("replication slot \"%s\" does not exist",
+ name)));
+ /*
+ * Nothing to do for physical slots as we collect stats only for logical
+ * slots.
+ */
+ if (SlotIsPhysical(slot))
+ return;
+
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETREPLSLOTCOUNTER);
+ namestrcpy(&msg.m_slotname, name);
+ msg.clearall = false;
pgstat_send(&msg, sizeof(msg));
}
/*
- * Reset counters for a single SLRU, or all SLRUs (when name is null).
+ * Reset counters for a single SLRU.
*
* Permission checking for this function is managed through the normal
* GRANT system.
*/
void
-pgstat_reset_slru_counter(const char *name)
+pgstat_reset_slru(const char *name)
{
PgStat_MsgResetslrucounter msg;
+ AssertArg(name != NULL);
+
if (pgStatSock == PGINVALID_SOCKET)
return;
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSLRUCOUNTER);
- msg.m_index = (name) ? pgstat_slru_index(name) : -1;
+ msg.m_index = pgstat_slru_index(name);
pgstat_send(&msg, sizeof(msg));
}
#include "utils/pgstat_internal.h"
-/*
- * Reset counters for a single subscription, or all subscriptions (when subid
- * is InvalidOid).
- *
- * Permission checking for this function is managed through the normal
- * GRANT system.
- */
-void
-pgstat_reset_subscription_counter(Oid subid)
-{
- PgStat_MsgResetsubcounter msg;
-
- if (pgStatSock == PGINVALID_SOCKET)
- return;
-
- msg.m_subid = subid;
- pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSUBCOUNTER);
-
- pgstat_send(&msg, sizeof(msg));
-}
-
/*
* Report a subscription error.
*/
#include "pgstat.h"
#include "postmaster/bgworker_internals.h"
#include "postmaster/postmaster.h"
-#include "replication/slot.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "utils/acl.h"
{
char *target = text_to_cstring(PG_GETARG_TEXT_PP(0));
- pgstat_reset_shared_counters(target);
+ if (strcmp(target, "archiver") == 0)
+ pgstat_reset_of_kind(PGSTAT_KIND_ARCHIVER);
+ else if (strcmp(target, "bgwriter") == 0)
+ {
+ /*
+ * Historically checkpointer was part of bgwriter, continue to reset
+ * both for now.
+ */
+ pgstat_reset_of_kind(PGSTAT_KIND_BGWRITER);
+ pgstat_reset_of_kind(PGSTAT_KIND_CHECKPOINTER);
+ }
+ else if (strcmp(target, "wal") == 0)
+ pgstat_reset_of_kind(PGSTAT_KIND_WAL);
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized reset target: \"%s\"", target),
+ errhint("Target must be \"archiver\", \"bgwriter\", or \"wal\".")));
PG_RETURN_VOID();
}
{
Oid taboid = PG_GETARG_OID(0);
- pgstat_reset_single_counter(taboid, RESET_TABLE);
+ pgstat_reset(PGSTAT_KIND_RELATION, MyDatabaseId, taboid);
PG_RETURN_VOID();
}
{
Oid funcoid = PG_GETARG_OID(0);
- pgstat_reset_single_counter(funcoid, RESET_FUNCTION);
+ pgstat_reset(PGSTAT_KIND_FUNCTION, MyDatabaseId, funcoid);
PG_RETURN_VOID();
}
{
char *target = NULL;
- if (!PG_ARGISNULL(0))
+ if (PG_ARGISNULL(0))
+ pgstat_reset_of_kind(PGSTAT_KIND_SLRU);
+ else
+ {
target = text_to_cstring(PG_GETARG_TEXT_PP(0));
-
- pgstat_reset_slru_counter(target);
+ pgstat_reset_slru(target);
+ }
PG_RETURN_VOID();
}
{
char *target = NULL;
- if (!PG_ARGISNULL(0))
+ if (PG_ARGISNULL(0))
+ pgstat_reset_of_kind(PGSTAT_KIND_REPLSLOT);
+ else
{
- ReplicationSlot *slot;
-
target = text_to_cstring(PG_GETARG_TEXT_PP(0));
-
- /*
- * Check if the slot exists with the given name. It is possible that
- * by the time this message is executed the slot is dropped but at
- * least this check will ensure that the given name is for a valid
- * slot.
- */
- slot = SearchNamedReplicationSlot(target, true);
-
- if (!slot)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("replication slot \"%s\" does not exist",
- target)));
-
- /*
- * Nothing to do for physical slots as we collect stats only for
- * logical slots.
- */
- if (SlotIsPhysical(slot))
- PG_RETURN_VOID();
+ pgstat_reset_replslot(target);
}
- pgstat_reset_replslot_counter(target);
-
PG_RETURN_VOID();
}
if (PG_ARGISNULL(0))
{
/* Clear all subscription stats */
- subid = InvalidOid;
+ pgstat_reset_of_kind(PGSTAT_KIND_SUBSCRIPTION);
}
else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid subscription OID %u", subid)));
+ pgstat_reset(PGSTAT_KIND_SUBSCRIPTION, InvalidOid, subid);
}
- pgstat_reset_subscription_counter(subid);
-
PG_RETURN_VOID();
}
*/
typedef int64 PgStat_Counter;
-/* Possible targets for resetting cluster-wide shared values */
-typedef enum PgStat_Shared_Reset_Target
-{
- RESET_ARCHIVER,
- RESET_BGWRITER,
- RESET_WAL
-} 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
typedef struct PgStat_MsgResetsharedcounter
{
PgStat_MsgHdr m_hdr;
- PgStat_Shared_Reset_Target m_resettarget;
+ PgStat_Kind m_resettarget;
} PgStat_MsgResetsharedcounter;
/* ----------
{
PgStat_MsgHdr m_hdr;
Oid m_databaseid;
- PgStat_Single_Reset_Type m_resettype;
+ PgStat_Kind m_resettype;
Oid m_objectid;
} PgStat_MsgResetsinglecounter;
extern void pgstat_ping(void);
extern void pgstat_reset_counters(void);
-extern void pgstat_reset_single_counter(Oid objectid, PgStat_Single_Reset_Type type);
-extern void pgstat_reset_shared_counters(const char *);
+extern void pgstat_reset(PgStat_Kind kind, Oid dboid, Oid objectid);
+extern void pgstat_reset_of_kind(PgStat_Kind kind);
/* stats accessors */
extern void pgstat_clear_snapshot(void);
* Functions in pgstat_replslot.c
*/
-extern void pgstat_reset_replslot_counter(const char *name);
+extern void pgstat_reset_replslot(const char *name);
extern void pgstat_report_replslot(const PgStat_StatReplSlotEntry *repSlotStat);
extern void pgstat_report_replslot_create(const char *slotname);
extern void pgstat_report_replslot_drop(const char *slotname);
* Functions in pgstat_slru.c
*/
-extern void pgstat_reset_slru_counter(const char *);
+extern void pgstat_reset_slru(const char *);
extern void pgstat_count_slru_page_zeroed(int slru_idx);
extern void pgstat_count_slru_page_hit(int slru_idx);
extern void pgstat_count_slru_page_read(int slru_idx);
* Functions in pgstat_subscription.c
*/
-extern void pgstat_reset_subscription_counter(Oid subid);
extern void pgstat_report_subscription_error(Oid subid, bool is_apply_error);
extern void pgstat_report_subscription_drop(Oid subid);
PgStat_MsgVacuum
PgStat_MsgWal
PgStat_SLRUStats
-PgStat_Shared_Reset_Target
-PgStat_Single_Reset_Type
PgStat_StatDBEntry
PgStat_StatFuncEntry
PgStat_StatReplSlotEntry