21#define NUM_BUFFERCACHE_PAGES_MIN_ELEM 8
22#define NUM_BUFFERCACHE_PAGES_ELEM 9
23#define NUM_BUFFERCACHE_SUMMARY_ELEM 5
24#define NUM_BUFFERCACHE_USAGE_COUNTS_ELEM 4
25#define NUM_BUFFERCACHE_EVICT_ELEM 2
26#define NUM_BUFFERCACHE_EVICT_RELATION_ELEM 3
27#define NUM_BUFFERCACHE_EVICT_ALL_ELEM 3
29#define NUM_BUFFERCACHE_OS_PAGES_ELEM 3
32 .
name =
"pg_buffercache",
142 elog(
ERROR,
"return type must be a row type");
146 elog(
ERROR,
"incorrect number of output arguments");
327 int pages_per_buffer;
328 int *os_page_status = NULL;
336 elog(
ERROR,
"libnuma initialization failed or NUMA is not supported on this platform");
361 Assert((os_page_size % BLCKSZ == 0) || (BLCKSZ % os_page_size == 0));
365 void **os_page_ptrs = NULL;
374 endptr = (
char *)
TYPEALIGN(os_page_size,
376 os_page_count = (endptr - startptr) / os_page_size;
379 os_page_ptrs =
palloc0(
sizeof(
void *) * os_page_count);
380 os_page_status =
palloc(
sizeof(
uint64) * os_page_count);
389 for (
char *ptr = startptr; ptr < endptr; ptr += os_page_size)
391 os_page_ptrs[
idx++] = ptr;
401 "os_page_size=%zu",
NBuffers, os_page_count, os_page_size);
407 memset(os_page_status, 0xff,
sizeof(
int) * os_page_count);
411 elog(
ERROR,
"failed NUMA pages inquiry: %m");
425 elog(
ERROR,
"return type must be a row type");
428 elog(
ERROR,
"incorrect number of output arguments");
449 pages_per_buffer =
Max(1, BLCKSZ / os_page_size) + 1;
450 max_entries =
NBuffers * pages_per_buffer;
461 elog(
DEBUG1,
"NUMA: page-faulting the buffercache for proper NUMA readouts");
495 endptr_buff = buffptr + BLCKSZ;
497 Assert(startptr_buff < endptr_buff);
500 page_num = (startptr_buff - startptr) / os_page_size;
503 for (
char *ptr = startptr_buff; ptr < endptr_buff; ptr += os_page_size)
600 int32 buffers_used = 0;
601 int32 buffers_unused = 0;
602 int32 buffers_dirty = 0;
603 int32 buffers_pinned = 0;
604 int64 usagecount_total = 0;
607 elog(
ERROR,
"return type must be a row type");
640 memset(nulls, 0,
sizeof(nulls));
646 if (buffers_used != 0)
679 usage_counts[usage_count]++;
682 dirty[usage_count]++;
685 pinned[usage_count]++;
709 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
710 errmsg(
"must be superuser to use %s()",
730 elog(
ERROR,
"return type must be a row type");
761 int32 buffers_evicted = 0;
762 int32 buffers_flushed = 0;
763 int32 buffers_skipped = 0;
766 elog(
ERROR,
"return type must be a row type");
776 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
777 errmsg(
"relation uses local buffers, %s() is intended to be used for shared buffers only",
778 "pg_buffercache_evict_relation")));
808 int32 buffers_evicted = 0;
809 int32 buffers_flushed = 0;
810 int32 buffers_skipped = 0;
813 elog(
ERROR,
"return type must be a row type");
Datum idx(PG_FUNCTION_ARGS)
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
#define InvalidBlockNumber
static Datum values[MAXATTR]
#define BM_MAX_USAGE_COUNT
static ForkNumber BufTagGetForkNum(const BufferTag *tag)
static RelFileNumber BufTagGetRelNumber(const BufferTag *tag)
static void UnlockBufHdr(BufferDesc *desc)
#define BUF_STATE_GET_USAGECOUNT(state)
#define BUF_STATE_GET_REFCOUNT(state)
static BufferDesc * GetBufferDescriptor(uint32 id)
static Buffer BufferDescriptorGetBuffer(const BufferDesc *bdesc)
void EvictAllUnpinnedBuffers(int32 *buffers_evicted, int32 *buffers_flushed, int32 *buffers_skipped)
void EvictRelUnpinnedBuffers(Relation rel, int32 *buffers_evicted, int32 *buffers_flushed, int32 *buffers_skipped)
bool EvictUnpinnedBuffer(Buffer buf, bool *buffer_flushed)
uint32 LockBufHdr(BufferDesc *desc)
static Block BufferGetBlock(Buffer buffer)
#define TYPEALIGN(ALIGNVAL, LEN)
#define TYPEALIGN_DOWN(ALIGNVAL, LEN)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
#define PG_GETARG_INT32(n)
#define PG_GETARG_BOOL(n)
#define PG_RETURN_DATUM(x)
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
#define SRF_IS_FIRSTCALL()
#define SRF_PERCALL_SETUP()
#define SRF_RETURN_NEXT(_funcctx, _result)
#define SRF_FIRSTCALL_INIT()
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
#define SRF_RETURN_DONE(_funcctx)
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void * MemoryContextAllocHuge(MemoryContext context, Size size)
#define CHECK_FOR_INTERRUPTS()
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Datum pg_buffercache_os_pages(PG_FUNCTION_ARGS)
PG_MODULE_MAGIC_EXT(.name="pg_buffercache",.version=PG_VERSION)
Datum pg_buffercache_evict_relation(PG_FUNCTION_ARGS)
#define NUM_BUFFERCACHE_USAGE_COUNTS_ELEM
#define NUM_BUFFERCACHE_OS_PAGES_ELEM
Datum pg_buffercache_evict(PG_FUNCTION_ARGS)
Datum pg_buffercache_summary(PG_FUNCTION_ARGS)
static void pg_buffercache_superuser_check(char *func_name)
PG_FUNCTION_INFO_V1(pg_buffercache_pages)
Datum pg_buffercache_usage_counts(PG_FUNCTION_ARGS)
#define NUM_BUFFERCACHE_SUMMARY_ELEM
Datum pg_buffercache_pages(PG_FUNCTION_ARGS)
#define NUM_BUFFERCACHE_EVICT_ELEM
#define NUM_BUFFERCACHE_PAGES_MIN_ELEM
#define NUM_BUFFERCACHE_EVICT_ALL_ELEM
Datum pg_buffercache_evict_all(PG_FUNCTION_ARGS)
#define NUM_BUFFERCACHE_PAGES_ELEM
Datum pg_buffercache_numa_pages(PG_FUNCTION_ARGS)
static bool firstNumaTouch
static Datum pg_buffercache_os_pages_internal(FunctionCallInfo fcinfo, bool include_numa)
#define NUM_BUFFERCACHE_EVICT_RELATION_ELEM
#define pg_numa_touch_mem_if_required(ptr)
PGDLLIMPORT int pg_numa_query_pages(int pid, unsigned long count, void **pages, int *status)
PGDLLIMPORT int pg_numa_init(void)
static Datum Int64GetDatum(int64 X)
static Datum Int16GetDatum(int16 X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum Float8GetDatum(float8 X)
static Datum Int32GetDatum(int32 X)
#define RelationUsesLocalBuffers(relation)
Size pg_get_shmem_pagesize(void)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
BufferCacheOsPagesRec * record
BufferCachePagesRec * record
RelFileNumber relfilenumber
MemoryContext multi_call_memory_ctx
TupleDesc CreateTemplateTupleDesc(int natts)
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)