PostgreSQL Source Code git master
pgstat_slru.c
Go to the documentation of this file.
1/* -------------------------------------------------------------------------
2 *
3 * pgstat_slru.c
4 * Implementation of SLRU statistics.
5 *
6 * This file contains the implementation of SLRU 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-2025, PostgreSQL Global Development Group
12 *
13 * IDENTIFICATION
14 * src/backend/utils/activity/pgstat_slru.c
15 * -------------------------------------------------------------------------
16 */
17
18#include "postgres.h"
19
21#include "utils/timestamp.h"
22
23
24static inline PgStat_SLRUStats *get_slru_entry(int slru_idx);
26
27
28/*
29 * SLRU statistics counts waiting to be flushed out. We assume this variable
30 * inits to zeroes. Entries are one-to-one with slru_names[]. Changes of
31 * SLRU counters are reported within critical sections so we use static memory
32 * in order to avoid memory allocation.
33 */
35static bool have_slrustats = false;
36
37
38/*
39 * Reset counters for a single SLRU.
40 *
41 * Permission checking for this function is managed through the normal
42 * GRANT system.
43 */
44void
46{
48
49 Assert(name != NULL);
50
52}
53
54/*
55 * SLRU statistics count accumulation functions --- called from slru.c
56 */
57
58void
60{
61 get_slru_entry(slru_idx)->blocks_zeroed += 1;
62}
63
64void
66{
67 get_slru_entry(slru_idx)->blocks_hit += 1;
68}
69
70void
72{
73 get_slru_entry(slru_idx)->blocks_exists += 1;
74}
75
76void
78{
79 get_slru_entry(slru_idx)->blocks_read += 1;
80}
81
82void
84{
85 get_slru_entry(slru_idx)->blocks_written += 1;
86}
87
88void
90{
91 get_slru_entry(slru_idx)->flush += 1;
92}
93
94void
96{
97 get_slru_entry(slru_idx)->truncate += 1;
98}
99
100/*
101 * Support function for the SQL-callable pgstat* functions. Returns
102 * a pointer to the slru statistics struct.
103 */
106{
108
110}
111
112/*
113 * Returns SLRU name for an index. The index may be above SLRU_NUM_ELEMENTS,
114 * in which case this returns NULL. This allows writing code that does not
115 * know the number of entries in advance.
116 */
117const char *
119{
120 if (slru_idx < 0 || slru_idx >= SLRU_NUM_ELEMENTS)
121 return NULL;
122
123 return slru_names[slru_idx];
124}
125
126/*
127 * Determine index of entry for a SLRU with a given name. If there's no exact
128 * match, returns index of the last "other" entry used for SLRUs defined in
129 * external projects.
130 */
131int
133{
134 int i;
135
136 for (i = 0; i < SLRU_NUM_ELEMENTS; i++)
137 {
138 if (strcmp(slru_names[i], name) == 0)
139 return i;
140 }
141
142 /* return index of the last entry (which is the "other" one) */
143 return (SLRU_NUM_ELEMENTS - 1);
144}
145
146/*
147 * Check if there are any SLRU stats entries waiting for flush.
148 */
149bool
151{
152 return have_slrustats;
153}
154
155/*
156 * Flush out locally pending SLRU stats entries
157 *
158 * If nowait is true, this function returns false on lock failure. Otherwise
159 * this function always returns true.
160 *
161 * If nowait is true, this function returns true if the lock could not be
162 * acquired. Otherwise return false.
163 */
164bool
166{
167 PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
168 int i;
169
170 if (!have_slrustats)
171 return false;
172
173 if (!nowait)
174 LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
175 else if (!LWLockConditionalAcquire(&stats_shmem->lock, LW_EXCLUSIVE))
176 return true;
177
178 for (i = 0; i < SLRU_NUM_ELEMENTS; i++)
179 {
180 PgStat_SLRUStats *sharedent = &stats_shmem->stats[i];
181 PgStat_SLRUStats *pendingent = &pending_SLRUStats[i];
182
183#define SLRU_ACC(fld) sharedent->fld += pendingent->fld
184 SLRU_ACC(blocks_zeroed);
185 SLRU_ACC(blocks_hit);
186 SLRU_ACC(blocks_read);
188 SLRU_ACC(blocks_exists);
189 SLRU_ACC(flush);
190 SLRU_ACC(truncate);
191#undef SLRU_ACC
192 }
193
194 /* done, clear the pending entry */
196
197 LWLockRelease(&stats_shmem->lock);
198
199 have_slrustats = false;
200
201 return false;
202}
203
204void
206{
207 PgStatShared_SLRU *stats_shmem = (PgStatShared_SLRU *) stats;
208
210}
211
212void
214{
215 for (int i = 0; i < SLRU_NUM_ELEMENTS; i++)
217}
218
219void
221{
222 PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
223
224 LWLockAcquire(&stats_shmem->lock, LW_SHARED);
225
226 memcpy(pgStatLocal.snapshot.slru, &stats_shmem->stats,
227 sizeof(stats_shmem->stats));
228
229 LWLockRelease(&stats_shmem->lock);
230}
231
232/*
233 * Returns pointer to entry with counters for given SLRU (based on the name
234 * stored in SlruCtl as lwlock tranche name).
235 */
236static inline PgStat_SLRUStats *
237get_slru_entry(int slru_idx)
238{
240
241 /*
242 * The postmaster should never register any SLRU statistics counts; if it
243 * did, the counts would be duplicated into child processes via fork().
244 */
246
247 Assert((slru_idx >= 0) && (slru_idx < SLRU_NUM_ELEMENTS));
248
249 have_slrustats = true;
250
251 return &pending_SLRUStats[slru_idx];
252}
253
254static void
256{
257 PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
258
259 LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
260
261 memset(&stats_shmem->stats[index], 0, sizeof(PgStat_SLRUStats));
262 stats_shmem->stats[index].stat_reset_timestamp = ts;
263
264 LWLockRelease(&stats_shmem->lock);
265}
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1644
#define Assert(condition)
Definition: c.h:815
#define MemSet(start, val, len)
Definition: c.h:977
int64 TimestampTz
Definition: timestamp.h:39
bool IsUnderPostmaster
Definition: globals.c:119
bool IsPostmasterEnvironment
Definition: globals.c:118
int i
Definition: isn.c:72
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
static int64 blocks_written
Definition: pg_checksums.c:38
void pgstat_snapshot_fixed(PgStat_Kind kind)
Definition: pgstat.c:1089
PgStat_LocalState pgStatLocal
Definition: pgstat.c:213
static const char *const slru_names[]
#define pgstat_assert_is_up()
#define SLRU_NUM_ELEMENTS
#define PGSTAT_KIND_SLRU
Definition: pgstat_kind.h:39
static bool have_slrustats
Definition: pgstat_slru.c:35
void pgstat_slru_snapshot_cb(void)
Definition: pgstat_slru.c:220
void pgstat_count_slru_page_exists(int slru_idx)
Definition: pgstat_slru.c:71
void pgstat_count_slru_page_read(int slru_idx)
Definition: pgstat_slru.c:77
static PgStat_SLRUStats pending_SLRUStats[SLRU_NUM_ELEMENTS]
Definition: pgstat_slru.c:34
int pgstat_get_slru_index(const char *name)
Definition: pgstat_slru.c:132
PgStat_SLRUStats * pgstat_fetch_slru(void)
Definition: pgstat_slru.c:105
void pgstat_count_slru_page_hit(int slru_idx)
Definition: pgstat_slru.c:65
void pgstat_count_slru_page_zeroed(int slru_idx)
Definition: pgstat_slru.c:59
void pgstat_count_slru_truncate(int slru_idx)
Definition: pgstat_slru.c:95
bool pgstat_slru_flush_cb(bool nowait)
Definition: pgstat_slru.c:165
#define SLRU_ACC(fld)
static void pgstat_reset_slru_counter_internal(int index, TimestampTz ts)
Definition: pgstat_slru.c:255
const char * pgstat_get_slru_name(int slru_idx)
Definition: pgstat_slru.c:118
void pgstat_count_slru_page_written(int slru_idx)
Definition: pgstat_slru.c:83
void pgstat_reset_slru(const char *name)
Definition: pgstat_slru.c:45
void pgstat_slru_reset_all_cb(TimestampTz ts)
Definition: pgstat_slru.c:213
void pgstat_count_slru_flush(int slru_idx)
Definition: pgstat_slru.c:89
void pgstat_slru_init_shmem_cb(void *stats)
Definition: pgstat_slru.c:205
bool pgstat_slru_have_pending_cb(void)
Definition: pgstat_slru.c:150
static PgStat_SLRUStats * get_slru_entry(int slru_idx)
Definition: pgstat_slru.c:237
PgStat_SLRUStats stats[SLRU_NUM_ELEMENTS]
PgStat_Snapshot snapshot
PgStat_ShmemControl * shmem
PgStat_Counter blocks_read
Definition: pgstat.h:422
PgStat_Counter blocks_exists
Definition: pgstat.h:424
TimestampTz stat_reset_timestamp
Definition: pgstat.h:427
PgStat_Counter blocks_zeroed
Definition: pgstat.h:420
PgStat_Counter blocks_written
Definition: pgstat.h:423
PgStat_Counter blocks_hit
Definition: pgstat.h:421
PgStat_Counter truncate
Definition: pgstat.h:426
PgStat_Counter flush
Definition: pgstat.h:425
PgStatShared_SLRU slru
PgStat_SLRUStats slru[SLRU_NUM_ELEMENTS]
Definition: type.h:96
const char * name