mirror of
https://github.com/postgres/postgres.git
synced 2025-08-31 17:02:12 +03:00
Collect statistics about SLRU caches
There's a number of SLRU caches used to access important data like clog, commit timestamps, multixact, asynchronous notifications, etc. Until now we had no easy way to monitor these shared caches, compute hit ratios, number of reads/writes etc. This commit extends the statistics collector to track this information for a predefined list of SLRUs, and also introduces a new system view pg_stat_slru displaying the data. The list of built-in SLRUs is fixed, but additional SLRUs may be defined in extensions. Unfortunately, there's no suitable registry of SLRUs, so this patch simply defines a fixed list of SLRUs with entries for the built-in ones and one entry for all additional SLRUs. Extensions adding their own SLRU are fairly rare, so this seems acceptable. This patch only allows monitoring of SLRUs, not tuning. The SLRU sizes are still fixed (hard-coded in the code) and it's not entirely clear which of the SLRUs might need a GUC to tune size. In a way, allowing us to determine that is one of the goals of this patch. Bump catversion as the patch introduces new functions and system view. Author: Tomas Vondra Reviewed-by: Alvaro Herrera Discussion: https://www.postgresql.org/message-id/flat/20200119143707.gyinppnigokesjok@development
This commit is contained in:
@@ -1690,6 +1690,83 @@ pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_INT64(pgstat_fetch_global()->buf_alloc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns statistics of SLRU caches.
|
||||
*/
|
||||
Datum
|
||||
pg_stat_get_slru(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#define PG_STAT_GET_SLRU_COLS 9
|
||||
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
|
||||
TupleDesc tupdesc;
|
||||
Tuplestorestate *tupstore;
|
||||
MemoryContext per_query_ctx;
|
||||
MemoryContext oldcontext;
|
||||
int i;
|
||||
PgStat_SLRUStats *stats;
|
||||
|
||||
/* check to see if caller supports us returning a tuplestore */
|
||||
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("set-valued function called in context that cannot accept a set")));
|
||||
if (!(rsinfo->allowedModes & SFRM_Materialize))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("materialize mode required, but it is not allowed in this context")));
|
||||
|
||||
/* Build a tuple descriptor for our result type */
|
||||
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
||||
elog(ERROR, "return type must be a row type");
|
||||
|
||||
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
|
||||
oldcontext = MemoryContextSwitchTo(per_query_ctx);
|
||||
|
||||
tupstore = tuplestore_begin_heap(true, false, work_mem);
|
||||
rsinfo->returnMode = SFRM_Materialize;
|
||||
rsinfo->setResult = tupstore;
|
||||
rsinfo->setDesc = tupdesc;
|
||||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
/* request SLRU stats from the stat collector */
|
||||
stats = pgstat_fetch_slru();
|
||||
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
/* for each row */
|
||||
Datum values[PG_STAT_GET_SLRU_COLS];
|
||||
bool nulls[PG_STAT_GET_SLRU_COLS];
|
||||
PgStat_SLRUStats stat = stats[i];
|
||||
char *name;
|
||||
|
||||
name = pgstat_slru_name(i);
|
||||
|
||||
if (!name)
|
||||
break;
|
||||
|
||||
MemSet(values, 0, sizeof(values));
|
||||
MemSet(nulls, 0, sizeof(nulls));
|
||||
|
||||
values[0] = PointerGetDatum(cstring_to_text(name));
|
||||
values[1] = Int64GetDatum(stat.blocks_zeroed);
|
||||
values[2] = Int64GetDatum(stat.blocks_hit);
|
||||
values[3] = Int64GetDatum(stat.blocks_read);
|
||||
values[4] = Int64GetDatum(stat.blocks_written);
|
||||
values[5] = Int64GetDatum(stat.blocks_exists);
|
||||
values[6] = Int64GetDatum(stat.flush);
|
||||
values[7] = Int64GetDatum(stat.truncate);
|
||||
values[8] = Int64GetDatum(stat.stat_reset_timestamp);
|
||||
|
||||
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
|
||||
}
|
||||
|
||||
/* clean up and return the tuplestore */
|
||||
tuplestore_donestoring(tupstore);
|
||||
|
||||
return (Datum) 0;
|
||||
}
|
||||
|
||||
Datum
|
||||
pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
|
||||
{
|
||||
@@ -1935,6 +2012,20 @@ pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/* Reset SLRU counters (a specific one or all of them). */
|
||||
Datum
|
||||
pg_stat_reset_slru(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *target = NULL;
|
||||
|
||||
if (!PG_ARGISNULL(0))
|
||||
target = text_to_cstring(PG_GETARG_TEXT_PP(0));
|
||||
|
||||
pgstat_reset_slru_counter(target);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
Datum
|
||||
pg_stat_get_archiver(PG_FUNCTION_ARGS)
|
||||
{
|
||||
|
Reference in New Issue
Block a user