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-2024, PostgreSQL Global Development Group
12  *
13  * IDENTIFICATION
14  * src/backend/utils/activity/pgstat_slru.c
15  * -------------------------------------------------------------------------
16  */
17 
18 #include "postgres.h"
19 
20 #include "utils/pgstat_internal.h"
21 #include "utils/timestamp.h"
22 
23 
24 static 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  */
35 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  */
44 void
45 pgstat_reset_slru(const char *name)
46 {
48 
49  Assert(name != NULL);
50 
52 }
53 
54 /*
55  * SLRU statistics count accumulation functions --- called from slru.c
56  */
57 
58 void
60 {
61  get_slru_entry(slru_idx)->blocks_zeroed += 1;
62 }
63 
64 void
66 {
67  get_slru_entry(slru_idx)->blocks_hit += 1;
68 }
69 
70 void
72 {
73  get_slru_entry(slru_idx)->blocks_exists += 1;
74 }
75 
76 void
78 {
79  get_slru_entry(slru_idx)->blocks_read += 1;
80 }
81 
82 void
84 {
85  get_slru_entry(slru_idx)->blocks_written += 1;
86 }
87 
88 void
90 {
91  get_slru_entry(slru_idx)->flush += 1;
92 }
93 
94 void
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 
109  return pgStatLocal.snapshot.slru;
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  */
117 const char *
118 pgstat_get_slru_name(int slru_idx)
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  */
131 int
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  * Flush out locally pending SLRU stats entries
148  *
149  * If nowait is true, this function returns false on lock failure. Otherwise
150  * this function always returns true.
151  *
152  * If nowait is true, this function returns true if the lock could not be
153  * acquired. Otherwise return false.
154  */
155 bool
156 pgstat_slru_flush(bool nowait)
157 {
158  PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
159  int i;
160 
161  if (!have_slrustats)
162  return false;
163 
164  if (!nowait)
165  LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
166  else if (!LWLockConditionalAcquire(&stats_shmem->lock, LW_EXCLUSIVE))
167  return true;
168 
169  for (i = 0; i < SLRU_NUM_ELEMENTS; i++)
170  {
171  PgStat_SLRUStats *sharedent = &stats_shmem->stats[i];
172  PgStat_SLRUStats *pendingent = &pending_SLRUStats[i];
173 
174 #define SLRU_ACC(fld) sharedent->fld += pendingent->fld
175  SLRU_ACC(blocks_zeroed);
176  SLRU_ACC(blocks_hit);
177  SLRU_ACC(blocks_read);
179  SLRU_ACC(blocks_exists);
180  SLRU_ACC(flush);
181  SLRU_ACC(truncate);
182 #undef SLRU_ACC
183  }
184 
185  /* done, clear the pending entry */
187 
188  LWLockRelease(&stats_shmem->lock);
189 
190  have_slrustats = false;
191 
192  return false;
193 }
194 
195 void
197 {
198  for (int i = 0; i < SLRU_NUM_ELEMENTS; i++)
200 }
201 
202 void
204 {
205  PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
206 
207  LWLockAcquire(&stats_shmem->lock, LW_SHARED);
208 
209  memcpy(pgStatLocal.snapshot.slru, &stats_shmem->stats,
210  sizeof(stats_shmem->stats));
211 
212  LWLockRelease(&stats_shmem->lock);
213 }
214 
215 /*
216  * Returns pointer to entry with counters for given SLRU (based on the name
217  * stored in SlruCtl as lwlock tranche name).
218  */
219 static inline PgStat_SLRUStats *
220 get_slru_entry(int slru_idx)
221 {
223 
224  /*
225  * The postmaster should never register any SLRU statistics counts; if it
226  * did, the counts would be duplicated into child processes via fork().
227  */
229 
230  Assert((slru_idx >= 0) && (slru_idx < SLRU_NUM_ELEMENTS));
231 
232  have_slrustats = true;
233 
234  return &pending_SLRUStats[slru_idx];
235 }
236 
237 static void
239 {
240  PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
241 
242  LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
243 
244  memset(&stats_shmem->stats[index], 0, sizeof(PgStat_SLRUStats));
245  stats_shmem->stats[index].stat_reset_timestamp = ts;
246 
247  LWLockRelease(&stats_shmem->lock);
248 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1654
#define Assert(condition)
Definition: c.h:858
#define MemSet(start, val, len)
Definition: c.h:1020
int64 TimestampTz
Definition: timestamp.h:39
bool IsUnderPostmaster
Definition: globals.c:117
bool IsPostmasterEnvironment
Definition: globals.c:116
int i
Definition: isn.c:73
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1170
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1783
bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1341
@ LW_SHARED
Definition: lwlock.h:115
@ LW_EXCLUSIVE
Definition: lwlock.h:114
static int64 blocks_written
Definition: pg_checksums.c:39
void pgstat_snapshot_fixed(PgStat_Kind kind)
Definition: pgstat.c:938
PgStat_LocalState pgStatLocal
Definition: pgstat.c:193
@ PGSTAT_KIND_SLRU
Definition: pgstat.h:52
static const char *const slru_names[]
#define pgstat_assert_is_up()
#define SLRU_NUM_ELEMENTS
bool have_slrustats
Definition: pgstat_slru.c:35
void pgstat_slru_snapshot_cb(void)
Definition: pgstat_slru.c:203
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
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
#define SLRU_ACC(fld)
static void pgstat_reset_slru_counter_internal(int index, TimestampTz ts)
Definition: pgstat_slru.c:238
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
PgStat_SLRUStats * pgstat_fetch_slru(void)
Definition: pgstat_slru.c:105
const char * pgstat_get_slru_name(int slru_idx)
Definition: pgstat_slru.c:118
bool pgstat_slru_flush(bool nowait)
Definition: pgstat_slru.c:156
void pgstat_slru_reset_all_cb(TimestampTz ts)
Definition: pgstat_slru.c:196
void pgstat_count_slru_flush(int slru_idx)
Definition: pgstat_slru.c:89
static PgStat_SLRUStats * get_slru_entry(int slru_idx)
Definition: pgstat_slru.c:220
PgStat_SLRUStats stats[SLRU_NUM_ELEMENTS]
PgStat_Snapshot snapshot
PgStat_ShmemControl * shmem
PgStat_Counter blocks_read
Definition: pgstat.h:384
PgStat_Counter blocks_exists
Definition: pgstat.h:386
TimestampTz stat_reset_timestamp
Definition: pgstat.h:389
PgStat_Counter blocks_zeroed
Definition: pgstat.h:382
PgStat_Counter blocks_written
Definition: pgstat.h:385
PgStat_Counter blocks_hit
Definition: pgstat.h:383
PgStat_Counter truncate
Definition: pgstat.h:388
PgStat_Counter flush
Definition: pgstat.h:387
PgStatShared_SLRU slru
PgStat_SLRUStats slru[SLRU_NUM_ELEMENTS]
Definition: type.h:95
const char * name