1/* -------------------------------------------------------------------------
4 * Implementation of replication slot statistics.
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
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.
19 * Copyright (c) 2001-2025, PostgreSQL Global Development Group
22 * src/backend/utils/activity/pgstat_replslot.c
23 * -------------------------------------------------------------------------
36 * Reset counters for a single replication slot.
38 * Permission checking for this function is managed through the normal
50 /* Check if the slot exits with the given name. */
55 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
56 errmsg(
"replication slot \"%s\" does not exist",
60 * Reset stats if it is a logical slot. Nothing to do for physical slots
61 * as we collect stats only for logical slots.
71 * Report replication slot statistics.
73 * We can rely on the stats for the slot to exist and to belong to this
74 * slot. We can only get here if pgstat_create_replslot() or
75 * pgstat_acquire_replslot() have already been called.
87 statent = &shstatent->
stats;
89 /* Update the replication slot statistics */
90#define
REPLSLOT_ACC(fld) statent->fld += repSlotStat->fld
105 * Report replication slot creation.
107 * NB: This gets called with ReplicationSlotAllocationLock already held, be
108 * careful about calling back into slot.c.
123 * NB: need to accept that there might be stats from an older slot, e.g.
124 * if we previously crashed after dropping a slot.
126 memset(&shstatent->
stats, 0,
sizeof(shstatent->
stats));
132 * Report replication slot has been acquired.
134 * This guarantees that a stats entry exists during later
135 * pgstat_report_replslot() calls.
137 * If we previously crashed, no stats data exists. But if we did not crash,
138 * the stats do belong to this slot:
139 * - the stats cannot belong to a dropped slot, pgstat_drop_replslot() would
141 * - if the slot was removed while shut down,
142 * pgstat_replslot_from_serialized_name_cb() returning false would have
143 * caused the stats to be dropped
153 * Report replication slot drop.
166 * Support function for the SQL-callable pgstat* functions. Returns
167 * a pointer to the replication slot statistics struct.
192 * This is only called late during shutdown. The set of existing slots
193 * isn't allowed to change at this point, we can assume that a slot exists
197 elog(
ERROR,
"could not find name for replication slot index %" PRIu64,
206 /* slot might have been deleted */
Datum idx(PG_FUNCTION_ARGS)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Assert(PointerIsAligned(start, uint64))
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
void pgstat_reset(PgStat_Kind kind, Oid dboid, uint64 objid)
void * pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
#define PGSTAT_KIND_REPLSLOT
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)
#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)
int ReplicationSlotIndex(ReplicationSlot *slot)
ReplicationSlot * SearchNamedReplicationSlot(const char *name, bool need_lock)
bool ReplicationSlotName(int index, Name name)
#define SlotIsLogical(slot)
PgStat_StatReplSlotEntry stats
PgStatShared_Common * shared_stats