Re-introduce pgstat_drop_entry(), keeping ABI compatibility

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 850b9218c8.

Discussion: https://postgr.es/m/ajZz_sVJVX7pmPHo@alvherre.pgsql
Backpatch-through: 15-18
This commit is contained in:
Michael Paquier 2026-06-23 07:59:00 +09:00
parent 011eedcdc3
commit afb076b297
6 changed files with 25 additions and 22 deletions

View file

@ -18,15 +18,6 @@
# Be sure to replace "<ADD JUSTIFICATION HERE>" with details of your change and
# why it is deemed acceptable.
2e0c61aed6241bb66547bfab7467d43f889f78ba
#
# Fix PANIC with track_functions due to concurrent drop of pgstats entries
# 2026-06-18 11:49:36 +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).
586f4266fb4945f6ea3564b9c1bab093eb74bee4
#
# Fix ABI break by moving PROCSIG_SLOTSYNC_MESSAGE in ProcSignalReason

View file

@ -112,8 +112,8 @@ pgstat_init_function_usage(FunctionCallInfo fcinfo,
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"));
}

View file

@ -157,8 +157,8 @@ pgstat_drop_replslot(ReplicationSlot *slot)
{
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();
}

View file

@ -844,7 +844,7 @@ pgstat_free_entry(PgStatShared_HashEntry *shent, dshash_seq_status *hstat)
/*
* 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.
*/
@ -932,6 +932,17 @@ pgstat_drop_database_and_contents(Oid dboid)
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, Oid objoid)
{
return pgstat_drop_entry_ext(kind, dboid, objoid, false);
}
/*
* Drop a single stats entry.
*
@ -946,8 +957,8 @@ pgstat_drop_database_and_contents(Oid dboid)
* pgstat_gc_entry_refs().
*/
bool
pgstat_drop_entry(PgStat_Kind kind, Oid dboid, Oid objoid,
bool missing_ok)
pgstat_drop_entry_ext(PgStat_Kind kind, Oid dboid, Oid objoid,
bool missing_ok)
{
PgStat_HashKey key;
PgStatShared_HashEntry *shent;

View file

@ -84,7 +84,7 @@ AtEOXact_PgStat_DroppedStats(PgStat_SubXactStatus *xact_state, bool isCommit)
* Transaction that dropped an object committed. Drop the stats
* too.
*/
if (!pgstat_drop_entry(it->kind, it->dboid, it->objoid, true))
if (!pgstat_drop_entry_ext(it->kind, it->dboid, it->objoid, true))
not_freed_count++;
}
else if (!isCommit && pending->is_create)
@ -93,7 +93,7 @@ AtEOXact_PgStat_DroppedStats(PgStat_SubXactStatus *xact_state, bool isCommit)
* Transaction that created an object aborted. Drop the stats
* associated with the object.
*/
if (!pgstat_drop_entry(it->kind, it->dboid, it->objoid, true))
if (!pgstat_drop_entry_ext(it->kind, it->dboid, it->objoid, true))
not_freed_count++;
}
@ -158,7 +158,7 @@ AtEOSubXact_PgStat_DroppedStats(PgStat_SubXactStatus *xact_state,
* Subtransaction creating a new stats object aborted. Drop the
* stats object.
*/
if (!pgstat_drop_entry(it->kind, it->dboid, it->objoid, true))
if (!pgstat_drop_entry_ext(it->kind, it->dboid, it->objoid, true))
not_freed_count++;
pfree(pending);
}
@ -320,7 +320,7 @@ pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items,
{
xl_xact_stats_item *it = &items[i];
if (!pgstat_drop_entry(it->kind, it->dboid, it->objoid, true))
if (!pgstat_drop_entry_ext(it->kind, it->dboid, it->objoid, true))
not_freed_count++;
}

View file

@ -625,8 +625,9 @@ extern PgStat_EntryRef *pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, Oid ob
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, Oid objoid,
bool missing_ok);
extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, Oid objoid);
extern bool pgstat_drop_entry_ext(PgStat_Kind kind, Oid dboid, Oid objoid,
bool missing_ok);
extern void pgstat_drop_all_entries(void);
extern PgStat_EntryRef *pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, Oid objoid,
bool nowait);