Skip to content

Commit 8fb580a

Browse files
committed
pgstat: prepare APIs used by pgstatfuncs for shared memory stats.
With the introduction of PgStat_Kind PgStat_Single_Reset_Type, PgStat_Shared_Reset_Target don't make sense anymore. Replace them with PgStat_Kind. Instead of having dedicated reset functions for different kinds of stats, use two generic helper routines (one to reset all stats of a kind, one to reset one stats entry). A number of reset functions were named pgstat_reset_*_counter(), despite affecting multiple counters. The generic helper routines get rid of pgstat_reset_single_counter(), pgstat_reset_subscription_counter(). Rename pgstat_reset_slru_counter(), pgstat_reset_replslot_counter() to pgstat_reset_slru(), pgstat_reset_replslot() respectively, and have them only deal with a single SLRU/slot. Resetting all SLRUs/slots goes through the generic pgstat_reset_of_kind(). Previously pg_stat_reset_replication_slot() used SearchNamedReplicationSlot() to check if a slot exists. API wise it seems better to move that to pgstat_replslot.c. This is done separately from the - quite large - shared memory statistics patch to make review easier. Reviewed-By: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Discussion: https://postgr.es/m/20220404041516.cctrvpadhuriawlq@alap3.anarazel.de
1 parent 997afad commit 8fb580a

File tree

7 files changed

+161
-131
lines changed

7 files changed

+161
-131
lines changed

src/backend/postmaster/pgstat.c

Lines changed: 92 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ static bool pgstat_write_statsfile_needed(void);
124124
static bool pgstat_db_requested(Oid databaseid);
125125

126126
static PgStat_StatReplSlotEntry *pgstat_get_replslot_entry(NameData name, bool create_it);
127-
static void pgstat_reset_replslot(PgStat_StatReplSlotEntry *slotstats, TimestampTz ts);
127+
static void pgstat_reset_replslot_entry(PgStat_StatReplSlotEntry *slotstats, TimestampTz ts);
128128

129129
static HTAB *pgstat_collect_oids(Oid catalogid, AttrNumber anum_oid);
130130

@@ -1084,55 +1084,110 @@ pgstat_reset_counters(void)
10841084
}
10851085

10861086
/*
1087-
* Reset a single counter.
1087+
* Reset a single variable-numbered entry.
1088+
*
1089+
* If the stats kind is within a database, also reset the database's
1090+
* stat_reset_timestamp.
10881091
*
10891092
* Permission checking for this function is managed through the normal
10901093
* GRANT system.
10911094
*/
10921095
void
1093-
pgstat_reset_single_counter(Oid objoid, PgStat_Single_Reset_Type type)
1096+
pgstat_reset(PgStat_Kind kind, Oid dboid, Oid objoid)
10941097
{
1095-
PgStat_MsgResetsinglecounter msg;
10961098

10971099
if (pgStatSock == PGINVALID_SOCKET)
10981100
return;
10991101

1100-
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSINGLECOUNTER);
1101-
msg.m_databaseid = MyDatabaseId;
1102-
msg.m_resettype = type;
1103-
msg.m_objectid = objoid;
1102+
switch (kind)
1103+
{
1104+
case PGSTAT_KIND_FUNCTION:
1105+
case PGSTAT_KIND_RELATION:
1106+
{
1107+
PgStat_MsgResetsinglecounter msg;
11041108

1105-
pgstat_send(&msg, sizeof(msg));
1109+
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSINGLECOUNTER);
1110+
msg.m_databaseid = dboid;
1111+
msg.m_resettype = kind;
1112+
msg.m_objectid = objoid;
1113+
pgstat_send(&msg, sizeof(msg));
1114+
}
1115+
break;
1116+
1117+
case PGSTAT_KIND_SUBSCRIPTION:
1118+
{
1119+
PgStat_MsgResetsubcounter msg;
1120+
1121+
Assert(dboid == InvalidOid);
1122+
msg.m_subid = objoid;
1123+
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSUBCOUNTER);
1124+
}
1125+
break;
1126+
1127+
default:
1128+
elog(ERROR, "unexpected");
1129+
}
11061130
}
11071131

