Add pgstat_drop_matching_entries() to pgstats
authorMichael Paquier <michael@paquier.xyz>
Fri, 31 Jan 2025 03:27:19 +0000 (12:27 +0900)
committerMichael Paquier <michael@paquier.xyz>
Fri, 31 Jan 2025 03:27:19 +0000 (12:27 +0900)
This allows users of the cumulative statistics to drop entries in the
shared hash stats table, deleting as well local references.  Callers of
this function can optionally define a callback able to filter which
entries to drop, similarly to pgstat_reset_matching_entries() with its
callback do_reset().

pgstat_drop_all_entries() is refactored so as it uses this new function.

Author: Lukas Fitti
Discussion: https://postgr.es/m/CAP53PkwuFbo3NkwZgxwNRMjMfqPEqidD-SggaoQ4ijotBVLJAA@mail.gmail.com

src/backend/utils/activity/pgstat_shmem.c
src/include/utils/pgstat_internal.h

index 342586397d66969b5b388d0744c205fa9b11f2a8..770d62425c5dc65ecb883b1e59cec87c076cead3 100644 (file)
@@ -993,19 +993,39 @@ pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
    return freed;
 }
 
+/*
+ * Scan through the shared hashtable of stats, dropping statistics if
+ * approved by the optional do_drop() function.
+ */
 void
-pgstat_drop_all_entries(void)
+pgstat_drop_matching_entries(bool (*do_drop) (PgStatShared_HashEntry *, Datum),
+                            Datum match_data)
 {
    dshash_seq_status hstat;
    PgStatShared_HashEntry *ps;
    uint64      not_freed_count = 0;
 
+   /* entries are removed, take an exclusive lock */
    dshash_seq_init(&hstat, pgStatLocal.shared_hash, true);
    while ((ps = dshash_seq_next(&hstat)) != NULL)
    {
        if (ps->dropped)
            continue;
 
+       if (do_drop != NULL && !do_drop(ps, match_data))
+           continue;
+
+       /* delete local reference */
+       if (pgStatEntryRefHash)
+       {
+           PgStat_EntryRefHashEntry *lohashent =
+               pgstat_entry_ref_hash_lookup(pgStatEntryRefHash, ps->key);
+
+           if (lohashent)
+               pgstat_release_entry_ref(lohashent->key, lohashent->entry_ref,
+                                        true);
+       }
+
        if (!pgstat_drop_entry_internal(ps, &hstat))
            not_freed_count++;
    }
@@ -1015,6 +1035,15 @@ pgstat_drop_all_entries(void)
        pgstat_request_entry_refs_gc();
 }
 
+/*
+ * Scan through the shared hashtable of stats and drop all entries.
+ */
+void
+pgstat_drop_all_entries(void)
+{
+   pgstat_drop_matching_entries(NULL, 0);
+}
+
 static void
 shared_stat_reset_contents(PgStat_Kind kind, PgStatShared_Common *header,
                           TimestampTz ts)
index a3d39d2b725d09470ed13c4273f931e2a6cac908..06dcea3f0dcf8d918f0c652e950d02a67c5b8ca9 100644 (file)
@@ -718,6 +718,8 @@ extern bool pgstat_lock_entry_shared(PgStat_EntryRef *entry_ref, bool nowait);
 extern void pgstat_unlock_entry(PgStat_EntryRef *entry_ref);
 extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid);
 extern void pgstat_drop_all_entries(void);
+extern void pgstat_drop_matching_entries(bool (*do_drop) (PgStatShared_HashEntry *, Datum),
+                                        Datum match_data);
 extern PgStat_EntryRef *pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, uint64 objid,
                                                    bool nowait);
 extern void pgstat_reset_entry(PgStat_Kind kind, Oid dboid, uint64 objid, TimestampTz ts);