PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pgstat_wal.c
Go to the documentation of this file.
1/* -------------------------------------------------------------------------
2 *
3 * pgstat_wal.c
4 * Implementation of WAL statistics.
5 *
6 * This file contains the implementation of WAL statistics. It is kept
7 * separate from pgstat.c to enforce the line between the statistics access /
8 * storage implementation and the details about individual types of
9 * statistics.
10 *
11 * Copyright (c) 2001-2024, PostgreSQL Global Development Group
12 *
13 * IDENTIFICATION
14 * src/backend/utils/activity/pgstat_wal.c
15 * -------------------------------------------------------------------------
16 */
17
18#include "postgres.h"
19
20#include "executor/instrument.h"
22
23
25
26/*
27 * WAL usage counters saved from pgWalUsage at the previous call to
28 * pgstat_report_wal(). This is used to calculate how much WAL usage
29 * happens between pgstat_report_wal() calls, by subtracting
30 * the previous counters from the current ones.
31 */
33
34
35/*
36 * Calculate how much WAL usage counters have increased and update
37 * shared WAL and IO statistics.
38 *
39 * Must be called by processes that generate WAL, that do not call
40 * pgstat_report_stat(), like walwriter.
41 *
42 * "force" set to true ensures that the statistics are flushed; note that
43 * this needs to acquire the pgstat shmem LWLock, waiting on it. When
44 * set to false, the statistics may not be flushed if the lock could not
45 * be acquired.
46 */
47void
49{
50 bool nowait;
51
52 /* like in pgstat.c, don't wait for lock acquisition when !force */
53 nowait = !force;
54
55 /* flush wal stats */
56 pgstat_flush_wal(nowait);
57
58 /* flush IO stats */
59 pgstat_flush_io(nowait);
60}
61
62/*
63 * Support function for the SQL-callable pgstat* functions. Returns
64 * a pointer to the WAL statistics struct.
65 */
68{
70
71 return &pgStatLocal.snapshot.wal;
72}
73
74/*
75 * Simple wrapper of pgstat_wal_flush_cb()
76 */
77void
78pgstat_flush_wal(bool nowait)
79{
80 (void) pgstat_wal_flush_cb(nowait);
81}
82
83/*
84 * Calculate how much WAL usage counters have increased by subtracting the
85 * previous counters from the current ones.
86 *
87 * If nowait is true, this function returns true if the lock could not be
88 * acquired. Otherwise return false.
89 */
90bool
92{
93 PgStatShared_Wal *stats_shmem = &pgStatLocal.shmem->wal;
94 WalUsage wal_usage_diff = {0};
95
97 Assert(pgStatLocal.shmem != NULL &&
99
100 /*
101 * This function can be called even if nothing at all has happened. Avoid
102 * taking lock for nothing in that case.
103 */
105 return false;
106
107 /*
108 * We don't update the WAL usage portion of the local WalStats elsewhere.
109 * Calculate how much WAL usage counters were increased by subtracting the
110 * previous counters from the current ones.
111 */
112 WalUsageAccumDiff(&wal_usage_diff, &pgWalUsage, &prevWalUsage);
113
114 if (!nowait)
115 LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
116 else if (!LWLockConditionalAcquire(&stats_shmem->lock, LW_EXCLUSIVE))
117 return true;
118
119#define WALSTAT_ACC(fld, var_to_add) \
120 (stats_shmem->stats.fld += var_to_add.fld)
121#define WALSTAT_ACC_INSTR_TIME(fld) \
122 (stats_shmem->stats.fld += INSTR_TIME_GET_MICROSEC(PendingWalStats.fld))
123 WALSTAT_ACC(wal_records, wal_usage_diff);
124 WALSTAT_ACC(wal_fpi, wal_usage_diff);
125 WALSTAT_ACC(wal_bytes, wal_usage_diff);
126 WALSTAT_ACC(wal_buffers_full, PendingWalStats);
127 WALSTAT_ACC(wal_write, PendingWalStats);
128 WALSTAT_ACC(wal_sync, PendingWalStats);
129 WALSTAT_ACC_INSTR_TIME(wal_write_time);
130 WALSTAT_ACC_INSTR_TIME(wal_sync_time);
131#undef WALSTAT_ACC_INSTR_TIME
132#undef WALSTAT_ACC
133
134 LWLockRelease(&stats_shmem->lock);
135
136 /*
137 * Save the current counters for the subsequent calculation of WAL usage.
138 */
140
141 /*
142 * Clear out the statistics buffer, so it can be re-used.
143 */
145
146 return false;
147}
148
149void
151{
152 /*
153 * Initialize prevWalUsage with pgWalUsage so that pgstat_wal_flush_cb()
154 * can calculate how much pgWalUsage counters are increased by subtracting
155 * prevWalUsage from pgWalUsage.
156 */
158}
159
160/*
161 * To determine whether any WAL activity has occurred since last time, not
162 * only the number of generated WAL records but also the numbers of WAL
163 * writes and syncs need to be checked. Because even transaction that
164 * generates no WAL records can write or sync WAL data when flushing the
165 * data pages.
166 */
167bool
169{
173}
174
175void
177{
178 PgStatShared_Wal *stats_shmem = (PgStatShared_Wal *) stats;
179
181}
182
183void
185{
186 PgStatShared_Wal *stats_shmem = &pgStatLocal.shmem->wal;
187
188 LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
189 memset(&stats_shmem->stats, 0, sizeof(stats_shmem->stats));
190 stats_shmem->stats.stat_reset_timestamp = ts;
191 LWLockRelease(&stats_shmem->lock);
192}
193
194void
196{
197 PgStatShared_Wal *stats_shmem = &pgStatLocal.shmem->wal;
198
199 LWLockAcquire(&stats_shmem->lock, LW_SHARED);
200 memcpy(&pgStatLocal.snapshot.wal, &stats_shmem->stats,
201 sizeof(pgStatLocal.snapshot.wal));
202 LWLockRelease(&stats_shmem->lock);
203}
#define Assert(condition)
Definition: c.h:812
#define MemSet(start, val, len)
Definition: c.h:974
int64 TimestampTz
Definition: timestamp.h:39
bool IsUnderPostmaster
Definition: globals.c:119
bool IsPostmasterEnvironment
Definition: globals.c:118
WalUsage pgWalUsage
Definition: instrument.c:22
void WalUsageAccumDiff(WalUsage *dst, const WalUsage *add, const WalUsage *sub)
Definition: instrument.c:286
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1168
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1781
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:707
bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1339
@ LWTRANCHE_PGSTATS_DATA
Definition: lwlock.h:205
@ LW_SHARED
Definition: lwlock.h:115
@ LW_EXCLUSIVE
Definition: lwlock.h:114
void pgstat_snapshot_fixed(PgStat_Kind kind)
Definition: pgstat.c:1089
PgStat_LocalState pgStatLocal
Definition: pgstat.c:213
#define PGSTAT_KIND_WAL
Definition: pgstat.h:60
void pgstat_flush_io(bool nowait)
Definition: pgstat_io.c:186
void pgstat_flush_wal(bool nowait)
Definition: pgstat_wal.c:78
#define WALSTAT_ACC(fld, var_to_add)
void pgstat_wal_reset_all_cb(TimestampTz ts)
Definition: pgstat_wal.c:184
void pgstat_wal_init_shmem_cb(void *stats)
Definition: pgstat_wal.c:176
void pgstat_report_wal(bool force)
Definition: pgstat_wal.c:48
void pgstat_wal_init_backend_cb(void)
Definition: pgstat_wal.c:150
bool pgstat_wal_flush_cb(bool nowait)
Definition: pgstat_wal.c:91
static WalUsage prevWalUsage
Definition: pgstat_wal.c:32
bool pgstat_wal_have_pending_cb(void)
Definition: pgstat_wal.c:168
void pgstat_wal_snapshot_cb(void)
Definition: pgstat_wal.c:195
PgStat_PendingWalStats PendingWalStats
Definition: pgstat_wal.c:24
PgStat_WalStats * pgstat_fetch_stat_wal(void)
Definition: pgstat_wal.c:67
#define WALSTAT_ACC_INSTR_TIME(fld)
PgStat_WalStats stats
PgStat_Snapshot snapshot
PgStat_ShmemControl * shmem
PgStat_Counter wal_write
Definition: pgstat.h:520
PgStat_Counter wal_sync
Definition: pgstat.h:521
PgStatShared_Wal wal
PgStat_WalStats wal
TimestampTz stat_reset_timestamp
Definition: pgstat.h:508
int64 wal_records
Definition: instrument.h:53