This routine acts as a wrapper of a new pgstat_drop_entry_ext(), used in
the core code with a missing_ok argument.
This includes an update of .abi-compliance-history, removing the latest
entry that has documented the change of pgstat_drop_entry(). This
change is applied across v15~v18. HEAD keeps pgstat_drop_entry() as
single entry point, with the new missing_ok.
Per discussion with Álvaro Herrera and Lukas Fittl. This is a follow-up
of
850b9218c8e4.
Discussion: https://postgr.es/m/ajZz_sVJVX7pmPHo@alvherre.pgsql
Backpatch-through: 15-18
# Be sure to replace "<ADD JUSTIFICATION HERE>" with details of your change and
# why it is deemed acceptable.
-5cc59834b860ed48d710c1baa9c50c66540c64d0
-#
-# Fix PANIC with track_functions due to concurrent drop of pgstats entries
-# 2026-06-18 11:49:34 +0900
-#
-# This commit has added a "missing_ok" argument to pgstat_drop_entry(). All
-# the callers of this routine are in core for v15-v17. One custom stats kinds
-# available in the public since v18 is impacted (maintainer informed).
-
8d9a97e0bb6d820dac553848f0d5d8cc3f3e219d
#
# Avoid name collision with NOT NULL constraints
dlist_init(&pgStatPending);
/* drop the backend stats entry */
- if (!pgstat_drop_entry(PGSTAT_KIND_BACKEND, InvalidOid, MyProcNumber, false))
+ if (!pgstat_drop_entry_ext(PGSTAT_KIND_BACKEND, InvalidOid, MyProcNumber, false))
pgstat_request_entry_refs_gc();
pgstat_detach_shmem();
AcceptInvalidationMessages();
if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(fcinfo->flinfo->fn_oid)))
{
- pgstat_drop_entry(PGSTAT_KIND_FUNCTION, MyDatabaseId,
- fcinfo->flinfo->fn_oid, true);
+ pgstat_drop_entry_ext(PGSTAT_KIND_FUNCTION, MyDatabaseId,
+ fcinfo->flinfo->fn_oid, true);
ereport(ERROR, errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function call to dropped function"));
}
{
Assert(LWLockHeldByMeInMode(ReplicationSlotAllocationLock, LW_EXCLUSIVE));
- if (!pgstat_drop_entry(PGSTAT_KIND_REPLSLOT, InvalidOid,
- ReplicationSlotIndex(slot), false))
+ if (!pgstat_drop_entry_ext(PGSTAT_KIND_REPLSLOT, InvalidOid,
+ ReplicationSlotIndex(slot), false))
pgstat_request_entry_refs_gc();
}
/*
* Helper for both pgstat_drop_database_and_contents() and
- * pgstat_drop_entry(). If hstat is non-null delete the shared entry using
+ * pgstat_drop_entry_ext(). If hstat is non-null delete the shared entry using
* dshash_delete_current(), otherwise use dshash_delete_entry(). In either
* case the entry needs to be already locked.
*/
pgstat_request_entry_refs_gc();
}
+/*
+ * ABI-preserving wrapper around pgstat_drop_entry_ext().
+ *
+ * The original routine introduced in v15 did not include "missing_ok".
+ */
+bool
+pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
+{
+ return pgstat_drop_entry_ext(kind, dboid, objid, false);
+}
+
/*
* Drop a single stats entry.
*
* pgstat_gc_entry_refs().
*/
bool
-pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid,
- bool missing_ok)
+pgstat_drop_entry_ext(PgStat_Kind kind, Oid dboid, uint64 objid,
+ bool missing_ok)
{
PgStat_HashKey key;
PgStatShared_HashEntry *shent;
* Transaction that dropped an object committed. Drop the stats
* too.
*/
- if (!pgstat_drop_entry(it->kind, it->dboid, objid, true))
+ if (!pgstat_drop_entry_ext(it->kind, it->dboid, objid, true))
not_freed_count++;
}
else if (!isCommit && pending->is_create)
* Transaction that created an object aborted. Drop the stats
* associated with the object.
*/
- if (!pgstat_drop_entry(it->kind, it->dboid, objid, true))
+ if (!pgstat_drop_entry_ext(it->kind, it->dboid, objid, true))
not_freed_count++;
}
* Subtransaction creating a new stats object aborted. Drop the
* stats object.
*/
- if (!pgstat_drop_entry(it->kind, it->dboid, objid, true))
+ if (!pgstat_drop_entry_ext(it->kind, it->dboid, objid, true))
not_freed_count++;
pfree(pending);
}
xl_xact_stats_item *it = &items[i];
uint64 objid = ((uint64) it->objid_hi) << 32 | it->objid_lo;
- if (!pgstat_drop_entry(it->kind, it->dboid, objid, true))
+ if (!pgstat_drop_entry_ext(it->kind, it->dboid, objid, true))
not_freed_count++;
}
extern bool pgstat_lock_entry(PgStat_EntryRef *entry_ref, bool nowait);
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,
- bool missing_ok);
+extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid);
+extern bool pgstat_drop_entry_ext(PgStat_Kind kind, Oid dboid, uint64 objid,
+ bool missing_ok);
extern void pgstat_drop_all_entries(void);
extern void pgstat_drop_matching_entries(bool (*do_drop) (PgStatShared_HashEntry *, Datum),
Datum match_data);
if (!inj_stats_loaded || !inj_stats_enabled)
return;
- if (!pgstat_drop_entry(PGSTAT_KIND_INJECTION, InvalidOid,
- PGSTAT_INJ_IDX(name), false))
+ if (!pgstat_drop_entry_ext(PGSTAT_KIND_INJECTION, InvalidOid,
+ PGSTAT_INJ_IDX(name), false))
pgstat_request_entry_refs_gc();
}