diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 44094bb..e93150c 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -875,6 +875,15 @@ CREATE VIEW pg_stat_he3walwrite AS FROM pg_stat_get_he3walwrite() AS s ; +CREATE VIEW pg_stat_he3_logindex AS +SELECT + s.memtable_total, + s.memtable_used, + s.memtable_start_index, + s.memtable_active_index, + s.page_total +FROM pg_stat_get_he3_logindex() AS s; + CREATE VIEW pg_stat_slru AS SELECT s.name, diff --git a/src/backend/storage/lmgr/he3db_logindex.c b/src/backend/storage/lmgr/he3db_logindex.c index 76933b1..e3702ca 100644 --- a/src/backend/storage/lmgr/he3db_logindex.c +++ b/src/backend/storage/lmgr/he3db_logindex.c @@ -23,7 +23,7 @@ LogIndexMemListSize(uint64 he3db_logindex_mem_size) if (logindex_mem_tbl_size < 3) elog(FATAL, "The number=%ld of logindex memory table is less than 3", logindex_mem_tbl_size); else - ereport(LOG, (errmsg("The total log index memory table size is %ld", size))); + ereport(LOG, (errmsg("The total log index memory table size is %ld, number logindex mem-table size is %ld", size, logindex_mem_tbl_size))); return size; } @@ -42,20 +42,21 @@ static void SetNewPageItem(LogIndexMemTBL *mem_tbl, const BufferTag *page) static LogIndexMemTBL *GetNextFreeMemTbl(void) { // TODO change to Lightweight Lock - LWLockAcquire(LogIndexMemListLock,LW_EXCLUSIVE); - // Circular List - log_index_mem_list->active_table_index = (log_index_mem_list->active_table_index + 1)%(log_index_mem_list->table_cap); - LWLockRelease(LogIndexMemListLock); + uint64 active_tbl_index = (log_index_mem_list->active_table_index + 1)%(log_index_mem_list->table_cap); // if all mem table is full, waiting for recycle - if(log_index_mem_list->active_table_index == log_index_mem_list->table_start_index) + if(active_tbl_index == log_index_mem_list->table_start_index) { elog(LOG, "Mem table is full, waiting for cleanup. Total size: %ld", logindex_mem_tbl_size); } - while(log_index_mem_list->active_table_index == log_index_mem_list->table_start_index) + while(active_tbl_index == log_index_mem_list->table_start_index) { pg_usleep(10); /* 10 us */ } - elog(DEBUG5, "Find next free mem table"); + elog(DEBUG5, "Find next free mem table and set active_table_index + 1: %ld", active_tbl_index); + LWLockAcquire(LogIndexMemListLock,LW_EXCLUSIVE); + // Circular List + log_index_mem_list->active_table_index = active_tbl_index; + LWLockRelease(LogIndexMemListLock); // if it finds free mem table will return directly. return &(log_index_mem_list->mem_table[log_index_mem_list->active_table_index]); } @@ -827,3 +828,30 @@ void FreeTagNode(TagNode *head) tn = NULL; } } + +void He3DBGetLogindexStats(uint64 *memtable_total, uint64 *memtable_used, uint64 *memtable_active_index, + uint64 *memtable_start_index, uint64 *page_total) +{ + LWLockAcquire(LogIndexMemListLock,LW_SHARED); + *memtable_start_index = log_index_mem_list->table_start_index; + *memtable_active_index = log_index_mem_list->active_table_index; + *memtable_total = log_index_mem_list->table_cap; + LWLockRelease(LogIndexMemListLock); + *memtable_used = ((*memtable_active_index - *memtable_start_index) + *memtable_total)%*memtable_total + 1; + uint64 tbl_index = *memtable_start_index; + uint64 page_num = 0; + while(tbl_index != *memtable_active_index) + { + LogIndexMemTBL *mem_tbl = &(log_index_mem_list->mem_table[tbl_index]); + tbl_index = (tbl_index + 1)%(*memtable_total); + page_num = page_num + mem_tbl->meta.page_free_head - 2; + } + if (tbl_index == *memtable_active_index) + { + LogIndexMemTBL *mem_tbl = &(log_index_mem_list->mem_table[tbl_index]); + if (pg_atomic_read_u32(&mem_tbl->meta.state) != LOG_INDEX_MEM_TBL_STATE_FREE){ + page_num = page_num + mem_tbl->meta.page_free_head - 2; + } + } + *page_total = page_num; +} diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 27138e2..0801acb 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -33,6 +33,7 @@ #include "utils/inet.h" #include "utils/pg_lsn.h" #include "utils/timestamp.h" +#include "storage/he3db_logindex.h" #define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var)))) @@ -2429,4 +2430,52 @@ pg_stat_get_he3walwrite(PG_FUNCTION_ARGS) /* Returns the record as Datum */ PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls))); +} + +/* + * Returns statistics of logindex + */ +Datum +pg_stat_get_he3_logindex(PG_FUNCTION_ARGS) +{ +#define PG_STAT_GET_HE3_LOGINDEX_COLS 5 + TupleDesc tupdesc; + Datum values[PG_STAT_GET_HE3_LOGINDEX_COLS]; + bool nulls[PG_STAT_GET_HE3_LOGINDEX_COLS]; + uint64 memtable_total; + uint64 memtable_used; + uint64 memtable_active_index; + uint64 memtable_start_index; + uint64 page_total; + + /* Initialise values and NULL flags arrays */ + MemSet(values, 0, sizeof(values)); + MemSet(nulls, 0, sizeof(nulls)); + + /* Initialise attributes information in the tuple descriptor */ + tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_HE3_LOGINDEX_COLS); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "memtable_total", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "memtable_used", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "memtable_start_index", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 4, "memtable_active_index", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 5, "page_total", + INT8OID, -1, 0); + + BlessTupleDesc(tupdesc); + + He3DBGetLogindexStats(&memtable_total, &memtable_used, &memtable_active_index, &memtable_start_index, &page_total); + + /* Fill values and NULLs */ + values[0] = UInt64GetDatum(memtable_total); + values[1] = UInt64GetDatum(memtable_used); + values[2] = UInt64GetDatum(memtable_start_index); + values[3] = UInt64GetDatum(memtable_active_index); + values[4] = UInt64GetDatum(page_total); + + /* Returns the record as Datum */ + PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls))); } \ No newline at end of file diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index c80bef9..cab0d06 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5590,6 +5590,14 @@ proargnames => '{write_lsn,flush_lsn,writekv_totaltimes,writekv_parallels}', prosrc => 'pg_stat_get_he3walwrite' }, +{ oid => '6207', descr => 'statistics: information about He3DB LogIndex', + proname => 'pg_stat_get_he3_logindex', proisstrict => 'f', provolatile => 's', + proparallel => 'r', prorettype => 'record', proargtypes => '', + proallargtypes => '{int8,int8,int8,int8,int8}', + proargmodes => '{o,o,o,o,o}', + proargnames => '{memtable_total,memtable_used,memtable_start_index,memtable_active_index,page_total}', + prosrc => 'pg_stat_get_he3_logindex' }, + { oid => '2306', descr => 'statistics: information about SLRU caches', proname => 'pg_stat_get_slru', prorows => '100', proisstrict => 'f', proretset => 't', provolatile => 's', proparallel => 'r', diff --git a/src/include/storage/he3db_logindex.h b/src/include/storage/he3db_logindex.h index 2722b22..ef548a7 100644 --- a/src/include/storage/he3db_logindex.h +++ b/src/include/storage/he3db_logindex.h @@ -117,4 +117,6 @@ extern void FreeLsnNode(LsnNode *head); extern TagNode *GetBufTagByLsnRange(XLogRecPtr start_lsn, XLogRecPtr end_lsn); extern void FreeTagNode(TagNode *head); extern bool CheckBufTagExistByLsnRange(const BufferTag *page, XLogRecPtr start_lsn, XLogRecPtr end_lsn); +extern void He3DBGetLogindexStats(uint64 *memtable_total, uint64 *memtable_used, uint64 *memtable_active_index, + uint64 *memtable_start_index, uint64 *page_total); #endif /* HE3DB_LOGINDEX_H */ \ No newline at end of file