11081132
/*
1109-
* Reset cluster-wide shared counters.
1133+
* Reset stats for all entries of a kind.
11101134
*
11111135
* Permission checking for this function is managed through the normal
11121136
* GRANT system.
11131137
*/
11141138
void
1115-
pgstat_reset_shared_counters(const char *target)
1139+
pgstat_reset_of_kind(PgStat_Kind kind)
11161140
{
1117-
PgStat_MsgResetsharedcounter msg;
1118-
11191141
if (pgStatSock == PGINVALID_SOCKET)
11201142
return;
11211143

1122-
if (strcmp(target, "archiver") == 0)
1123-
msg.m_resettarget = RESET_ARCHIVER;
1124-
else if (strcmp(target, "bgwriter") == 0)
1125-
msg.m_resettarget = RESET_BGWRITER;
1126-
else if (strcmp(target, "wal") == 0)
1127-
msg.m_resettarget = RESET_WAL;
1128-
else
1129-
ereport(ERROR,
1130-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1131-
errmsg("unrecognized reset target: \"%s\"", target),
1132-
errhint("Target must be \"archiver\", \"bgwriter\", or \"wal\".")));
1144+
switch (kind)
1145+
{
1146+
case PGSTAT_KIND_ARCHIVER:
1147+
case PGSTAT_KIND_BGWRITER:
1148+
case PGSTAT_KIND_CHECKPOINTER:
1149+
case PGSTAT_KIND_WAL:
1150+
{
1151+
PgStat_MsgResetsharedcounter msg;
11331152

1134-
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSHAREDCOUNTER);
1135-
pgstat_send(&msg, sizeof(msg));
1153+
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSHAREDCOUNTER);
1154+
msg.m_resettarget = kind;
1155+
pgstat_send(&msg, sizeof(msg));
1156+
}
1157+
break;
1158+
case PGSTAT_KIND_SLRU:
1159+
{
1160+
PgStat_MsgResetslrucounter msg;
1161+
1162+
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSLRUCOUNTER);
1163+
msg.m_index = -1;
1164+
pgstat_send(&msg, sizeof(msg));
1165+
}
1166+
break;
1167+
case PGSTAT_KIND_REPLSLOT:
1168+
{
1169+
PgStat_MsgResetreplslotcounter msg;
1170+
1171+
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETREPLSLOTCOUNTER);
1172+
msg.clearall = true;
1173+
pgstat_send(&msg, sizeof(msg));
1174+
}
1175+
break;
1176+
1177+
case PGSTAT_KIND_SUBSCRIPTION:
1178+
{
1179+
PgStat_MsgResetsubcounter msg;
1180+
1181+
msg.m_subid = InvalidOid;
1182+
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSUBCOUNTER);
1183+
1184+
pgstat_send(&msg, sizeof(msg));
1185+
}
1186+
break;
1187+
1188+
default:
1189+
elog(ERROR, "unexpected");
1190+
}
11361191
}
11371192

11381193
/*
@@ -1954,7 +2009,7 @@ pgstat_get_replslot_entry(NameData name, bool create)
19542009
if (create && !found)
19552010
{
19562011
namestrcpy(&(slotent->slotname), NameStr(name));
1957-
pgstat_reset_replslot(slotent, 0);
2012+
pgstat_reset_replslot_entry(slotent, 0);
19582013
}
19592014

19602015
return slotent;
@@ -1964,7 +2019,7 @@ pgstat_get_replslot_entry(NameData name, bool create)
19642019
* Reset the given replication slot stats.
19652020
*/
19662021
static void
1967-
pgstat_reset_replslot(PgStat_StatReplSlotEntry *slotent, TimestampTz ts)
2022+
pgstat_reset_replslot_entry(PgStat_StatReplSlotEntry *slotent, TimestampTz ts)
19682023
{
19692024
/* reset only counters. Don't clear slot name */
19702025
slotent->spill_txns = 0;
@@ -3528,7 +3583,8 @@ pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len)
35283583
static void
35293584
pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len)
35303585
{
3531-
if (msg->m_resettarget == RESET_BGWRITER)
3586+
if (msg->m_resettarget == PGSTAT_KIND_BGWRITER ||
3587+
msg->m_resettarget == PGSTAT_KIND_CHECKPOINTER)
35323588
{
35333589
/*
35343590
* Reset the global, bgwriter and checkpointer statistics for the
@@ -3537,13 +3593,13 @@ pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len)
35373593
memset(&globalStats, 0, sizeof(globalStats));
35383594
globalStats.bgwriter.stat_reset_timestamp = GetCurrentTimestamp();
35393595
}
3540-
else if (msg->m_resettarget == RESET_ARCHIVER)
3596+
else if (msg->m_resettarget == PGSTAT_KIND_ARCHIVER)
35413597
{
35423598
/* Reset the archiver statistics for the cluster. */
35433599
memset(&archiverStats, 0, sizeof(archiverStats));
35443600
archiverStats.stat_reset_timestamp = GetCurrentTimestamp();
35453601
}
3546-
else if (msg->m_resettarget == RESET_WAL)
3602+
else if (msg->m_resettarget == PGSTAT_KIND_WAL)
35473603
{
35483604
/* Reset the WAL statistics for the cluster. */
35493605
memset(&walStats, 0, sizeof(walStats));
@@ -3577,10 +3633,10 @@ pgstat_recv_resetsinglecounter(PgStat_MsgResetsinglecounter *msg, int len)
35773633
dbentry->stat_reset_timestamp = GetCurrentTimestamp();
35783634

35793635
/* Remove object if it exists, ignore it if not */
3580-
if (msg->m_resettype == RESET_TABLE)
3636+
if (msg->m_resettype == PGSTAT_KIND_RELATION)
35813637
(void) hash_search(dbentry->tables, (void *) &(msg->m_objectid),
35823638
HASH_REMOVE, NULL);
3583-
else if (msg->m_resettype == RESET_FUNCTION)
3639+
else if (msg->m_resettype == PGSTAT_KIND_FUNCTION)
35843640
(void) hash_search(dbentry->functions, (void *) &(msg->m_objectid),
35853641
HASH_REMOVE, NULL);
35863642
}
@@ -3626,7 +3682,7 @@ pgstat_recv_resetreplslotcounter(PgStat_MsgResetreplslotcounter *msg,
36263682

36273683
hash_seq_init(&sstat, replSlotStatHash);
36283684
while ((slotent = (PgStat_StatReplSlotEntry *) hash_seq_search(&sstat)) != NULL)
3629-
pgstat_reset_replslot(slotent, ts);
3685+
pgstat_reset_replslot_entry(slotent, ts);
36303686
}
36313687
else
36323688
{
@@ -3643,7 +3699,7 @@ pgstat_recv_resetreplslotcounter(PgStat_MsgResetreplslotcounter *msg,
36433699
return;
36443700

36453701
/* Reset the stats for the requested replication slot */
3646-
pgstat_reset_replslot(slotent, ts);
3702+
pgstat_reset_replslot_entry(slotent, ts);
36473703
}
36483704
}
36493705

@@ -3963,7 +4019,7 @@ pgstat_recv_replslot(PgStat_MsgReplSlot *msg, int len)
39634019
* lost, slotent has stats for the old slot. So we initialize all
39644020
* counters at slot creation.
39654021
*/
3966-
pgstat_reset_replslot(slotent, 0);
4022+
pgstat_reset_replslot_entry(slotent, 0);
39674023
}
39684024
else
39694025
{

src/backend/utils/activity/pgstat_replslot.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,45 @@
2323

2424

2525
/*
26-
* Reset counters for a single replication slot, or all replication slots
27-
* (when name is null).
26+
* Reset counters for a single replication slot.
2827
*
2928
* Permission checking for this function is managed through the normal
3029
* GRANT system.
3130
*/
3231
void
33-
pgstat_reset_replslot_counter(const char *name)
32+
pgstat_reset_replslot(const char *name)
3433
{
34+
ReplicationSlot *slot;
3535
PgStat_MsgResetreplslotcounter msg;
3636

37+
AssertArg(name != NULL);
38+
3739
if (pgStatSock == PGINVALID_SOCKET)
3840
return;
3941

40-
if (name)
41-
{
42-
namestrcpy(&msg.m_slotname, name);
43-
msg.clearall = false;
44-
}
45-
else
46-
msg.clearall = true;
42+
/*
43+
* Check if the slot exists with the given name. It is possible that by
44+
* the time this message is executed the slot is dropped but at least this
45+
* check will ensure that the given name is for a valid slot.
46+
*/
47+
slot = SearchNamedReplicationSlot(name, true);
4748

48-
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETREPLSLOTCOUNTER);
49+
if (!slot)
50+
ereport(ERROR,
51+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
52+
errmsg("replication slot \"%s\" does not exist",
53+
name)));
4954

