Compare commits

...

6 Commits

Author SHA1 Message Date
BodoBolero
e808179cb2 allow all users in role pg_monitor to monitor their LFC working set 2024-02-26 15:01:50 +01:00
Konstantin Knizhnik
cf73c3c79e Remove unneded header include 2023-04-05 21:47:15 +03:00
Konstantin Knizhnik
31950850c4 Use stadnard Postgres HyperLogLog algorithm for estimation of working set size 2023-03-31 19:52:09 +03:00
Konstantin Knizhnik
77d113518c Fix pow_2_32 defintion 2023-03-31 17:14:24 +03:00
Konstantin Knizhnik
cb9ac4ccca Use standard Postgres hash function for HyperLogLog 2023-03-31 10:01:26 +03:00
Konstantin Knizhnik
bf9de03865 Calculate approximate number of accessed unique pages to estimate woring set size at compute 2023-03-30 16:55:39 +03:00
4 changed files with 46 additions and 5 deletions

View File

@@ -24,6 +24,8 @@
#include "pgstat.h"
#include "pagestore_client.h"
#include "access/parallel.h"
#include "common/hashfn.h"
#include "lib/hyperloglog.h"
#include "postmaster/bgworker.h"
#include "storage/relfilenode.h"
#include "storage/buf_internals.h"
@@ -65,6 +67,7 @@
#define MAX_MONITOR_INTERVAL_USEC 1000000 /* 1 second */
#define MAX_DISK_WRITE_RATE 1000 /* MB/sec */
#define HYPER_LOG_LOG_BIT_WIDTH 10
typedef struct FileCacheEntry
{
@@ -77,9 +80,11 @@ typedef struct FileCacheEntry
typedef struct FileCacheControl
{
uint32 size; /* size of cache file in chunks */
uint32 used; /* number of used chunks */
dlist_head lru; /* double linked list for LRU replacement algorithm */
uint32 size; /* size of cache file in chunks */
uint32 used; /* number of used chunks */
dlist_head lru; /* double linked list for LRU replacement algorithm */
hyperLogLogState wss_estimation; /* estimation of wroking set size */
char hyperloglog_hashes[(1 << HYPER_LOG_LOG_BIT_WIDTH) + 1];
} FileCacheControl;
static HTAB* lfc_hash;
@@ -124,6 +129,12 @@ lfc_shmem_startup(void)
lfc_ctl->size = 0;
lfc_ctl->used = 0;
dlist_init(&lfc_ctl->lru);
initHyperLogLog(&lfc_ctl->wss_estimation, HYPER_LOG_LOG_BIT_WIDTH);
/* We need hashes in shared memory */
pfree(lfc_ctl->wss_estimation.hashesArr);
memset(lfc_ctl->hyperloglog_hashes, 0, sizeof lfc_ctl->hyperloglog_hashes);
lfc_ctl->wss_estimation.hashesArr = lfc_ctl->hyperloglog_hashes;
/* Remove file cache on restart */
(void)unlink(lfc_path);
@@ -396,6 +407,11 @@ lfc_read(RelFileNode rnode, ForkNumber forkNum, BlockNumber blkno,
LWLockAcquire(lfc_lock, LW_EXCLUSIVE);
entry = hash_search_with_hash_value(lfc_hash, &tag, hash, HASH_FIND, NULL);
/* Approximate working set */
tag.blockNum = blkno;
addHyperLogLog(&lfc_ctl->wss_estimation, hash_bytes((char const*)&tag, sizeof(tag)));
if (entry == NULL || (entry->bitmap[chunk_offs >> 5] & (1 << (chunk_offs & 31))) == 0)
{
/* Page is not cached */
@@ -698,3 +714,21 @@ local_cache_pages(PG_FUNCTION_ARGS)
else
SRF_RETURN_DONE(funcctx);
}
PG_FUNCTION_INFO_V1(approximate_working_set_size);
Datum
approximate_working_set_size(PG_FUNCTION_ARGS)
{
int32 dc = -1;
if (lfc_size_limit != 0)
{
bool reset = PG_GETARG_BOOL(0);
LWLockAcquire(lfc_lock, reset ? LW_EXCLUSIVE : LW_SHARED);
dc = (int32) estimateHyperLogLog(&lfc_ctl->wss_estimation);
if (reset)
memset(lfc_ctl->hyperloglog_hashes, 0, sizeof lfc_ctl->hyperloglog_hashes);
LWLockRelease(lfc_lock);
}
PG_RETURN_INT32(dc);
}

View File

@@ -27,6 +27,13 @@ RETURNS SETOF RECORD
AS 'MODULE_PATHNAME', 'local_cache_pages'
LANGUAGE C PARALLEL SAFE;
CREATE FUNCTION approximate_working_set_size(reset bool)
RETURNS integer
AS 'MODULE_PATHNAME', 'approximate_working_set_size'
LANGUAGE C PARALLEL SAFE;
GRANT EXECUTE ON FUNCTION approximate_working_set_size() TO pg_monitor;
-- Create a view for convenient access.
CREATE VIEW local_cache AS
SELECT P.* FROM local_cache_pages() AS P