PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pgstat_replslot.c
Go to the documentation of this file.
1/* -------------------------------------------------------------------------
2 *
3 * pgstat_replslot.c
4 * Implementation of replication slot statistics.
5 *
6 * This file contains the implementation of replication slot 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 * Replication slot stats work a bit different than other variable-numbered
12 * stats. Slots do not have oids (so they can be created on physical
13 * replicas). Use the slot index as object id while running. However, the slot
14 * index can change when restarting. That is addressed by using the name when
15 * (de-)serializing. After a restart it is possible for slots to have been
16 * dropped while shut down, which is addressed by not restoring stats for
17 * slots that cannot be found by name when starting up.
18 *
19 * Copyright (c) 2001-2026, PostgreSQL Global Development Group
20 *
21 * IDENTIFICATION
22 * src/backend/utils/activity/pgstat_replslot.c
23 * -------------------------------------------------------------------------
24 */
25
26#include "postgres.h"
27
28#include "replication/slot.h"
30
31
32static int get_replslot_index(const char *name, bool need_lock);
33
34
35/*
36 * Reset counters for a single replication slot.
37 *
38 * Permission checking for this function is managed through the normal
39 * GRANT system.
40 */
41void
43{
44 ReplicationSlot *slot;
45
46 Assert(name != NULL);
47
49
50 /* Check if the slot exists with the given name. */
51 slot = SearchNamedReplicationSlot(name, false);
52 if (!slot)
55 errmsg("replication slot \"%s\" does not exist",
56 name)));
57
58 /*
59 * Reset stats if it is a logical slot. Nothing to do for physical slots
60 * as we collect stats only for logical slots.
61 */
62 if (SlotIsLogical(slot))
65
67}
68
69/*
70 * Report replication slot statistics.
71 *
72 * We can rely on the stats for the slot to exist and to belong to this
73 * slot. We can only get here if pgstat_create_replslot() or
74 * pgstat_acquire_replslot() have already been called.
75 */
76void
78{
79 PgStat_EntryRef *entry_ref;
82
84 ReplicationSlotIndex(slot), false);
86 statent = &shstatent->stats;
87
88 /* Update the replication slot statistics */
89#define REPLSLOT_ACC(fld) statent->fld += repSlotStat->fld
90 REPLSLOT_ACC(spill_txns);
91 REPLSLOT_ACC(spill_count);
92 REPLSLOT_ACC(spill_bytes);
93 REPLSLOT_ACC(stream_txns);
94 REPLSLOT_ACC(stream_count);
95 REPLSLOT_ACC(stream_bytes);
96 REPLSLOT_ACC(mem_exceeded_count);
97 REPLSLOT_ACC(total_txns);
98 REPLSLOT_ACC(total_bytes);
99#undef REPLSLOT_ACC
100
101 pgstat_unlock_entry(entry_ref);
102}
103
104/*
105 * Report replication slot sync skip statistics.
106 *
107 * Similar to pgstat_report_replslot(), we can rely on the stats for the
108 * slot to exist and to belong to this slot.
109 */
110void
112{
113 PgStat_EntryRef *entry_ref;
116
117 /* Slot sync stats are valid only for synced logical slots on standby. */
118 Assert(slot->data.synced);
120
122 ReplicationSlotIndex(slot), false);
123 Assert(entry_ref != NULL);
124
126 statent = &shstatent->stats;
127
128 statent->slotsync_skip_count += 1;
129 statent->slotsync_last_skip = GetCurrentTimestamp();
130
131 pgstat_unlock_entry(entry_ref);
132}
133
134/*
135 * Report replication slot creation.
136 *
137 * NB: This gets called with ReplicationSlotAllocationLock already held, be
138 * careful about calling back into slot.c.
139 */
140void
142{
143 PgStat_EntryRef *entry_ref;
145
147
149 ReplicationSlotIndex(slot), false);
151
152 /*
153 * NB: need to accept that there might be stats from an older slot, e.g.
154 * if we previously crashed after dropping a slot.
155 */
156 memset(&shstatent->stats, 0, sizeof(shstatent->stats));
157
158 pgstat_unlock_entry(entry_ref);
159}
160
161/*
162 * Report replication slot has been acquired.
163 *
164 * This guarantees that a stats entry exists during later
165 * pgstat_report_replslot() or pgstat_report_replslotsync() calls.
166 *
167 * If we previously crashed, no stats data exists. But if we did not crash,
168 * the stats do belong to this slot:
169 * - the stats cannot belong to a dropped slot, pgstat_drop_replslot() would
170 * have been called
171 * - if the slot was removed while shut down,
172 * pgstat_replslot_from_serialized_name_cb() returning false would have
173 * caused the stats to be dropped
174 */
175void
181
182/*
183 * Report replication slot drop.
184 */
185void
194
195/*
196 * Support function for the SQL-callable pgstat* functions. Returns
197 * a pointer to the replication slot statistics struct.
198 */
217
218void
220{
221 /*
222 * This is only called late during shutdown. The set of existing slots
223 * isn't allowed to change at this point, we can assume that a slot exists
224 * at the offset.
225 */
226 if (!ReplicationSlotName(key->objid, name))
227 elog(ERROR, "could not find name for replication slot index %" PRIu64,
228 key->objid);
229}
230
231bool
233{
234 int idx = get_replslot_index(NameStr(*name), true);
235
236 /* slot might have been deleted */
237 if (idx == -1)
238 return false;
239
240 key->kind = PGSTAT_KIND_REPLSLOT;
241 key->dboid = InvalidOid;
242 key->objid = idx;
243
244 return true;
245}
246
247void
249{
250 ((PgStatShared_ReplSlot *) header)->stats.stat_reset_timestamp = ts;
251}
252
253static int
255{
256 ReplicationSlot *slot;
257
258 Assert(name != NULL);
259
261
262 if (!slot)
263 return -1;
264
265 return ReplicationSlotIndex(slot);
266}
Datum idx(PG_FUNCTION_ARGS)
Definition _int_op.c:262
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1645
#define NameStr(name)
Definition c.h:765
#define Assert(condition)
Definition c.h:873
int64 TimestampTz
Definition timestamp.h:39
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1176
bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1955
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1793
@ LW_SHARED
Definition lwlock.h:113
@ LW_EXCLUSIVE
Definition lwlock.h:112
void pgstat_reset(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition pgstat.c:864
void * pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition pgstat.c:944
#define PGSTAT_KIND_REPLSLOT
Definition pgstat_kind.h:30
bool pgstat_replslot_from_serialized_name_cb(const NameData *name, PgStat_HashKey *key)
void pgstat_reset_replslot(const char *name)
void pgstat_create_replslot(ReplicationSlot *slot)
PgStat_StatReplSlotEntry * pgstat_fetch_replslot(NameData slotname)
void pgstat_acquire_replslot(ReplicationSlot *slot)
static int get_replslot_index(const char *name, bool need_lock)
void pgstat_report_replslot(ReplicationSlot *slot, const PgStat_StatReplSlotEntry *repSlotStat)
void pgstat_replslot_to_serialized_name_cb(const PgStat_HashKey *key, const PgStatShared_Common *header, NameData *name)
void pgstat_replslot_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts)
void pgstat_drop_replslot(ReplicationSlot *slot)
void pgstat_report_replslotsync(ReplicationSlot *slot)
#define REPLSLOT_ACC(fld)
void pgstat_request_entry_refs_gc(void)
PgStat_EntryRef * pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, uint64 objid, bool create, bool *created_entry)
bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
void pgstat_unlock_entry(PgStat_EntryRef *entry_ref)
PgStat_EntryRef * pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, uint64 objid, bool nowait)
#define InvalidOid
static int fb(int x)
int ReplicationSlotIndex(ReplicationSlot *slot)
Definition slot.c:573
ReplicationSlot * SearchNamedReplicationSlot(const char *name, bool need_lock)
Definition slot.c:540
bool ReplicationSlotName(int index, Name name)
Definition slot.c:589
#define SlotIsLogical(slot)
Definition slot.h:285
PgStatShared_Common * shared_stats
ReplicationSlotPersistentData data
Definition slot.h:210
Definition c.h:760
const char * name
bool RecoveryInProgress(void)
Definition xlog.c:6460