mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Add new pgstats routine to split pending data setup
This commit adds pgstat_prep_pending_from_entry_ref(), a new pgstats routine that is able to prepare an existing PgStat_EntryRef to receive pending stats. This split gives a way for callers to obtain first a reference via pgstat_get_entry_ref(), then set up pending data as two separate, distinctive, steps. Previously, the only way to get an entry reference with pending data ready was pgstat_prep_pending_entry(), which bundles lookup, creation, and pending setup in a single call. Callers that need finer control over the entry creation had no way to attach pending data to an already-obtained entry reference. One case where this has shown to matter for a stats kind is where one wants to check some capacity (for example where a GUC bounds the maximum numer of entries allowed) before deciding if a new entry should be created. So this split can help in reducing calls to pgstat_get_entry_ref(), meaning less shmem hash table lookups. The only logical ordering change is that pgStatPendingContext is initialized after calling pgstat_get_entry_ref() in pgstat_prep_pending_entry(). This does not matter in practice. pgstat_prep_pending_entry() is refactored to use the new function internally. All the existing callers are unchanged. Existing out-of-core custom stats kinds should see no impact. Author: Sami Imseih <samimseih@gmail.com> Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/CAA5RZ0sV+TsLejUMhAM=PJoOm8u-t8ru7B67KvyLCy=19sM87g@mail.gmail.com
This commit is contained in:
@@ -1311,29 +1311,10 @@ pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, uint64 objid, bool *creat
|
||||
{
|
||||
PgStat_EntryRef *entry_ref;
|
||||
|
||||
/* need to be able to flush out */
|
||||
Assert(pgstat_get_kind_info(kind)->flush_pending_cb != NULL);
|
||||
|
||||
if (unlikely(!pgStatPendingContext))
|
||||
{
|
||||
pgStatPendingContext =
|
||||
AllocSetContextCreate(TopMemoryContext,
|
||||
"PgStat Pending",
|
||||
ALLOCSET_SMALL_SIZES);
|
||||
}
|
||||
|
||||
entry_ref = pgstat_get_entry_ref(kind, dboid, objid,
|
||||
true, created_entry);
|
||||
|
||||
if (entry_ref->pending == NULL)
|
||||
{
|
||||
size_t entrysize = pgstat_get_kind_info(kind)->pending_size;
|
||||
|
||||
Assert(entrysize != (size_t) -1);
|
||||
|
||||
entry_ref->pending = MemoryContextAllocZero(pgStatPendingContext, entrysize);
|
||||
dlist_push_tail(&pgStatPending, &entry_ref->pending_node);
|
||||
}
|
||||
pgstat_prep_pending_from_entry_ref(entry_ref);
|
||||
|
||||
return entry_ref;
|
||||
}
|
||||
@@ -1377,6 +1358,40 @@ pgstat_delete_pending_entry(PgStat_EntryRef *entry_ref)
|
||||
dlist_delete(&entry_ref->pending_node);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare the given entry to receive pending stats, if not already done.
|
||||
*/
|
||||
void
|
||||
pgstat_prep_pending_from_entry_ref(PgStat_EntryRef *entry_ref)
|
||||
{
|
||||
PgStat_Kind kind;
|
||||
|
||||
Assert(entry_ref != NULL);
|
||||
|
||||
kind = entry_ref->shared_entry->key.kind;
|
||||
|
||||
/* need to be able to flush out */
|
||||
Assert(pgstat_get_kind_info(kind)->flush_pending_cb != NULL);
|
||||
|
||||
if (entry_ref->pending == NULL)
|
||||
{
|
||||
size_t entrysize = pgstat_get_kind_info(kind)->pending_size;
|
||||
|
||||
Assert(entrysize != (size_t) -1);
|
||||
|
||||
if (unlikely(!pgStatPendingContext))
|
||||
{
|
||||
pgStatPendingContext =
|
||||
AllocSetContextCreate(TopMemoryContext,
|
||||
"PgStat Pending",
|
||||
ALLOCSET_SMALL_SIZES);
|
||||
}
|
||||
|
||||
entry_ref->pending = MemoryContextAllocZero(pgStatPendingContext, entrysize);
|
||||
dlist_push_tail(&pgStatPending, &entry_ref->pending_node);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush out pending variable-numbered stats.
|
||||
*/
|
||||
|
||||
@@ -680,6 +680,7 @@ extern void pgstat_assert_is_up(void);
|
||||
#endif
|
||||
|
||||
extern void pgstat_delete_pending_entry(PgStat_EntryRef *entry_ref);
|
||||
extern void pgstat_prep_pending_from_entry_ref(PgStat_EntryRef *entry_ref);
|
||||
extern PgStat_EntryRef *pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid,
|
||||
uint64 objid,
|
||||
bool *created_entry);
|
||||
|
||||
Reference in New Issue
Block a user