PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, 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
53
54/*
55 * SLRU statistics count accumulation functions --- called from slru.c
56 */
57
58#define PGSTAT_COUNT_SLRU(stat) \
59void \
60CppConcat(pgstat_count_slru_,stat)(int slru_idx) \
61{ \
62 get_slru_entry(slru_idx)->stat += 1; \
63}
64
65/* pgstat_count_slru_blocks_zeroed */
66PGSTAT_COUNT_SLRU(blocks_zeroed)
67
68/* pgstat_count_slru_blocks_hit */
69PGSTAT_COUNT_SLRU(blocks_hit)
70
71/* pgstat_count_slru_blocks_exists */
72PGSTAT_COUNT_SLRU(blocks_exists)
73
74/* pgstat_count_slru_blocks_read */
75PGSTAT_COUNT_SLRU(blocks_read)
76
77/* pgstat_count_slru_blocks_written */
79
80/* pgstat_count_slru_flush */
82
83/* pgstat_count_slru_truncate */
84PGSTAT_COUNT_SLRU(truncate)
85
86/*
87 * Support function for the SQL-callable pgstat* functions. Returns
88 * a pointer to the slru statistics struct.
89 */
97
98/*
99 * Returns SLRU name for an index. The index may be above SLRU_NUM_ELEMENTS,
100 * in which case this returns NULL. This allows writing code that does not
101 * know the number of entries in advance.
102 */
103const char *
105{
106 if (slru_idx < 0 || slru_idx >= SLRU_NUM_ELEMENTS)
107 return NULL;
108
109 return slru_names[slru_idx];
110}
111
112/*
113 * Determine index of entry for a SLRU with a given name. If there's no exact
114 * match, returns index of the last "other" entry used for SLRUs defined in
115 * external projects.
116 */
117int
119{
120 int i;
121
122 Assert(name);
123 for (i = 0; i < SLRU_NUM_ELEMENTS; i++)
124 {
125 if (strcmp(slru_names[i], name) == 0)
126 return i;
127 }
128
129 /* return index of the last entry (which is the "other" one) */
130 return (SLRU_NUM_ELEMENTS - 1);
131}
132
133/*
134 * Flush out locally pending SLRU stats entries
135 *
136 * If nowait is true, this function returns false on lock failure. Otherwise
137 * this function always returns true.
138 *
139 * If nowait is true, this function returns true if the lock could not be
140 * acquired. Otherwise return false.
141 */
142bool
144{
145 PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
146 int i;
147
148 if (!have_slrustats)
149 return false;
150
151 if (!nowait)
152 LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
153 else if (!LWLockConditionalAcquire(&stats_shmem->lock, LW_EXCLUSIVE))
154 return true;
155
156 for (i = 0; i < SLRU_NUM_ELEMENTS; i++)
157 {
158 PgStat_SLRUStats *sharedent = &stats_shmem->stats[i];
159 PgStat_SLRUStats *pendingent = &pending_SLRUStats[i];
160
161#define SLRU_ACC(fld) sharedent->fld += pendingent->fld
162 SLRU_ACC(blocks_zeroed);
163 SLRU_ACC(blocks_hit);
164 SLRU_ACC(blocks_read);
166 SLRU_ACC(blocks_exists);
167 SLRU_ACC(flush);
168 SLRU_ACC(truncate);
169#undef SLRU_ACC
170 }
171
172 /* done, clear the pending entry */
174
175 LWLockRelease(&stats_shmem->lock);
176
177 have_slrustats = false;
178
179 return false;
180}
181
182void
184{
185 PgStatShared_SLRU *stats_shmem = (PgStatShared_SLRU *) stats;
186
187 LWLockInitialize(&stats_shmem->lock, LWTRANCHE_PGSTATS_DATA);
188}
189
190void
196
197void
199{
200 PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
201
202 LWLockAcquire(&stats_shmem->lock, LW_SHARED);
203
204 memcpy(pgStatLocal.snapshot.slru, &stats_shmem->stats,
205 sizeof(stats_shmem->stats));
206
207 LWLockRelease(&stats_shmem->lock);
208}
209
210/*
211 * Returns pointer to entry with counters for given SLRU (based on the name
212 * stored in SlruCtl as lwlock tranche name).
213 */
214static inline PgStat_SLRUStats *
215get_slru_entry(int slru_idx)
216{
218
219 /*
220 * The postmaster should never register any SLRU statistics counts; if it
221 * did, the counts would be duplicated into child processes via fork().
222 */
224
225 Assert((slru_idx >= 0) && (slru_idx < SLRU_NUM_ELEMENTS));
226
227 have_slrustats = true;
228 pgstat_report_fixed = true;
229
230 return &pending_SLRUStats[slru_idx];
231}
232
233static void
235{
236 PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
237
238 LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
239
240 memset(&stats_shmem->stats[index], 0, sizeof(PgStat_SLRUStats));
241 stats_shmem->stats[index].stat_reset_timestamp = ts;
242
243 LWLockRelease(&stats_shmem->lock);
244}
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1639
#define Assert(condition)
Definition c.h:943
#define MemSet(start, val, len)
Definition c.h:1107
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
int64 TimestampTz
Definition timestamp.h:39
bool IsUnderPostmaster
Definition globals.c:122
bool IsPostmasterEnvironment
Definition globals.c:121
int i
Definition isn.c:77
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition lwlock.c:670
bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1321
@ LW_SHARED
Definition lwlock.h:105
@ LW_EXCLUSIVE
Definition lwlock.h:104
static int64 blocks_written
void pgstat_snapshot_fixed(PgStat_Kind kind)
Definition pgstat.c:1104
bool pgstat_report_fixed
Definition pgstat.c:219
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:40
static bool have_slrustats
Definition pgstat_slru.c:35
void pgstat_slru_snapshot_cb(void)
static PgStat_SLRUStats pending_SLRUStats[SLRU_NUM_ELEMENTS]
Definition pgstat_slru.c:34
int pgstat_get_slru_index(const char *name)
PgStat_SLRUStats * pgstat_fetch_slru(void)
Definition pgstat_slru.c:91
#define PGSTAT_COUNT_SLRU(stat)
Definition pgstat_slru.c:58
bool pgstat_slru_flush_cb(bool nowait)
#define SLRU_ACC(fld)
static void pgstat_reset_slru_counter_internal(int index, TimestampTz ts)
const char * pgstat_get_slru_name(int slru_idx)
void pgstat_reset_slru(const char *name)
Definition pgstat_slru.c:45
void pgstat_slru_reset_all_cb(TimestampTz ts)
void pgstat_slru_init_shmem_cb(void *stats)
static PgStat_SLRUStats * get_slru_entry(int slru_idx)
PgStat_SLRUStats stats[SLRU_NUM_ELEMENTS]
PgStat_Snapshot snapshot
PgStat_ShmemControl * shmem
TimestampTz stat_reset_timestamp
Definition pgstat.h:439
PgStatShared_SLRU slru
PgStat_SLRUStats slru[SLRU_NUM_ELEMENTS]
Definition type.h:96
const char * name