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-2022, 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  AssertArg(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. Writer processes are mutually excluded
151  * using LWLock, but readers are expected to use change-count protocol to avoid
152  * interference with writers.
153  *
154  * If nowait is true, this function returns true if the lock could not be
155  * acquired. Otherwise return false.
156  */
157 bool
158 pgstat_slru_flush(bool nowait)
159 {
160  PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
161  int i;
162 
163  if (!have_slrustats)
164  return false;
165 
166  if (!nowait)
167  LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
168  else if (!LWLockConditionalAcquire(&stats_shmem->lock, LW_EXCLUSIVE))
169  return true;
170 
171  for (i = 0; i < SLRU_NUM_ELEMENTS; i++)
172  {
173  PgStat_SLRUStats *sharedent = &stats_shmem->stats[i];
174  PgStat_SLRUStats *pendingent = &pending_SLRUStats[i];
175 
176 #define SLRU_ACC(fld) sharedent->fld += pendingent->fld
177  SLRU_ACC(blocks_zeroed);
178  SLRU_ACC(blocks_hit);
179  SLRU_ACC(blocks_read);
181  SLRU_ACC(blocks_exists);
182  SLRU_ACC(flush);
183  SLRU_ACC(truncate);
184 #undef SLRU_ACC
185  }
186 
187  /* done, clear the pending entry */
189 
190  LWLockRelease(&stats_shmem->lock);
191 
192  have_slrustats = false;
193 
194  return false;
195 }
196 
197 void
199 {
200  for (int i = 0; i < SLRU_NUM_ELEMENTS; i++)
202 }
203 
204 void
206 {
207  PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
208 
209  LWLockAcquire(&stats_shmem->lock, LW_SHARED);
210 
211  memcpy(pgStatLocal.snapshot.slru, &stats_shmem->stats,
212  sizeof(stats_shmem->stats));
213 
214  LWLockRelease(&stats_shmem->lock);
215 }
216 
217 /*
218  * Returns pointer to entry with counters for given SLRU (based on the name
219  * stored in SlruCtl as lwlock tranche name).
220  */
221 static inline PgStat_SLRUStats *
222 get_slru_entry(int slru_idx)
223 {
225 
226  /*
227  * The postmaster should never register any SLRU statistics counts; if it
228  * did, the counts would be duplicated into child processes via fork().
229  */
231 
232  Assert((slru_idx >= 0) && (slru_idx < SLRU_NUM_ELEMENTS));
233 
234  have_slrustats = true;
235 
236  return &pending_SLRUStats[slru_idx];
237 }
238 
239 static void
241 {
242  PgStatShared_SLRU *stats_shmem = &pgStatLocal.shmem->slru;
243 
244  LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
245 
246  memset(&stats_shmem->stats[index], 0, sizeof(PgStat_SLRUStats));
247  stats_shmem->stats[index].stat_reset_timestamp = ts;
248 
249  LWLockRelease(&stats_shmem->lock);
250 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1574
#define MemSet(start, val, len)
Definition: c.h:1008
#define AssertArg(condition)
Definition: c.h:806
int64 TimestampTz
Definition: timestamp.h:39
const char * name
Definition: encode.c:561
bool IsUnderPostmaster
Definition: globals.c:113
bool IsPostmasterEnvironment
Definition: globals.c:112
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1196
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1800
bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1367
@ LW_SHARED
Definition: lwlock.h:105
@ LW_EXCLUSIVE
Definition: lwlock.h:104
static int64 blocks_written
Definition: pg_checksums.c:39
void pgstat_snapshot_fixed(PgStat_Kind kind)
Definition: pgstat.c:899
PgStat_LocalState pgStatLocal
Definition: pgstat.c:195
@ PGSTAT_KIND_SLRU
Definition: pgstat.h:51
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:205
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:240
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:158
void pgstat_slru_reset_all_cb(TimestampTz ts)
Definition: pgstat_slru.c:198
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:222
PgStat_SLRUStats stats[SLRU_NUM_ELEMENTS]
PgStat_Snapshot snapshot
PgStat_ShmemControl * shmem
PgStat_Counter blocks_read
Definition: pgstat.h:340
PgStat_Counter blocks_exists
Definition: pgstat.h:342
TimestampTz stat_reset_timestamp
Definition: pgstat.h:345
PgStat_Counter blocks_zeroed
Definition: pgstat.h:338
PgStat_Counter blocks_written
Definition: pgstat.h:341
PgStat_Counter blocks_hit
Definition: pgstat.h:339
PgStat_Counter truncate
Definition: pgstat.h:344
PgStat_Counter flush
Definition: pgstat.h:343
PgStatShared_SLRU slru
PgStat_SLRUStats slru[SLRU_NUM_ELEMENTS]
Definition: type.h:90