From 09ecf3b99e4779136b0c060c56ef4a126cb7dc51 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 2 Apr 2022 15:36:30 -0700
Subject: [PATCH v68 11/31] pgstat: revise replslot API in preparation for
 shared memory stats.

---
 src/include/pgstat.h                         |  5 +++--
 src/include/replication/slot.h               |  1 +
 src/backend/replication/logical/logical.c    |  2 +-
 src/backend/replication/slot.c               | 15 ++++++++++++++-
 src/backend/utils/activity/pgstat_replslot.c |  9 ++++++---
 5 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 4e0692d8b2b..7d8cea48efa 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -1150,8 +1150,9 @@ extern PgStat_TableStatus *find_tabstat_entry(Oid rel_id);
 
 extern void pgstat_reset_replslot_counters(void);
 extern void pgstat_reset_replslot_counter(const char *name);
-extern void pgstat_report_replslot(const PgStat_StatReplSlotEntry *repSlotStat);
-extern void pgstat_create_replslot(const char *slotname);
+struct ReplicationSlot;
+extern void pgstat_report_replslot(struct ReplicationSlot *slot, const PgStat_StatReplSlotEntry *repSlotStat);
+extern void pgstat_create_replslot(struct ReplicationSlot *slot);
 extern void pgstat_drop_replslot(const char *slotname);
 
 
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index 24b30210c3e..1ee63c4cf44 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -216,6 +216,7 @@ extern bool ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive);
 extern void ReplicationSlotsDropDBSlots(Oid dboid);
 extern bool InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno);
 extern ReplicationSlot *SearchNamedReplicationSlot(const char *name, bool need_lock);
+extern int ReplicationSlotIndex(ReplicationSlot *slot);
 extern void ReplicationSlotNameForTablesync(Oid suboid, Oid relid, char *syncslotname, int szslot);
 extern void ReplicationSlotDropAtPubNode(WalReceiverConn *wrconn, char *slotname, bool missing_ok);
 
diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c
index e1f14aeecb5..656ec8f5555 100644
--- a/src/backend/replication/logical/logical.c
+++ b/src/backend/replication/logical/logical.c
@@ -1921,7 +1921,7 @@ UpdateDecodingStats(LogicalDecodingContext *ctx)
 	repSlotStat.total_txns = rb->totalTxns;
 	repSlotStat.total_bytes = rb->totalBytes;
 
-	pgstat_report_replslot(&repSlotStat);
+	pgstat_report_replslot(ctx->slot, &repSlotStat);
 
 	rb->spillTxns = 0;
 	rb->spillCount = 0;
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index b02571e4dd8..5d3b3fe6db6 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -356,7 +356,7 @@ ReplicationSlotCreate(const char *name, bool db_specific,
 	 * ReplicationSlotAllocationLock.
 	 */
 	if (SlotIsLogical(slot))
-		pgstat_create_replslot(NameStr(slot->data.name));
+		pgstat_create_replslot(slot);
 
 	/*
 	 * Now that the slot has been marked as in_use and active, it's safe to
@@ -399,6 +399,19 @@ SearchNamedReplicationSlot(const char *name, bool need_lock)
 	return slot;
 }
 
+/*
+ * Return the index of the replication slot in
+ * ReplicationSlotCtl->replication_slots.
+ *
+ * This is mainly useful to have an efficient key for storing replication slot
+ * stats.
+ */
+int
+ReplicationSlotIndex(ReplicationSlot *slot)
+{
+	return slot - ReplicationSlotCtl->replication_slots;
+}
+
 /*
  * Find a previously created slot and mark it as used by this process.
  *
diff --git a/src/backend/utils/activity/pgstat_replslot.c b/src/backend/utils/activity/pgstat_replslot.c
index 8d64ecd8aaf..b1e894f2b21 100644
--- a/src/backend/utils/activity/pgstat_replslot.c
+++ b/src/backend/utils/activity/pgstat_replslot.c
@@ -85,7 +85,7 @@ pgstat_reset_replslot_counter(const char *name)
  * Report replication slot statistics.
  */
 void
-pgstat_report_replslot(const PgStat_StatReplSlotEntry *repSlotStat)
+pgstat_report_replslot(ReplicationSlot *slot, const PgStat_StatReplSlotEntry *repSlotStat)
 {
 	PgStat_MsgReplSlot msg;
 
@@ -109,14 +109,17 @@ pgstat_report_replslot(const PgStat_StatReplSlotEntry *repSlotStat)
 
 /*
  * Report replication slot creation.
+ *
+ * NB: This gets called with ReplicationSlotAllocationLock already held, be
+ * careful about calling back into slot.c.
  */
 void
-pgstat_create_replslot(const char *slotname)
+pgstat_create_replslot(ReplicationSlot *slot)
 {
 	PgStat_MsgReplSlot msg;
 
 	pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_REPLSLOT);
-	namestrcpy(&msg.m_slotname, slotname);
+	namestrcpy(&msg.m_slotname, NameStr(slot->data.name));
 	msg.m_create = true;
 	msg.m_drop = false;
 	pgstat_send(&msg, sizeof(PgStat_MsgReplSlot));
-- 
2.35.1.677.gabf474a5dd

