more work on exposing LFC stats

This commit is contained in:
Heikki Linnakangas
2025-07-23 13:39:32 +03:00
parent bfdd37b54e
commit 35da660200
4 changed files with 61 additions and 4 deletions

View File

@@ -252,6 +252,14 @@ pub unsafe extern "C" fn bcomm_cache_iterate_next(
}
}
#[allow(clippy::missing_safety_doc)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn bcomm_cache_get_num_pages_used(
bs: &mut CommunicatorBackendStruct,
) -> u64 {
bs.integrated_cache.get_num_buckets_in_use() as u64
}
impl<'t> CommunicatorBackendStruct<'t> {
/// The slot must be free, or this panics.
pub(crate) fn start_neon_io_request(&mut self, request_slot_idx: i32, request: &NeonIORequest) {

View File

@@ -759,6 +759,10 @@ impl<'t> IntegratedCacheReadAccess<'t> {
Some((key, _)) => GetBucketResult::Occupied(key.rel, key.block_number),
}
}
pub fn get_num_buckets_in_use(&self) -> usize {
self.block_map.get_num_buckets_in_use()
}
}
pub struct BackendCacheReadOp<'t> {

View File

@@ -86,6 +86,10 @@ typedef struct CommunicatorShmemPerBackendData
*/
uint64 request_counter;
/* Counters, for metrics. */
uint64 cache_misses;
uint64 cache_hits;
/*
* Normally, when reading or writing pages from shared buffer cache, the
* worker process can operate directly on the shared buffer. But when
@@ -122,7 +126,8 @@ typedef struct CommunicatorShmemData
static CommunicatorShmemData *communicator_shmem_ptr;
#define MyIOCompletionLatch (&communicator_shmem_ptr->backends[MyProcNumber].io_completion_latch)
static CommunicatorShmemPerBackendData *my_per_backend_data;
#define MyIOCompletionLatch (&my_per_backend_data->io_completion_latch)
#define MAX_INFLIGHT_ASYNC_REQUESTS 5
@@ -308,6 +313,8 @@ communicator_new_init(void)
if (MyBgworkerEntry && strcmp(MyBgworkerEntry->bgw_function_name, "communicator_new_bgworker_main") == 0)
return;
my_per_backend_data = &communicator_shmem_ptr->backends[MyProcNumber];
OwnLatch(MyIOCompletionLatch);
my_bs = rcommunicator_backend_init(cis, MyProcNumber);
@@ -753,6 +760,7 @@ retry:
}
pgBufferUsage.file_cache.hits += nblocks;
my_per_backend_data->cache_hits += nblocks;
return;
}
@@ -768,6 +776,7 @@ retry:
* as a cache miss.
*/
pgBufferUsage.file_cache.misses += nblocks;
my_per_backend_data->cache_misses += nblocks;
wait_request_completion(request_idx, &result);
Assert(num_inflight_requests == 1);
@@ -1363,7 +1372,42 @@ communicator_new_approximate_working_set_size_seconds(time_t duration, bool rese
LfcStatsEntry *
communicator_new_get_lfc_stats(uint32 *num_entries)
{
// TODO
*num_entries = 0;
return NULL;
LfcStatsEntry *entries;
int n = 0;
uint64 cache_misses = 0;
uint64 cache_hits = 0;
for (int i = 0; i < MaxProcs; i++)
{
cache_misses += communicator_shmem_ptr->backends[i].cache_misses;
cache_hits += communicator_shmem_ptr->backends[i].cache_hits;
}
#define NUM_ENTRIES 10
entries = palloc(sizeof(LfcStatsEntry) * NUM_ENTRIES);
entries[n++] = (LfcStatsEntry) {"file_cache_misses", false, cache_misses};
entries[n++] = (LfcStatsEntry) {"file_cache_hits", false, cache_hits };
entries[n++] = (LfcStatsEntry) {"file_cache_used_pages", false,
bcomm_cache_get_num_pages_used(my_bs) };
/* TODO: these stats are exposed by the legacy LFC implementation */
#if 0
entries[n++] = (LfcStatsEntry) {"file_cache_used", lfc_ctl == NULL,
lfc_ctl ? lfc_ctl->used : 0 };
entries[n++] = (LfcStatsEntry) {"file_cache_writes", lfc_ctl == NULL,
lfc_ctl ? lfc_ctl->writes : 0 };
entries[n++] = (LfcStatsEntry) {"file_cache_size", lfc_ctl == NULL,
lfc_ctl ? lfc_ctl->size : 0 };
entries[n++] = (LfcStatsEntry) {"file_cache_evicted_pages", lfc_ctl == NULL,
lfc_ctl ? lfc_ctl->evicted_pages : 0 };
entries[n++] = (LfcStatsEntry) {"file_cache_limit", lfc_ctl == NULL,
lfc_ctl ? lfc_ctl->limit : 0 };
#endif
Assert(n <= NUM_ENTRIES);
*num_entries = n;
return entries;
}

View File

@@ -735,6 +735,7 @@ neon_get_lfc_stats(PG_FUNCTION_ARGS)
Datum values[NUM_NEON_GET_STATS_COLS];
bool nulls[NUM_NEON_GET_STATS_COLS];
nulls[0] = false;
values[0] = CStringGetTextDatum(entry->metric_name);
nulls[1] = entry->isnull;
values[1] = Int64GetDatum(entry->isnull ? 0 : entry->value);