.shared_data_off = offsetof(PgStatShared_IO, stats),
.shared_data_len = sizeof(((PgStatShared_IO *) 0)->stats),
+ .flush_fixed_cb = pgstat_io_flush_cb,
+ .have_fixed_pending_cb = pgstat_io_have_pending_cb,
.init_shmem_cb = pgstat_io_init_shmem_cb,
.reset_all_cb = pgstat_io_reset_all_cb,
.snapshot_cb = pgstat_io_snapshot_cb,
.shared_data_off = offsetof(PgStatShared_SLRU, stats),
.shared_data_len = sizeof(((PgStatShared_SLRU *) 0)->stats),
+ .flush_fixed_cb = pgstat_slru_flush_cb,
+ .have_fixed_pending_cb = pgstat_slru_have_pending_cb,
.init_shmem_cb = pgstat_slru_init_shmem_cb,
.reset_all_cb = pgstat_slru_reset_all_cb,
.snapshot_cb = pgstat_slru_snapshot_cb,
.shared_data_len = sizeof(((PgStatShared_Wal *) 0)->stats),
.init_backend_cb = pgstat_wal_init_backend_cb,
+ .flush_fixed_cb = pgstat_wal_flush_cb,
+ .have_fixed_pending_cb = pgstat_wal_have_pending_cb,
.init_shmem_cb = pgstat_wal_init_shmem_cb,
.reset_all_cb = pgstat_wal_reset_all_cb,
.snapshot_cb = pgstat_wal_snapshot_cb,
}
/* Don't expend a clock check if nothing to do */
- if (dlist_is_empty(&pgStatPending) &&
- !have_iostats &&
- !have_slrustats &&
- !pgstat_have_pending_wal())
+ if (dlist_is_empty(&pgStatPending))
{
- Assert(pending_since == 0);
- return 0;
+ bool do_flush = false;
+
+ /* Check for pending fixed-numbered stats */
+ for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++)
+ {
+ const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind);
+
+ if (!kind_info)
+ continue;
+ if (!kind_info->fixed_amount)
+ {
+ Assert(kind_info->have_fixed_pending_cb == NULL);
+ continue;
+ }
+ if (!kind_info->have_fixed_pending_cb)
+ continue;
+
+ if (kind_info->have_fixed_pending_cb())
+ {
+ do_flush = true;
+ break;
+ }
+ }
+
+ if (!do_flush)
+ {
+ Assert(pending_since == 0);
+ return 0;
+ }
}
/*
/* flush database / relation / function / ... stats */
partial_flush |= pgstat_flush_pending_entries(nowait);
- /* flush IO stats */
- partial_flush |= pgstat_flush_io(nowait);
+ /* flush of fixed-numbered stats */
+ for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++)
+ {
+ const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind);
- /* flush wal stats */
- partial_flush |= pgstat_flush_wal(nowait);
+ if (!kind_info)
+ continue;
+ if (!kind_info->fixed_amount)
+ {
+ Assert(kind_info->flush_fixed_cb == NULL);
+ continue;
+ }
+ if (!kind_info->flush_fixed_cb)
+ continue;
- /* flush SLRU stats */
- partial_flush |= pgstat_slru_flush(nowait);
+ partial_flush |= kind_info->flush_fixed_cb(nowait);
+ }
last_flush = now;
static PgStat_PendingIO PendingIOStats;
-bool have_iostats = false;
+static bool have_iostats = false;
/*
return &pgStatLocal.snapshot.io;
}
+/*
+ * Check if there any IO stats waiting for flush.
+ */
+bool
+pgstat_io_have_pending_cb(void)
+{
+ return have_iostats;
+}
+
+/*
+ * Simpler wrapper of pgstat_io_flush_cb()
+ */
+void
+pgstat_flush_io(bool nowait)
+{
+ (void) pgstat_io_flush_cb(nowait);
+}
+
/*
* Flush out locally pending IO statistics
*
* acquired. Otherwise, return false.
*/
bool
-pgstat_flush_io(bool nowait)
+pgstat_io_flush_cb(bool nowait)
{
LWLock *bktype_lock;
PgStat_BktypeIO *bktype_shstats;
* in order to avoid memory allocation.
*/
static PgStat_SLRUStats pending_SLRUStats[SLRU_NUM_ELEMENTS];
-bool have_slrustats = false;
+static bool have_slrustats = false;
/*
return (SLRU_NUM_ELEMENTS - 1);
}
+/*
+ * Check if there are any SLRU stats entries waiting for flush.
+ */
+bool
+pgstat_slru_have_pending_cb(void)
+{
+ return have_slrustats;
+}
+
/*
* Flush out locally pending SLRU stats entries
*
* acquired. Otherwise return false.
*/
bool
-pgstat_slru_flush(bool nowait)
+pgstat_slru_flush_cb(bool nowait)
{
PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
int i;
return &pgStatLocal.snapshot.wal;
}
+/*
+ * Simple wrapper of pgstat_wal_flush_cb()
+ */
+void
+pgstat_flush_wal(bool nowait)
+{
+ (void) pgstat_wal_flush_cb(nowait);
+}
+
/*
* Calculate how much WAL usage counters have increased by subtracting the
* previous counters from the current ones.
* acquired. Otherwise return false.
*/
bool
-pgstat_flush_wal(bool nowait)
+pgstat_wal_flush_cb(bool nowait)
{
PgStatShared_Wal *stats_shmem = &pgStatLocal.shmem->wal;
WalUsage wal_usage_diff = {0};
* This function can be called even if nothing at all has happened. Avoid
* taking lock for nothing in that case.
*/
- if (!pgstat_have_pending_wal())
+ if (!pgstat_wal_have_pending_cb())
return false;
/*
pgstat_wal_init_backend_cb(void)
{
/*
- * Initialize prevWalUsage with pgWalUsage so that pgstat_flush_wal() can
- * calculate how much pgWalUsage counters are increased by subtracting
+ * Initialize prevWalUsage with pgWalUsage so that pgstat_wal_flush_cb()
+ * can calculate how much pgWalUsage counters are increased by subtracting
* prevWalUsage from pgWalUsage.
*/
prevWalUsage = pgWalUsage;
* data pages.
*/
bool
-pgstat_have_pending_wal(void)
+pgstat_wal_have_pending_cb(void)
{
return pgWalUsage.wal_records != prevWalUsage.wal_records ||
PendingWalStats.wal_write != 0 ||
/*
* For variable-numbered stats: flush pending stats. Required if pending
- * data is used.
+ * data is used. See flush_fixed_cb for fixed-numbered stats.
*/
bool (*flush_pending_cb) (PgStat_EntryRef *sr, bool nowait);
*/
void (*init_shmem_cb) (void *stats);
+ /*
+ * For fixed-numbered statistics: Flush pending stats. Returns true if
+ * some of the stats could not be flushed, due to lock contention for
+ * example. Optional.
+ */
+ bool (*flush_fixed_cb) (bool nowait);
+
+ /*
+ * For fixed-numbered statistics: Check for pending stats in need of
+ * flush. Returns true if there are any stats pending for flush. Optional.
+ */
+ bool (*have_fixed_pending_cb) (void);
+
/*
* For fixed-numbered statistics: Reset All.
*/
* Functions in pgstat_io.c
*/
-extern bool pgstat_flush_io(bool nowait);
+extern void pgstat_flush_io(bool nowait);
+
+extern bool pgstat_io_have_pending_cb(void);
+extern bool pgstat_io_flush_cb(bool nowait);
extern void pgstat_io_init_shmem_cb(void *stats);
extern void pgstat_io_reset_all_cb(TimestampTz ts);
extern void pgstat_io_snapshot_cb(void);
* Functions in pgstat_slru.c
*/
-extern bool pgstat_slru_flush(bool nowait);
+extern bool pgstat_slru_have_pending_cb(void);
+extern bool pgstat_slru_flush_cb(bool nowait);
extern void pgstat_slru_init_shmem_cb(void *stats);
extern void pgstat_slru_reset_all_cb(TimestampTz ts);
extern void pgstat_slru_snapshot_cb(void);
* Functions in pgstat_wal.c
*/
-extern bool pgstat_flush_wal(bool nowait);
-extern bool pgstat_have_pending_wal(void);
+extern void pgstat_flush_wal(bool nowait);
extern void pgstat_wal_init_backend_cb(void);
+extern bool pgstat_wal_have_pending_cb(void);
+extern bool pgstat_wal_flush_cb(bool nowait);
extern void pgstat_wal_init_shmem_cb(void *stats);
extern void pgstat_wal_reset_all_cb(TimestampTz ts);
extern void pgstat_wal_snapshot_cb(void);
extern PGDLLIMPORT PgStat_LocalState pgStatLocal;
-/*
- * Variables in pgstat_io.c
- */
-
-extern PGDLLIMPORT bool have_iostats;
-
-
-/*
- * Variables in pgstat_slru.c
- */
-
-extern PGDLLIMPORT bool have_slrustats;
-
-
/*
* Implementation of inline functions declared above.
*/