3838 */
3939static PgStat_BackendPending PendingBackendStats = {0 };
4040
41+ /*
42+ * WAL usage counters saved from pgWalUsage at the previous call to
43+ * pgstat_report_wal(). This is used to calculate how much WAL usage
44+ * happens between pgstat_report_wal() calls, by subtracting the previous
45+ * counters from the current ones.
46+ */
47+ static WalUsage prevBackendWalUsage ;
48+
4149/*
4250 * Utility routines to report I/O stats for backends, kept here to avoid
4351 * exposing PendingBackendStats to the outside world.
@@ -184,6 +192,57 @@ pgstat_flush_backend_entry_io(PgStat_EntryRef *entry_ref)
184192 MemSet (& PendingBackendStats .pending_io , 0 , sizeof (PgStat_PendingIO ));
185193}
186194
195+ /*
196+ * To determine whether WAL usage happened.
197+ */
198+ static inline bool
199+ pgstat_backend_wal_have_pending (void )
200+ {
201+ return pgWalUsage .wal_records != prevBackendWalUsage .wal_records ;
202+ }
203+
204+ /*
205+ * Flush out locally pending backend WAL statistics. Locking is managed
206+ * by the caller.
207+ */
208+ static void
209+ pgstat_flush_backend_entry_wal (PgStat_EntryRef * entry_ref )
210+ {
211+ PgStatShared_Backend * shbackendent ;
212+ PgStat_WalCounters * bktype_shstats ;
213+ WalUsage wal_usage_diff = {0 };
214+
215+ /*
216+ * This function can be called even if nothing at all has happened for WAL
217+ * statistics. In this case, avoid unnecessarily modifying the stats
218+ * entry.
219+ */
220+ if (!pgstat_backend_wal_have_pending ())
221+ return ;
222+
223+ shbackendent = (PgStatShared_Backend * ) entry_ref -> shared_stats ;
224+ bktype_shstats = & shbackendent -> stats .wal_counters ;
225+
226+ /*
227+ * Calculate how much WAL usage counters were increased by subtracting the
228+ * previous counters from the current ones.
229+ */
230+ WalUsageAccumDiff (& wal_usage_diff , & pgWalUsage , & prevBackendWalUsage );
231+
232+ #define WALSTAT_ACC (fld , var_to_add ) \
233+ (bktype_shstats->fld += var_to_add.fld)
234+ WALSTAT_ACC (wal_buffers_full , wal_usage_diff );
235+ WALSTAT_ACC (wal_records , wal_usage_diff );
236+ WALSTAT_ACC (wal_fpi , wal_usage_diff );
237+ WALSTAT_ACC (wal_bytes , wal_usage_diff );
238+ #undef WALSTAT_ACC
239+
240+ /*
241+ * Save the current counters for the subsequent calculation of WAL usage.
242+ */
243+ prevBackendWalUsage = pgWalUsage ;
244+ }
245+
187246/*
188247 * Flush out locally pending backend statistics
189248 *
@@ -194,12 +253,22 @@ bool
194253pgstat_flush_backend (bool nowait , bits32 flags )
195254{
196255 PgStat_EntryRef * entry_ref ;
256+ bool has_pending_data = false;
197257
198258 if (!pgstat_tracks_backend_bktype (MyBackendType ))
199259 return false;
200260
201- if (pg_memory_is_all_zeros (& PendingBackendStats ,
202- sizeof (struct PgStat_BackendPending )))
261+ /* Some IO data pending? */
262+ if ((flags & PGSTAT_BACKEND_FLUSH_IO ) &&
263+ !pg_memory_is_all_zeros (& PendingBackendStats .pending_io ,
264+ sizeof (struct PgStat_PendingIO )))
265+ has_pending_data = true;
266+ /* Some WAL data pending? */
267+ else if ((flags & PGSTAT_BACKEND_FLUSH_WAL ) &&
268+ pgstat_backend_wal_have_pending ())
269+ has_pending_data = true;
270+
271+ if (!has_pending_data )
203272 return false;
204273
205274 entry_ref = pgstat_get_entry_ref_locked (PGSTAT_KIND_BACKEND , InvalidOid ,
@@ -211,6 +280,9 @@ pgstat_flush_backend(bool nowait, bits32 flags)
211280 if (flags & PGSTAT_BACKEND_FLUSH_IO )
212281 pgstat_flush_backend_entry_io (entry_ref );
213282
283+ if (flags & PGSTAT_BACKEND_FLUSH_WAL )
284+ pgstat_flush_backend_entry_wal (entry_ref );
285+
214286 pgstat_unlock_entry (entry_ref );
215287
216288 return false;
@@ -226,7 +298,8 @@ pgstat_backend_have_pending_cb(void)
226298 return false;
227299
228300 return (!pg_memory_is_all_zeros (& PendingBackendStats ,
229- sizeof (struct PgStat_BackendPending )));
301+ sizeof (struct PgStat_BackendPending )) ||
302+ pgstat_backend_wal_have_pending ());
230303}
231304
232305/*
@@ -261,6 +334,13 @@ pgstat_create_backend(ProcNumber procnum)
261334 pgstat_unlock_entry (entry_ref );
262335
263336 MemSet (& PendingBackendStats , 0 , sizeof (PgStat_BackendPending ));
337+
338+ /*
339+ * Initialize prevBackendWalUsage with pgWalUsage so that
340+ * pgstat_backend_flush_cb() can calculate how much pgWalUsage counters
341+ * are increased by subtracting prevBackendWalUsage from pgWalUsage.
342+ */
343+ prevBackendWalUsage = pgWalUsage ;
264344}
265345
266346/*
0 commit comments