55+
/*
56+
* Nothing to do for physical slots as we collect stats only for logical
57+
* slots.
58+
*/
59+
if (SlotIsPhysical(slot))
60+
return;
61+
62+
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETREPLSLOTCOUNTER);
63+
namestrcpy(&msg.m_slotname, name);
64+
msg.clearall = false;
5065
pgstat_send(&msg, sizeof(msg));
5166
}
5267

src/backend/utils/activity/pgstat_slru.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,23 @@ static PgStat_MsgSLRU SLRUStats[SLRU_NUM_ELEMENTS];
3333

3434

3535
/*
36-
* Reset counters for a single SLRU, or all SLRUs (when name is null).
36+
* Reset counters for a single SLRU.
3737
*
3838
* Permission checking for this function is managed through the normal
3939
* GRANT system.
4040
*/
4141
void
42-
pgstat_reset_slru_counter(const char *name)
42+
pgstat_reset_slru(const char *name)
4343
{
4444
PgStat_MsgResetslrucounter msg;
4545

46+
AssertArg(name != NULL);
47+
4648
if (pgStatSock == PGINVALID_SOCKET)
4749
return;
4850

4951
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSLRUCOUNTER);
50-
msg.m_index = (name) ? pgstat_slru_index(name) : -1;
52+
msg.m_index = pgstat_slru_index(name);
5153

5254
pgstat_send(&msg, sizeof(msg));
5355
}

src/backend/utils/activity/pgstat_subscription.c

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,6 @@
2020
#include "utils/pgstat_internal.h"
2121

2222

23-
/*
24-
* Reset counters for a single subscription, or all subscriptions (when subid
25-
* is InvalidOid).
26-
*
27-
* Permission checking for this function is managed through the normal
28-
* GRANT system.
29-
*/
30-
void
31-
pgstat_reset_subscription_counter(Oid subid)
32-
{
33-
PgStat_MsgResetsubcounter msg;
34-
35-
if (pgStatSock == PGINVALID_SOCKET)
36-
return;
37-
38-
msg.m_subid = subid;
39-
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSUBCOUNTER);
40-
41-
pgstat_send(&msg, sizeof(msg));
42-
}
43-
4423
/*
4524
* Report a subscription error.
4625
*/

0 commit comments

Comments
 (0)