mirror of
https://github.com/percona/pg_stat_monitor.git
synced 2026-02-04 05:56:21 +00:00
PG-154: Add backup option in case of no space left in the bucket.
This commit is contained in:
110
hash_query.c
110
hash_query.c
@@ -16,6 +16,9 @@
|
||||
|
||||
static pgssSharedState *pgss;
|
||||
static HTAB *pgss_hash;
|
||||
static HTAB *pgss_query_hash;
|
||||
|
||||
|
||||
|
||||
static HTAB* hash_init(const char *hash_name, int key_size, int entry_size, int hash_size);
|
||||
|
||||
@@ -39,6 +42,7 @@ pgss_startup(void)
|
||||
|
||||
pgss = NULL;
|
||||
pgss_hash = NULL;
|
||||
pgss_query_hash = NULL;
|
||||
|
||||
/*
|
||||
* Create or attach to the shared memory state, including hash table
|
||||
@@ -54,7 +58,7 @@ pgss_startup(void)
|
||||
ResetSharedState(pgss);
|
||||
}
|
||||
|
||||
pgss->query_buf_size_bucket = PGSM_QUERY_BUF_SIZE / PGSM_MAX_BUCKETS;
|
||||
pgss->query_buf_size_bucket = MAX_QUERY_BUF / PGSM_MAX_BUCKETS;
|
||||
|
||||
for (i = 0; i < PGSM_MAX_BUCKETS; i++)
|
||||
{
|
||||
@@ -63,7 +67,8 @@ pgss_startup(void)
|
||||
memset(buf, 0, sizeof (uint64));
|
||||
}
|
||||
|
||||
pgss_hash = hash_init("pg_stat_monitor: Queries hashtable", sizeof(pgssHashKey), sizeof(pgssEntry),PGSM_MAX);
|
||||
pgss_hash = hash_init("pg_stat_monitor: bucket hashtable", sizeof(pgssHashKey), sizeof(pgssEntry), MAX_BUCKET_ENTRIES);
|
||||
pgss_query_hash = hash_init("pg_stat_monitor: query hashtable", sizeof(pgssQueryHashKey), sizeof(pgssQueryEntry),500000);
|
||||
|
||||
LWLockRelease(AddinShmemInitLock);
|
||||
|
||||
@@ -80,16 +85,24 @@ pgsm_get_bucket_size(void)
|
||||
return pgss->query_buf_size_bucket;
|
||||
}
|
||||
|
||||
pgssSharedState* pgsm_get_ss(void)
|
||||
pgssSharedState*
|
||||
pgsm_get_ss(void)
|
||||
{
|
||||
return pgss;
|
||||
}
|
||||
|
||||
HTAB* pgsm_get_hash(void)
|
||||
HTAB*
|
||||
pgsm_get_hash(void)
|
||||
{
|
||||
return pgss_hash;
|
||||
}
|
||||
|
||||
HTAB*
|
||||
pgsm_get_query_hash(void)
|
||||
{
|
||||
return pgss_query_hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* shmem_shutdown hook: Dump statistics into file.
|
||||
*
|
||||
@@ -115,24 +128,21 @@ hash_memsize(void)
|
||||
Size size;
|
||||
|
||||
size = MAXALIGN(sizeof(pgssSharedState));
|
||||
size = add_size(size, hash_estimate_size(PGSM_MAX, sizeof(pgssEntry)));
|
||||
size = MAXALIGN(MAX_QUERY_BUF);
|
||||
size = add_size(size, hash_estimate_size(MAX_BUCKET_ENTRIES, sizeof(pgssEntry)));
|
||||
size = add_size(size, hash_estimate_size(500000, sizeof(pgssQueryEntry)));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
pgssEntry *
|
||||
hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key,int encoding)
|
||||
{
|
||||
pgssEntry *entry = NULL;
|
||||
bool found = false;
|
||||
|
||||
if (pgss->bucket_entry[pgss->current_wbucket] >= (PGSM_MAX / PGSM_MAX_BUCKETS))
|
||||
{
|
||||
pgss->bucket_overflow[pgss->current_wbucket]++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hash_get_num_entries(pgss_hash) >= PGSM_MAX)
|
||||
if (hash_get_num_entries(pgss_hash) >= MAX_BUCKET_ENTRIES)
|
||||
return NULL;
|
||||
|
||||
/* Find or create an entry with desired hash code */
|
||||
@@ -150,9 +160,32 @@ hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key,int encoding)
|
||||
/* ... and don't forget the query text metadata */
|
||||
entry->encoding = encoding;
|
||||
}
|
||||
if (entry == NULL)
|
||||
elog(FATAL, "%s", "Ibrar");
|
||||
return entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate least-used entries.
|
||||
*
|
||||
* Caller must hold an exclusive lock on pgss->lock.
|
||||
*/
|
||||
void
|
||||
hash_query_entry_dealloc(int bucket)
|
||||
{
|
||||
HASH_SEQ_STATUS hash_seq;
|
||||
pgssQueryEntry *entry;
|
||||
|
||||
printf ("--%d--", hash_get_num_entries(pgss_hash));
|
||||
hash_seq_init(&hash_seq, pgss_query_hash);
|
||||
while ((entry = hash_seq_search(&hash_seq)) != NULL)
|
||||
{
|
||||
if (entry->key.bucket_id == bucket)
|
||||
entry = hash_search(pgss_query_hash, &entry->key, HASH_REMOVE, NULL);
|
||||
}
|
||||
printf ("--%d", hash_get_num_entries(pgss_hash));
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate least-used entries.
|
||||
*
|
||||
@@ -164,13 +197,13 @@ hash_entry_dealloc(int bucket)
|
||||
HASH_SEQ_STATUS hash_seq;
|
||||
pgssEntry *entry;
|
||||
|
||||
pgss->bucket_entry[bucket] = 0;
|
||||
|
||||
hash_seq_init(&hash_seq, pgss_hash);
|
||||
while ((entry = hash_seq_search(&hash_seq)) != NULL)
|
||||
{
|
||||
if (entry->key.bucket_id == bucket || bucket < 0)
|
||||
{
|
||||
entry = hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +213,7 @@ hash_entry_dealloc(int bucket)
|
||||
void
|
||||
hash_entry_reset()
|
||||
{
|
||||
pgssSharedState *pgss = pgsm_get_ss();
|
||||
HASH_SEQ_STATUS hash_seq;
|
||||
pgssEntry *entry;
|
||||
|
||||
@@ -194,35 +228,35 @@ hash_entry_reset()
|
||||
LWLockRelease(pgss->lock);
|
||||
}
|
||||
|
||||
pgssEntry*
|
||||
hash_create_query_entry(unsigned int queryid,
|
||||
unsigned int userid,
|
||||
unsigned int dbid,
|
||||
unsigned int bucket_id,
|
||||
unsigned int ip)
|
||||
/* Caller must accuire lock */
|
||||
bool
|
||||
hash_create_query_entry(uint64 bucket_id, uint64 queryid)
|
||||
{
|
||||
pgssHashKey key;
|
||||
pgssEntry *entry = NULL;
|
||||
int encoding = GetDatabaseEncoding();
|
||||
pgssQueryHashKey key;
|
||||
pgssQueryEntry *entry = NULL;
|
||||
bool found;
|
||||
|
||||
key.queryid = queryid;
|
||||
key.userid = userid;
|
||||
key.dbid = dbid;
|
||||
key.bucket_id = bucket_id;
|
||||
key.ip = ip;
|
||||
key.bucket_id = bucket_id;
|
||||
|
||||
entry = (pgssQueryEntry *) hash_search(pgss_query_hash, &key, HASH_ENTER, &found);
|
||||
return (entry != NULL);
|
||||
}
|
||||
|
||||
/* Caller must accuire lock */
|
||||
bool
|
||||
hash_find_query_entry(uint64 bucket_id, uint64 queryid)
|
||||
{
|
||||
pgssQueryHashKey key;
|
||||
pgssQueryEntry *entry = NULL;
|
||||
bool found;
|
||||
|
||||
key.queryid = queryid;
|
||||
key.bucket_id = bucket_id;
|
||||
|
||||
/* Lookup the hash table entry with shared lock. */
|
||||
LWLockAcquire(pgss->lock, LW_SHARED);
|
||||
entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_FIND, NULL);
|
||||
if(!entry)
|
||||
{
|
||||
LWLockRelease(pgss->lock);
|
||||
LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
|
||||
|
||||
/* OK to create a new hashtable entry */
|
||||
entry = hash_entry_alloc(pgss, &key, encoding);
|
||||
}
|
||||
return entry;
|
||||
entry = (pgssQueryEntry *) hash_search(pgss_query_hash, &key, HASH_FIND, &found);
|
||||
return ((entry != NULL) && found);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
Reference in New Issue
Block a user