diff options
Diffstat (limited to 'src/backend/utils/activity/pgstat_backend.c')
-rw-r--r-- | src/backend/utils/activity/pgstat_backend.c | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c index 6efbb650aa8..da4c7edd772 100644 --- a/src/backend/utils/activity/pgstat_backend.c +++ b/src/backend/utils/activity/pgstat_backend.c @@ -39,6 +39,14 @@ static PgStat_BackendPending PendingBackendStats = {0}; /* + * WAL usage counters saved from pgWalUsage at the previous call to + * pgstat_report_wal(). This is used to calculate how much WAL usage + * happens between pgstat_report_wal() calls, by subtracting the previous + * counters from the current ones. + */ +static WalUsage prevBackendWalUsage; + +/* * Utility routines to report I/O stats for backends, kept here to avoid * exposing PendingBackendStats to the outside world. */ @@ -185,6 +193,57 @@ pgstat_flush_backend_entry_io(PgStat_EntryRef *entry_ref) } /* + * To determine whether WAL usage happened. + */ +static inline bool +pgstat_backend_wal_have_pending(void) +{ + return (pgWalUsage.wal_records != prevBackendWalUsage.wal_records); +} + +/* + * Flush out locally pending backend WAL statistics. Locking is managed + * by the caller. + */ +static void +pgstat_flush_backend_entry_wal(PgStat_EntryRef *entry_ref) +{ + PgStatShared_Backend *shbackendent; + PgStat_WalCounters *bktype_shstats; + WalUsage wal_usage_diff = {0}; + + /* + * This function can be called even if nothing at all has happened for WAL + * statistics. In this case, avoid unnecessarily modifying the stats + * entry. + */ + if (!pgstat_backend_wal_have_pending()) + return; + + shbackendent = (PgStatShared_Backend *) entry_ref->shared_stats; + bktype_shstats = &shbackendent->stats.wal_counters; + + /* + * Calculate how much WAL usage counters were increased by subtracting the + * previous counters from the current ones. + */ + WalUsageAccumDiff(&wal_usage_diff, &pgWalUsage, &prevBackendWalUsage); + +#define WALSTAT_ACC(fld, var_to_add) \ + (bktype_shstats->fld += var_to_add.fld) + WALSTAT_ACC(wal_buffers_full, wal_usage_diff); + WALSTAT_ACC(wal_records, wal_usage_diff); + WALSTAT_ACC(wal_fpi, wal_usage_diff); + WALSTAT_ACC(wal_bytes, wal_usage_diff); +#undef WALSTAT_ACC + + /* + * Save the current counters for the subsequent calculation of WAL usage. + */ + prevBackendWalUsage = pgWalUsage; +} + +/* * Flush out locally pending backend statistics * * "flags" parameter controls which statistics to flush. Returns true @@ -194,12 +253,23 @@ bool pgstat_flush_backend(bool nowait, bits32 flags) { PgStat_EntryRef *entry_ref; + bool has_pending_data = false; if (!pgstat_tracks_backend_bktype(MyBackendType)) return false; - if (pg_memory_is_all_zeros(&PendingBackendStats, - sizeof(struct PgStat_BackendPending))) + /* Some IO data pending? */ + if ((flags & PGSTAT_BACKEND_FLUSH_IO) && + !pg_memory_is_all_zeros(&PendingBackendStats.pending_io, + sizeof(struct PgStat_PendingIO))) + has_pending_data = true; + + /* Some WAL data pending? */ + if ((flags & PGSTAT_BACKEND_FLUSH_WAL) && + pgstat_backend_wal_have_pending()) + has_pending_data = true; + + if (!has_pending_data) return false; entry_ref = pgstat_get_entry_ref_locked(PGSTAT_KIND_BACKEND, InvalidOid, @@ -211,6 +281,9 @@ pgstat_flush_backend(bool nowait, bits32 flags) if (flags & PGSTAT_BACKEND_FLUSH_IO) pgstat_flush_backend_entry_io(entry_ref); + if (flags & PGSTAT_BACKEND_FLUSH_WAL) + pgstat_flush_backend_entry_wal(entry_ref); + pgstat_unlock_entry(entry_ref); return false; @@ -226,7 +299,8 @@ pgstat_backend_have_pending_cb(void) return false; return (!pg_memory_is_all_zeros(&PendingBackendStats, - sizeof(struct PgStat_BackendPending))); + sizeof(struct PgStat_BackendPending)) || + pgstat_backend_wal_have_pending()); } /* @@ -261,6 +335,13 @@ pgstat_create_backend(ProcNumber procnum) pgstat_unlock_entry(entry_ref); MemSet(&PendingBackendStats, 0, sizeof(PgStat_BackendPending)); + + /* + * Initialize prevBackendWalUsage with pgWalUsage so that + * pgstat_backend_flush_cb() can calculate how much pgWalUsage counters + * are increased by subtracting prevBackendWalUsage from pgWalUsage. + */ + prevBackendWalUsage = pgWalUsage; } /* |