PG-588: Some queries are not being normalised.
This bug uncovered serious issues with how the data was being stored by PSGM. So it require a complete redesign. pg_stat_monitor now stores the data locally within the backend process's local memory. The data is only stored when the query completes. This reduces the number of lock acquisitions that were previously needed during various stages of the execution. Also, this avoids data loss in case the current bucket changes during execution. Also, the unavailability of jumble state during later stages of executions was causing pg_stat_monitor to save non-normalized query. This was a major problem as well. pg_stat_monitor specific memory context is implemented. It is used for saving data locally. The context memory callback helps us clear the locally saved data so that we do not store it multiple times in the shared hash. As part of this major rewrite, pgss reference in function and variable names is changed to pgsm. Memory footprint for the entries is reduced, data types are corrected where needed, and we've removed unused variables, functions and macros. This patch was mutually created by: Co-authored-by: Hamid Akhtar <hamid.akhtar@percona.com> Co-authored-by: Muhammad Usama <muhammad.usama@percona.com>pull/378/head
parent
837bacdf3a
commit
de66ef0fce
2
Makefile
2
Makefile
|
@ -12,7 +12,7 @@ LDFLAGS_SL += $(filter -lm, $(LIBS))
|
|||
|
||||
TAP_TESTS = 1
|
||||
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf --inputdir=regression
|
||||
REGRESS = basic version guc pgsm_query_id functions counters relations database error_insert application_name application_name_unique top_query cmd_type error rows tags
|
||||
REGRESS = basic version guc pgsm_query_id functions counters relations database error_insert application_name application_name_unique top_query cmd_type error rows tags user
|
||||
|
||||
# Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
|
||||
# which typical installcheck users do not have (e.g. buildfarm clients).
|
||||
|
|
8
guc.c
8
guc.c
|
@ -41,9 +41,9 @@ init_guc(void)
|
|||
{
|
||||
.guc_name = "pg_stat_monitor.pgsm_max",
|
||||
.guc_desc = "Sets the maximum size of shared memory in (MB) used for statement's metadata tracked by pg_stat_monitor.",
|
||||
.guc_default = 100,
|
||||
.guc_min = 1,
|
||||
.guc_max = 1000,
|
||||
.guc_default = 256,
|
||||
.guc_min = 10,
|
||||
.guc_max = 10240,
|
||||
.guc_restart = true,
|
||||
.guc_unit = GUC_UNIT_MB,
|
||||
.guc_value = &PGSM_MAX
|
||||
|
@ -95,7 +95,7 @@ init_guc(void)
|
|||
.guc_desc = "Sets the maximum number of buckets.",
|
||||
.guc_default = 10,
|
||||
.guc_min = 1,
|
||||
.guc_max = 10,
|
||||
.guc_max = 20000,
|
||||
.guc_restart = true,
|
||||
.guc_unit = 0,
|
||||
.guc_value = &PGSM_MAX_BUCKETS
|
||||
|
|
266
hash_query.c
266
hash_query.c
|
@ -19,14 +19,15 @@
|
|||
#include "pg_stat_monitor.h"
|
||||
|
||||
static pgsmLocalState pgsmStateLocal;
|
||||
static PGSM_HASH_TABLE_HANDLE pgsm_create_bucket_hash(pgssSharedState *pgss, dsa_area *dsa);
|
||||
static PGSM_HASH_TABLE_HANDLE pgsm_create_bucket_hash(pgsmSharedState *pgsm, dsa_area *dsa);
|
||||
static Size pgsm_get_shared_area_size(void);
|
||||
static void InitializeSharedState(pgsmSharedState *pgsm);
|
||||
|
||||
#if USE_DYNAMIC_HASH
|
||||
/* parameter for the shared hash */
|
||||
static dshash_parameters dsh_params = {
|
||||
sizeof(pgssHashKey),
|
||||
sizeof(pgssEntry),
|
||||
sizeof(pgsmHashKey),
|
||||
sizeof(pgsmEntry),
|
||||
dshash_memcmp,
|
||||
dshash_memhash
|
||||
};
|
||||
|
@ -54,12 +55,12 @@ pgsm_query_area_size(void)
|
|||
Size
|
||||
pgsm_ShmemSize(void)
|
||||
{
|
||||
Size sz = MAXALIGN(sizeof(pgssSharedState));
|
||||
Size sz = MAXALIGN(sizeof(pgsmSharedState));
|
||||
sz = add_size(sz, MAX_QUERY_BUF);
|
||||
#if USE_DYNAMIC_HASH
|
||||
sz = add_size(sz, MAX_BUCKETS_MEM);
|
||||
#else
|
||||
sz = add_size(sz, hash_estimate_size(MAX_BUCKET_ENTRIES, sizeof(pgssEntry)));
|
||||
sz = add_size(sz, hash_estimate_size(MAX_BUCKET_ENTRIES, sizeof(pgsmEntry)));
|
||||
#endif
|
||||
return MAXALIGN(sz);
|
||||
}
|
||||
|
@ -77,47 +78,48 @@ pgsm_get_shared_area_size(void)
|
|||
#if USE_DYNAMIC_HASH
|
||||
sz = pgsm_ShmemSize();
|
||||
#else
|
||||
sz = MAXALIGN(sizeof(pgssSharedState));
|
||||
sz = MAXALIGN(sizeof(pgsmSharedState));
|
||||
sz = add_size(sz, pgsm_query_area_size());
|
||||
#endif
|
||||
return sz;
|
||||
}
|
||||
|
||||
void
|
||||
pgss_startup(void)
|
||||
pgsm_startup(void)
|
||||
{
|
||||
bool found = false;
|
||||
pgssSharedState *pgss;
|
||||
pgsmSharedState *pgsm;
|
||||
/* reset in case this is a restart within the postmaster */
|
||||
pgsmStateLocal.dsa = NULL;
|
||||
pgsmStateLocal.shared_hash = NULL;
|
||||
pgsmStateLocal.shared_pgssState = NULL;
|
||||
pgsmStateLocal.shared_pgsmState = NULL;
|
||||
|
||||
/*
|
||||
* Create or attach to the shared memory state, including hash table
|
||||
*/
|
||||
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
|
||||
|
||||
pgss = ShmemInitStruct("pg_stat_monitor", pgsm_get_shared_area_size(), &found);
|
||||
pgsm = ShmemInitStruct("pg_stat_monitor", pgsm_get_shared_area_size(), &found);
|
||||
if (!found)
|
||||
{
|
||||
/* First time through ... */
|
||||
dsa_area *dsa;
|
||||
char *p = (char *) pgss;
|
||||
char *p = (char *) pgsm;
|
||||
|
||||
pgss->lock = &(GetNamedLWLockTranche("pg_stat_monitor"))->lock;
|
||||
SpinLockInit(&pgss->mutex);
|
||||
ResetSharedState(pgss);
|
||||
/* the allocation of pgssSharedState itself */
|
||||
p += MAXALIGN(sizeof(pgssSharedState));
|
||||
pgss->raw_dsa_area = p;
|
||||
dsa = dsa_create_in_place(pgss->raw_dsa_area,
|
||||
pgsm->pgsm_oom = false;
|
||||
pgsm->lock = &(GetNamedLWLockTranche("pg_stat_monitor"))->lock;
|
||||
SpinLockInit(&pgsm->mutex);
|
||||
InitializeSharedState(pgsm);
|
||||
/* the allocation of pgsmSharedState itself */
|
||||
p += MAXALIGN(sizeof(pgsmSharedState));
|
||||
pgsm->raw_dsa_area = p;
|
||||
dsa = dsa_create_in_place(pgsm->raw_dsa_area,
|
||||
pgsm_query_area_size(),
|
||||
LWLockNewTrancheId(), 0);
|
||||
dsa_pin(dsa);
|
||||
dsa_set_size_limit(dsa, pgsm_query_area_size());
|
||||
|
||||
pgss->hash_handle = pgsm_create_bucket_hash(pgss,dsa);
|
||||
pgsm->hash_handle = pgsm_create_bucket_hash(pgsm,dsa);
|
||||
|
||||
/* If overflow is enabled, set the DSA size to unlimited,
|
||||
* and allow the DSA to grow beyond the shared memory space
|
||||
|
@ -125,7 +127,7 @@ pgss_startup(void)
|
|||
if (PGSM_OVERFLOW_TARGET == OVERFLOW_TARGET_DISK)
|
||||
dsa_set_size_limit(dsa, -1);
|
||||
|
||||
pgsmStateLocal.shared_pgssState = pgss;
|
||||
pgsmStateLocal.shared_pgsmState = pgsm;
|
||||
/*
|
||||
* Postmaster will never access the dsa again, thus free it's local
|
||||
* references.
|
||||
|
@ -143,29 +145,41 @@ pgss_startup(void)
|
|||
* If we're in the postmaster (or a standalone backend...), set up a shmem
|
||||
* exit hook to dump the statistics to disk.
|
||||
*/
|
||||
on_shmem_exit(pgss_shmem_shutdown, (Datum) 0);
|
||||
on_shmem_exit(pgsm_shmem_shutdown, (Datum) 0);
|
||||
}
|
||||
|
||||
static void
|
||||
InitializeSharedState(pgsmSharedState *pgsm)
|
||||
{
|
||||
pg_atomic_init_u64(&pgsm->current_wbucket, 0);
|
||||
pg_atomic_init_u64(&pgsm->prev_bucket_sec, 0);
|
||||
memset(&pgsm->bucket_entry, 0, MAX_BUCKETS * sizeof(uint64));
|
||||
pgsm->pgsm_mem_cxt = AllocSetContextCreate(TopMemoryContext,
|
||||
"pg_stat_monitor local store",
|
||||
ALLOCSET_DEFAULT_SIZES);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create the classic or dshahs hash table for storing the query statistics.
|
||||
*/
|
||||
static PGSM_HASH_TABLE_HANDLE
|
||||
pgsm_create_bucket_hash(pgssSharedState *pgss, dsa_area *dsa)
|
||||
pgsm_create_bucket_hash(pgsmSharedState *pgsm, dsa_area *dsa)
|
||||
{
|
||||
PGSM_HASH_TABLE_HANDLE bucket_hash;
|
||||
|
||||
#if USE_DYNAMIC_HASH
|
||||
dshash_table *dsh;
|
||||
pgss->hash_tranche_id = LWLockNewTrancheId();
|
||||
dsh_params.tranche_id = pgss->hash_tranche_id;
|
||||
pgsm->hash_tranche_id = LWLockNewTrancheId();
|
||||
dsh_params.tranche_id = pgsm->hash_tranche_id;
|
||||
dsh = dshash_create(dsa, &dsh_params, 0);
|
||||
bucket_hash = dshash_get_hash_table_handle(dsh);
|
||||
dshash_detach(dsh);
|
||||
#else
|
||||
HASHCTL info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.keysize = sizeof(pgssHashKey);
|
||||
info.entrysize = sizeof(pgssEntry);
|
||||
info.keysize = sizeof(pgsmHashKey);
|
||||
info.entrysize = sizeof(pgsmEntry);
|
||||
bucket_hash = ShmemInitHash("pg_stat_monitor: bucket hashtable", MAX_BUCKET_ENTRIES, MAX_BUCKET_ENTRIES, &info, HASH_ELEM | HASH_BLOBS);
|
||||
#endif
|
||||
return bucket_hash;
|
||||
|
@ -193,7 +207,7 @@ pgsm_attach_shmem(void)
|
|||
*/
|
||||
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
|
||||
|
||||
pgsmStateLocal.dsa = dsa_attach_in_place(pgsmStateLocal.shared_pgssState->raw_dsa_area,
|
||||
pgsmStateLocal.dsa = dsa_attach_in_place(pgsmStateLocal.shared_pgsmState->raw_dsa_area,
|
||||
NULL);
|
||||
/* pin the attached area to keep the area attached until end of
|
||||
* session or explicit detach.
|
||||
|
@ -201,11 +215,11 @@ pgsm_attach_shmem(void)
|
|||
dsa_pin_mapping(pgsmStateLocal.dsa);
|
||||
|
||||
#if USE_DYNAMIC_HASH
|
||||
dsh_params.tranche_id = pgsmStateLocal.shared_pgssState->hash_tranche_id;
|
||||
dsh_params.tranche_id = pgsmStateLocal.shared_pgsmState->hash_tranche_id;
|
||||
pgsmStateLocal.shared_hash = dshash_attach(pgsmStateLocal.dsa, &dsh_params,
|
||||
pgsmStateLocal.shared_pgssState->hash_handle, 0);
|
||||
pgsmStateLocal.shared_pgsmState->hash_handle, 0);
|
||||
#else
|
||||
pgsmStateLocal.shared_hash = pgsmStateLocal.shared_pgssState->hash_handle;
|
||||
pgsmStateLocal.shared_hash = pgsmStateLocal.shared_pgsmState->hash_handle;
|
||||
#endif
|
||||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
@ -219,17 +233,17 @@ get_dsa_area_for_query_text(void)
|
|||
}
|
||||
|
||||
PGSM_HASH_TABLE*
|
||||
get_pgssHash(void)
|
||||
get_pgsmHash(void)
|
||||
{
|
||||
pgsm_attach_shmem();
|
||||
return pgsmStateLocal.shared_hash;
|
||||
}
|
||||
|
||||
pgssSharedState *
|
||||
pgsmSharedState *
|
||||
pgsm_get_ss(void)
|
||||
{
|
||||
pgsm_attach_shmem();
|
||||
return pgsmStateLocal.shared_pgssState;
|
||||
return pgsmStateLocal.shared_pgsmState;
|
||||
}
|
||||
|
||||
|
||||
|
@ -240,35 +254,36 @@ pgsm_get_ss(void)
|
|||
* other processes running when this is called.
|
||||
*/
|
||||
void
|
||||
pgss_shmem_shutdown(int code, Datum arg)
|
||||
pgsm_shmem_shutdown(int code, Datum arg)
|
||||
{
|
||||
/* Don't try to dump during a crash. */
|
||||
elog(LOG,"pgss_shmem_shutdown");
|
||||
elog(LOG,"[pg_stat_monitor] pgsm_shmem_shutdown: Shutdown initiated.");
|
||||
|
||||
if (code)
|
||||
return;
|
||||
|
||||
pgsmStateLocal.shared_pgssState = NULL;
|
||||
pgsmStateLocal.shared_pgsmState = NULL;
|
||||
/* Safety check ... shouldn't get here unless shmem is set up. */
|
||||
if (!IsHashInitialize())
|
||||
return;
|
||||
}
|
||||
|
||||
pgssEntry *
|
||||
hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding)
|
||||
pgsmEntry *
|
||||
hash_entry_alloc(pgsmSharedState *pgsm, pgsmHashKey *key, int encoding)
|
||||
{
|
||||
pgssEntry *entry = NULL;
|
||||
pgsmEntry *entry = NULL;
|
||||
bool found = false;
|
||||
/* Find or create an entry with desired hash code */
|
||||
entry = (pgssEntry*) pgsm_hash_find_or_insert(pgsmStateLocal.shared_hash, key, &found);
|
||||
entry = (pgsmEntry*) pgsm_hash_find_or_insert(pgsmStateLocal.shared_hash, key, &found);
|
||||
if (entry == NULL)
|
||||
elog(DEBUG1, "hash_entry_alloc: OUT OF MEMORY");
|
||||
elog(DEBUG1, "[pg_stat_monitor] hash_entry_alloc: OUT OF MEMORY.");
|
||||
else if (!found)
|
||||
{
|
||||
pgss->bucket_entry[pg_atomic_read_u64(&pgss->current_wbucket)]++;
|
||||
pgsm->bucket_entry[pg_atomic_read_u64(&pgsm->current_wbucket)]++;
|
||||
/* New entry, initialize it */
|
||||
/* reset the statistics */
|
||||
memset(&entry->counters, 0, sizeof(Counters));
|
||||
entry->query_pos = InvalidDsaPointer;
|
||||
entry->query_text.query_pos = InvalidDsaPointer;
|
||||
entry->counters.info.parent_query = InvalidDsaPointer;
|
||||
|
||||
/* set the appropriate initial usage count */
|
||||
|
@ -288,23 +303,21 @@ hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding)
|
|||
/*
|
||||
* Prepare resources for using the new bucket:
|
||||
* - Deallocate finished hash table entries in new_bucket_id (entries whose
|
||||
* state is PGSS_FINISHED or PGSS_FINISHED).
|
||||
* state is PGSM_EXEC or PGSM_ERROR).
|
||||
* - Clear query buffer for new_bucket_id.
|
||||
* - If old_bucket_id != -1, move all pending hash table entries in
|
||||
* old_bucket_id to the new bucket id, also move pending queries from the
|
||||
* previous query buffer (query_buffer[old_bucket_id]) to the new one
|
||||
* (query_buffer[new_bucket_id]).
|
||||
*
|
||||
* Caller must hold an exclusive lock on pgss->lock.
|
||||
* Caller must hold an exclusive lock on pgsm->lock.
|
||||
*/
|
||||
void
|
||||
hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer)
|
||||
{
|
||||
PGSM_HASH_SEQ_STATUS hstat;
|
||||
pgssEntry *entry = NULL;
|
||||
pgsmEntry *entry = NULL;
|
||||
/* Store pending query ids from the previous bucket. */
|
||||
List *pending_entries = NIL;
|
||||
ListCell *pending_entry;
|
||||
|
||||
if (!pgsmStateLocal.shared_hash)
|
||||
return;
|
||||
|
@ -321,11 +334,10 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
|
|||
* in new_bucket_id if it has finished already.
|
||||
*/
|
||||
if (new_bucket_id < 0 ||
|
||||
(entry->key.bucket_id == new_bucket_id &&
|
||||
(entry->counters.state == PGSS_FINISHED || entry->counters.state == PGSS_ERROR)))
|
||||
(entry->key.bucket_id == new_bucket_id ))
|
||||
{
|
||||
dsa_pointer parent_qdsa = entry->counters.info.parent_query;
|
||||
pdsa = entry->query_pos;
|
||||
pdsa = entry->query_text.query_pos;
|
||||
|
||||
pgsm_hash_delete_current(&hstat, pgsmStateLocal.shared_hash, &entry->key);
|
||||
|
||||
|
@ -334,153 +346,23 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
|
|||
|
||||
if (DsaPointerIsValid(parent_qdsa))
|
||||
dsa_free(pgsmStateLocal.dsa, parent_qdsa);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we detect a pending query residing in the previous bucket id, we
|
||||
* add it to a list of pending elements to be moved to the new bucket
|
||||
* id. Can't update the hash table while iterating it inside this
|
||||
* loop, as this may introduce all sort of problems.
|
||||
*/
|
||||
if (old_bucket_id != -1 && entry->key.bucket_id == old_bucket_id)
|
||||
{
|
||||
if (entry->counters.state == PGSS_PARSE ||
|
||||
entry->counters.state == PGSS_PLAN ||
|
||||
entry->counters.state == PGSS_EXEC)
|
||||
{
|
||||
pgssEntry *bkp_entry = malloc(sizeof(pgssEntry));
|
||||
|
||||
if (!bkp_entry)
|
||||
{
|
||||
elog(DEBUG1, "hash_entry_dealloc: out of memory");
|
||||
|
||||
/*
|
||||
* No memory, If the entry has calls > 1 then we change
|
||||
* the state to finished, as the pending query will likely
|
||||
* finish execution during the new bucket time window. The
|
||||
* pending query will vanish in this case, can't list it
|
||||
* until it completes.
|
||||
*
|
||||
* If there is only one call to the query and it's
|
||||
* pending, remove the entry from the previous bucket and
|
||||
* allow it to finish in the new bucket, in order to avoid
|
||||
* the query living in the old bucket forever.
|
||||
*/
|
||||
if (entry->counters.calls.calls > 1)
|
||||
entry->counters.state = PGSS_FINISHED;
|
||||
else
|
||||
{
|
||||
pdsa = entry->query_pos;
|
||||
pgsm_hash_delete_current(&hstat, pgsmStateLocal.shared_hash, &entry->key);
|
||||
if (DsaPointerIsValid(pdsa))
|
||||
dsa_free(pgsmStateLocal.dsa, pdsa);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Save key/data from the previous entry. */
|
||||
memcpy(bkp_entry, entry, sizeof(pgssEntry));
|
||||
|
||||
/* Update key to use the new bucket id. */
|
||||
bkp_entry->key.bucket_id = new_bucket_id;
|
||||
|
||||
/* Add the entry to a list of nodes to be processed later. */
|
||||
pending_entries = lappend(pending_entries, bkp_entry);
|
||||
|
||||
/*
|
||||
* If the entry has calls > 1 then we change the state to
|
||||
* finished in the previous bucket, as the pending query will
|
||||
* likely finish execution during the new bucket time window.
|
||||
* Can't remove it from the previous bucket as it may have
|
||||
* many calls and we would lose the query statistics.
|
||||
*
|
||||
* If there is only one call to the query and it's pending,
|
||||
* remove the entry from the previous bucket and allow it to
|
||||
* finish in the new bucket, in order to avoid the query
|
||||
* living in the old bucket forever.
|
||||
*/
|
||||
if (entry->counters.calls.calls > 1)
|
||||
entry->counters.state = PGSS_FINISHED;
|
||||
else
|
||||
{
|
||||
pdsa = entry->query_pos;
|
||||
pgsm_hash_delete_current(&hstat, pgsmStateLocal.shared_hash, &entry->key);
|
||||
/* We should not delete the Query in DSA here
|
||||
* as the same will get reused when the entry gets inserted into new bucket
|
||||
*/
|
||||
}
|
||||
}
|
||||
pgsmStateLocal.shared_pgsmState->pgsm_oom = false;
|
||||
}
|
||||
}
|
||||
pgsm_hash_seq_term(&hstat);
|
||||
/*
|
||||
* Iterate over the list of pending queries in order to add them back to
|
||||
* the hash table with the updated bucket id.
|
||||
*/
|
||||
foreach(pending_entry, pending_entries)
|
||||
{
|
||||
bool found = false;
|
||||
pgssEntry *new_entry;
|
||||
pgssEntry *old_entry = (pgssEntry *) lfirst(pending_entry);
|
||||
|
||||
|
||||
PGSM_DISABLE_ERROR_CAPUTRE();
|
||||
{
|
||||
new_entry = (pgssEntry*) pgsm_hash_find_or_insert(pgsmStateLocal.shared_hash, &old_entry->key, &found);
|
||||
}PGSM_END_DISABLE_ERROR_CAPTURE();
|
||||
|
||||
if (new_entry == NULL)
|
||||
elog(DEBUG1, "%s", "pg_stat_monitor: out of memory");
|
||||
else if (!found)
|
||||
{
|
||||
/* Restore counters and other data. */
|
||||
new_entry->counters = old_entry->counters;
|
||||
SpinLockInit(&new_entry->mutex);
|
||||
new_entry->encoding = old_entry->encoding;
|
||||
new_entry->query_pos = old_entry->query_pos;
|
||||
}
|
||||
#if USE_DYNAMIC_HASH
|
||||
if(new_entry)
|
||||
dshash_release_lock(pgsmStateLocal.shared_hash, new_entry);
|
||||
#endif
|
||||
free(old_entry);
|
||||
}
|
||||
list_free(pending_entries);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release all entries.
|
||||
*/
|
||||
void
|
||||
hash_entry_reset()
|
||||
{
|
||||
pgssSharedState *pgss = pgsm_get_ss();
|
||||
PGSM_HASH_SEQ_STATUS hstat;
|
||||
pgssEntry *entry;
|
||||
|
||||
LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
|
||||
|
||||
pgsm_hash_seq_init(&hstat, pgsmStateLocal.shared_hash, true);
|
||||
|
||||
while ((entry = pgsm_hash_seq_next(&hstat)) != NULL)
|
||||
{
|
||||
dsa_pointer pdsa = entry->query_pos;
|
||||
pgsm_hash_delete_current(&hstat, pgsmStateLocal.shared_hash, &entry->key);
|
||||
if (DsaPointerIsValid(pdsa))
|
||||
dsa_free(pgsmStateLocal.dsa, pdsa);
|
||||
}
|
||||
|
||||
pgsm_hash_seq_term(&hstat);
|
||||
|
||||
pg_atomic_write_u64(&pgss->current_wbucket, 0);
|
||||
LWLockRelease(pgss->lock);
|
||||
}
|
||||
|
||||
bool
|
||||
IsHashInitialize(void)
|
||||
{
|
||||
return (pgsmStateLocal.shared_pgssState != NULL);
|
||||
return (pgsmStateLocal.shared_pgsmState != NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
IsSystemOOM(void)
|
||||
{
|
||||
return (IsHashInitialize() && pgsmStateLocal.shared_pgsmState->pgsm_oom);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -489,7 +371,7 @@ IsHashInitialize(void)
|
|||
*/
|
||||
|
||||
void *
|
||||
pgsm_hash_find_or_insert(PGSM_HASH_TABLE *shared_hash, pgssHashKey *key, bool* found)
|
||||
pgsm_hash_find_or_insert(PGSM_HASH_TABLE *shared_hash, pgsmHashKey *key, bool* found)
|
||||
{
|
||||
#if USE_DYNAMIC_HASH
|
||||
void *entry;
|
||||
|
@ -501,7 +383,7 @@ pgsm_hash_find_or_insert(PGSM_HASH_TABLE *shared_hash, pgssHashKey *key, bool* f
|
|||
}
|
||||
|
||||
void *
|
||||
pgsm_hash_find(PGSM_HASH_TABLE *shared_hash, pgssHashKey *key, bool* found)
|
||||
pgsm_hash_find(PGSM_HASH_TABLE *shared_hash, pgsmHashKey *key, bool* found)
|
||||
{
|
||||
#if USE_DYNAMIC_HASH
|
||||
return dshash_find(shared_hash, key, false);
|
||||
|
@ -546,4 +428,4 @@ pgsm_hash_delete_current(PGSM_HASH_SEQ_STATUS *hstat, PGSM_HASH_TABLE *shared_ha
|
|||
#else
|
||||
hash_search(shared_hash, key, HASH_REMOVE, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,9 @@ CREATE FUNCTION pg_stat_monitor_internal(
|
|||
IN showtext boolean,
|
||||
OUT bucket int8, -- 0
|
||||
OUT userid oid,
|
||||
OUT username text,
|
||||
OUT dbid oid,
|
||||
OUT datname text,
|
||||
OUT client_ip int8,
|
||||
|
||||
OUT queryid int8, -- 4
|
||||
|
@ -113,7 +115,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
bucket,
|
||||
bucket_start_time AS bucket_start_time,
|
||||
userid,
|
||||
userid::regrole AS user,
|
||||
username,
|
||||
dbid,
|
||||
datname,
|
||||
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||
|
@ -155,7 +157,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
cpu_user_time,
|
||||
cpu_sys_time,
|
||||
bucket_done
|
||||
FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid
|
||||
FROM pg_stat_monitor_internal(TRUE)
|
||||
ORDER BY bucket_start_time;
|
||||
RETURN 0;
|
||||
END;
|
||||
|
@ -169,7 +171,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
bucket,
|
||||
bucket_start_time AS bucket_start_time,
|
||||
userid,
|
||||
userid::regrole AS user,
|
||||
username,
|
||||
dbid,
|
||||
datname,
|
||||
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||
|
@ -222,7 +224,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
max_plan_time,
|
||||
mean_plan_time,
|
||||
stddev_plan_time
|
||||
FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid
|
||||
FROM pg_stat_monitor_internal(TRUE)
|
||||
ORDER BY bucket_start_time;
|
||||
RETURN 0;
|
||||
END;
|
||||
|
@ -235,7 +237,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
bucket,
|
||||
bucket_start_time AS bucket_start_time,
|
||||
userid,
|
||||
userid::regrole AS user,
|
||||
username,
|
||||
dbid,
|
||||
datname,
|
||||
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||
|
@ -288,7 +290,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
max_plan_time,
|
||||
mean_plan_time,
|
||||
stddev_plan_time
|
||||
FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid
|
||||
FROM pg_stat_monitor_internal(TRUE)
|
||||
ORDER BY bucket_start_time;
|
||||
RETURN 0;
|
||||
END;
|
||||
|
@ -301,7 +303,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
bucket,
|
||||
bucket_start_time AS bucket_start_time,
|
||||
userid,
|
||||
userid::regrole AS user,
|
||||
username,
|
||||
dbid,
|
||||
datname,
|
||||
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||
|
@ -367,7 +369,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
jit_emission_count,
|
||||
jit_emission_time
|
||||
|
||||
FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid
|
||||
FROM pg_stat_monitor_internal(TRUE)
|
||||
ORDER BY bucket_start_time;
|
||||
RETURN 0;
|
||||
END;
|
||||
|
@ -395,15 +397,19 @@ $$
|
|||
$$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT pgsm_create_view();
|
||||
REVOKE ALL ON FUNCTION range FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION get_cmd_type FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION decode_error_level FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pg_stat_monitor_internal FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION get_histogram_timings FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pgsm_create_view FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pgsm_create_11_view FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pgsm_create_13_view FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pgsm_create_14_view FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pgsm_create_15_view FROM PUBLIC;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION range TO PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION decode_error_level TO PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION get_histogram_timings TO PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION get_cmd_type TO PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION pg_stat_monitor_internal TO PUBLIC;
|
||||
|
||||
GRANT SELECT ON pg_stat_monitor TO PUBLIC;
|
||||
|
||||
-- Reset is only available to super user
|
||||
REVOKE ALL ON FUNCTION pg_stat_monitor_reset FROM PUBLIC;
|
||||
|
|
|
@ -84,8 +84,10 @@ CREATE FUNCTION pg_stat_monitor_internal(
|
|||
IN showtext boolean,
|
||||
OUT bucket int8, -- 0
|
||||
OUT userid oid,
|
||||
OUT username text,
|
||||
OUT dbid oid,
|
||||
OUT client_ip int8,
|
||||
OUT datname text,
|
||||
OUT client_ip int4,
|
||||
|
||||
OUT queryid int8, -- 4
|
||||
OUT planid int8,
|
||||
|
@ -169,7 +171,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
bucket,
|
||||
bucket_start_time AS bucket_start_time,
|
||||
userid,
|
||||
userid::regrole AS user,
|
||||
username,
|
||||
dbid,
|
||||
datname,
|
||||
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||
|
@ -211,7 +213,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
cpu_user_time,
|
||||
cpu_sys_time,
|
||||
bucket_done
|
||||
FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid
|
||||
FROM pg_stat_monitor_internal(TRUE)
|
||||
ORDER BY bucket_start_time;
|
||||
RETURN 0;
|
||||
END;
|
||||
|
@ -225,7 +227,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
bucket,
|
||||
bucket_start_time AS bucket_start_time,
|
||||
userid,
|
||||
userid::regrole AS user,
|
||||
username,
|
||||
dbid,
|
||||
datname,
|
||||
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||
|
@ -278,7 +280,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
max_plan_time,
|
||||
mean_plan_time,
|
||||
stddev_plan_time
|
||||
FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid
|
||||
FROM pg_stat_monitor_internal(TRUE)
|
||||
ORDER BY bucket_start_time;
|
||||
RETURN 0;
|
||||
END;
|
||||
|
@ -291,7 +293,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
bucket,
|
||||
bucket_start_time AS bucket_start_time,
|
||||
userid,
|
||||
userid::regrole AS user,
|
||||
username,
|
||||
dbid,
|
||||
datname,
|
||||
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||
|
@ -344,7 +346,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
max_plan_time,
|
||||
mean_plan_time,
|
||||
stddev_plan_time
|
||||
FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid
|
||||
FROM pg_stat_monitor_internal(TRUE)
|
||||
ORDER BY bucket_start_time;
|
||||
RETURN 0;
|
||||
END;
|
||||
|
@ -357,7 +359,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
bucket,
|
||||
bucket_start_time AS bucket_start_time,
|
||||
userid,
|
||||
userid::regrole AS user,
|
||||
username,
|
||||
dbid,
|
||||
datname,
|
||||
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||
|
@ -423,7 +425,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
jit_emission_count,
|
||||
jit_emission_time
|
||||
|
||||
FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid
|
||||
FROM pg_stat_monitor_internal(TRUE)
|
||||
ORDER BY bucket_start_time;
|
||||
RETURN 0;
|
||||
END;
|
||||
|
@ -451,15 +453,19 @@ $$
|
|||
$$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT pgsm_create_view();
|
||||
REVOKE ALL ON FUNCTION range FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION get_cmd_type FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION decode_error_level FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pg_stat_monitor_internal FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION get_histogram_timings FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pgsm_create_view FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pgsm_create_11_view FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pgsm_create_13_view FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pgsm_create_14_view FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pgsm_create_15_view FROM PUBLIC;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION range TO PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION decode_error_level TO PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION get_histogram_timings TO PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION get_cmd_type TO PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION pg_stat_monitor_internal TO PUBLIC;
|
||||
|
||||
GRANT SELECT ON pg_stat_monitor TO PUBLIC;
|
||||
|
||||
-- Reset is only available to super user
|
||||
REVOKE ALL ON FUNCTION pg_stat_monitor_reset FROM PUBLIC;
|
||||
|
|
1542
pg_stat_monitor.c
1542
pg_stat_monitor.c
File diff suppressed because it is too large
Load Diff
|
@ -57,6 +57,9 @@
|
|||
#include "utils/lsyscache.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/guc_tables.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/palloc.h"
|
||||
|
||||
|
||||
#define MAX_BACKEND_PROCESES (MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts)
|
||||
#define IntArrayGetTextDatum(x,y) intarray_get_datum(x,y)
|
||||
|
@ -64,7 +67,6 @@
|
|||
/* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */
|
||||
#define USAGE_EXEC(duration) (1.0)
|
||||
#define USAGE_INIT (1.0) /* including initial planning */
|
||||
#define ASSUMED_MEDIAN_INIT (10.0) /* initial assumed median usage */
|
||||
#define ASSUMED_LENGTH_INIT 1024 /* initial assumed mean query length */
|
||||
#define USAGE_DECREASE_FACTOR (0.99) /* decreased every entry_dealloc */
|
||||
#define STICKY_DECREASE_FACTOR (0.50) /* factor for sticky entries */
|
||||
|
@ -74,16 +76,16 @@
|
|||
|
||||
#define MAX_RESPONSE_BUCKET 50
|
||||
#define INVALID_BUCKET_ID -1
|
||||
#define MAX_REL_LEN 255
|
||||
#define MAX_BUCKETS 10
|
||||
#define TEXT_LEN 255
|
||||
#define ERROR_MESSAGE_LEN 100
|
||||
#define REL_TYPENAME_LEN 64
|
||||
#define REL_LST 10
|
||||
#define REL_LEN 1000
|
||||
#define REL_LEN 132 /* REL_TYPENAME_LEN * 2 (relname + schema) + 1 (for view indication) + 1 and dot and string terminator */
|
||||
#define CMD_LST 10
|
||||
#define CMD_LEN 20
|
||||
#define APPLICATIONNAME_LEN 100
|
||||
#define COMMENTS_LEN 512
|
||||
#define APPLICATIONNAME_LEN NAMEDATALEN
|
||||
#define COMMENTS_LEN 256
|
||||
#define PGSM_OVER_FLOW_MAX 10
|
||||
#define PLAN_TEXT_LEN 1024
|
||||
/* the assumption of query max nested level */
|
||||
|
@ -91,12 +93,13 @@
|
|||
|
||||
#define MAX_QUERY_BUF (PGSM_QUERY_SHARED_BUFFER * 1024 * 1024)
|
||||
#define MAX_BUCKETS_MEM (PGSM_MAX * 1024 * 1024)
|
||||
#define BUCKETS_MEM_OVERFLOW() ((hash_get_num_entries(pgss_hash) * sizeof(pgssEntry)) >= MAX_BUCKETS_MEM)
|
||||
#define MAX_BUCKET_ENTRIES (MAX_BUCKETS_MEM / sizeof(pgssEntry))
|
||||
#define BUCKETS_MEM_OVERFLOW() ((hash_get_num_entries(pgsm_hash) * sizeof(pgsmEntry)) >= MAX_BUCKETS_MEM)
|
||||
#define MAX_BUCKET_ENTRIES (MAX_BUCKETS_MEM / sizeof(pgsmEntry))
|
||||
#define QUERY_BUFFER_OVERFLOW(x,y) ((x + y + sizeof(uint64) + sizeof(uint64)) > MAX_QUERY_BUF)
|
||||
#define QUERY_MARGIN 100
|
||||
#define MIN_QUERY_LEN 10
|
||||
#define SQLCODE_LEN 20
|
||||
#define TOTAL_RELS_LENGTH (REL_LST * REL_LEN)
|
||||
|
||||
#if PG_VERSION_NUM >= 130000
|
||||
#define MAX_SETTINGS 15
|
||||
|
@ -196,23 +199,23 @@ typedef enum OVERFLOW_TARGET
|
|||
OVERFLOW_TARGET_DISK
|
||||
} OVERFLOW_TARGET;
|
||||
|
||||
typedef enum pgssStoreKind
|
||||
typedef enum pgsmStoreKind
|
||||
{
|
||||
PGSS_INVALID = -1,
|
||||
PGSM_INVALID = -1,
|
||||
|
||||
/*
|
||||
* PGSS_PLAN and PGSS_EXEC must be respectively 0 and 1 as they're used to
|
||||
* PGSM_PLAN and PGSM_EXEC must be respectively 0 and 1 as they're used to
|
||||
* reference the underlying values in the arrays in the Counters struct,
|
||||
* and this order is required in pg_stat_statements_internal().
|
||||
* and this order is required in pg_stat_monitor_internal().
|
||||
*/
|
||||
PGSS_PARSE = 0,
|
||||
PGSS_PLAN,
|
||||
PGSS_EXEC,
|
||||
PGSS_FINISHED,
|
||||
PGSS_ERROR,
|
||||
PGSM_PARSE = 0,
|
||||
PGSM_PLAN,
|
||||
PGSM_EXEC,
|
||||
PGSM_STORE,
|
||||
PGSM_ERROR,
|
||||
|
||||
PGSS_NUMKIND /* Must be last value of this enum */
|
||||
} pgssStoreKind;
|
||||
PGSM_NUMKIND /* Must be last value of this enum */
|
||||
} pgsmStoreKind;
|
||||
|
||||
/* the assumption of query max nested level */
|
||||
#define DEFAULT_MAX_NESTED_LEVEL 10
|
||||
|
@ -247,17 +250,17 @@ typedef struct PlanInfo
|
|||
size_t plan_len; /* strlen(plan_text) */
|
||||
} PlanInfo;
|
||||
|
||||
typedef struct pgssHashKey
|
||||
typedef struct pgsmHashKey
|
||||
{
|
||||
uint64 bucket_id; /* bucket number */
|
||||
uint64 queryid; /* query identifier */
|
||||
uint64 userid; /* user OID */
|
||||
uint64 dbid; /* database OID */
|
||||
uint64 ip; /* client ip address */
|
||||
uint64 planid; /* plan identifier */
|
||||
uint64 appid; /* hash of application name */
|
||||
uint64 toplevel; /* query executed at top level */
|
||||
} pgssHashKey;
|
||||
Oid userid; /* user OID */
|
||||
Oid dbid; /* database OID */
|
||||
uint32 ip; /* client ip address */
|
||||
bool toplevel; /* query executed at top level */
|
||||
} pgsmHashKey;
|
||||
|
||||
typedef struct QueryInfo
|
||||
{
|
||||
|
@ -307,6 +310,15 @@ typedef struct Blocks
|
|||
double temp_blk_read_time; /* time spent reading temp blocks, in msec */
|
||||
double temp_blk_write_time; /* time spent writing temp blocks, in
|
||||
* msec */
|
||||
|
||||
/*
|
||||
* Variables for local entry. The values to be passed to pgsm_update_entry
|
||||
* from pgsm_store.
|
||||
*/
|
||||
instr_time instr_blk_read_time; /* time spent reading blocks */
|
||||
instr_time instr_blk_write_time; /* time spent writing blocks */
|
||||
instr_time instr_temp_blk_read_time; /* time spent reading temp blocks */
|
||||
instr_time instr_temp_blk_write_time; /* time spent writing temp blocks */
|
||||
} Blocks;
|
||||
|
||||
typedef struct JitInfo
|
||||
|
@ -322,12 +334,21 @@ typedef struct JitInfo
|
|||
int64 jit_emission_count; /* number of times emission time has been
|
||||
* > 0 */
|
||||
double jit_emission_time; /* total time to emit jit code */
|
||||
|
||||
/*
|
||||
* Variables for local entry. The values to be passed to pgsm_update_entry
|
||||
* from pgsm_store.
|
||||
*/
|
||||
instr_time instr_generation_counter; /* generation counter */
|
||||
instr_time instr_inlining_counter; /* inlining counter */
|
||||
instr_time instr_optimization_counter; /* optimization counter */
|
||||
instr_time instr_emission_counter; /* emission counter */
|
||||
} JitInfo;
|
||||
|
||||
typedef struct SysInfo
|
||||
{
|
||||
float utime; /* user cpu time */
|
||||
float stime; /* system cpu time */
|
||||
double utime; /* user cpu time */
|
||||
double stime; /* system cpu time */
|
||||
} SysInfo;
|
||||
|
||||
typedef struct Wal_Usage
|
||||
|
@ -339,7 +360,6 @@ typedef struct Wal_Usage
|
|||
|
||||
typedef struct Counters
|
||||
{
|
||||
uint64 bucket_id; /* bucket id */
|
||||
Calls calls;
|
||||
QueryInfo info;
|
||||
CallTime time;
|
||||
|
@ -355,7 +375,6 @@ typedef struct Counters
|
|||
Wal_Usage walusage;
|
||||
int resp_calls[MAX_RESPONSE_BUCKET]; /* execution time's in
|
||||
* msec */
|
||||
int64 state; /* query state */
|
||||
} Counters;
|
||||
|
||||
/* Some global structure to get the cpu usage, really don't like the idea of global variable */
|
||||
|
@ -363,32 +382,33 @@ typedef struct Counters
|
|||
/*
|
||||
* Statistics per statement
|
||||
*/
|
||||
typedef struct pgssEntry
|
||||
typedef struct pgsmEntry
|
||||
{
|
||||
pgssHashKey key; /* hash key of entry - MUST BE FIRST */
|
||||
uint64 pgsm_query_id; /* pgsm generate normalized query hash */
|
||||
Counters counters; /* the statistics for this query */
|
||||
int encoding; /* query text encoding */
|
||||
slock_t mutex; /* protects the counters only */
|
||||
dsa_pointer query_pos; /* query location within query buffer */
|
||||
} pgssEntry;
|
||||
pgsmHashKey key; /* hash key of entry - MUST BE FIRST */
|
||||
uint64 pgsm_query_id; /* pgsm generate normalized query hash */
|
||||
char datname[NAMEDATALEN]; /* database name */
|
||||
char username[NAMEDATALEN]; /* user name */
|
||||
Counters counters; /* the statistics for this query */
|
||||
int encoding; /* query text encoding */
|
||||
slock_t mutex; /* protects the counters only */
|
||||
union
|
||||
{
|
||||
dsa_pointer query_pos; /* query location within query buffer */
|
||||
char* query_pointer;
|
||||
}query_text;
|
||||
} pgsmEntry;
|
||||
|
||||
/*
|
||||
* Global shared state
|
||||
*/
|
||||
typedef struct pgssSharedState
|
||||
typedef struct pgsmSharedState
|
||||
{
|
||||
LWLock *lock; /* protects hashtable search/modification */
|
||||
double cur_median_usage; /* current median usage in hashtable */
|
||||
slock_t mutex; /* protects following fields only: */
|
||||
Size extent; /* current extent of query file */
|
||||
int64 n_writers; /* number of active writers to query file */
|
||||
pg_atomic_uint64 current_wbucket;
|
||||
pg_atomic_uint64 prev_bucket_sec;
|
||||
uint64 bucket_entry[MAX_BUCKETS];
|
||||
TimestampTz bucket_start_time[MAX_BUCKETS]; /* start time of the bucket */
|
||||
LWLock *errors_lock; /* protects errors hashtable
|
||||
* search/modification */
|
||||
int hash_tranche_id;
|
||||
void *raw_dsa_area; /* DSA area pointer to store query texts.
|
||||
* dshash also lives in this memory when
|
||||
|
@ -398,28 +418,22 @@ typedef struct pgssSharedState
|
|||
* classic shared memory hash or dshash
|
||||
* (if we are using USE_DYNAMIC_HASH)
|
||||
*/
|
||||
} pgssSharedState;
|
||||
MemoryContext pgsm_mem_cxt;
|
||||
/* context to store stats in local
|
||||
* memory until they are pushed to shared hash
|
||||
*/
|
||||
bool pgsm_oom;
|
||||
} pgsmSharedState;
|
||||
|
||||
typedef struct pgsmLocalState
|
||||
{
|
||||
pgssSharedState *shared_pgssState;
|
||||
pgsmSharedState *shared_pgsmState;
|
||||
dsa_area *dsa; /* local dsa area for backend attached to the
|
||||
* dsa area created by postmaster at startup.
|
||||
*/
|
||||
PGSM_HASH_TABLE *shared_hash;
|
||||
}pgsmLocalState;
|
||||
|
||||
#define ResetSharedState(x) \
|
||||
do { \
|
||||
x->cur_median_usage = ASSUMED_MEDIAN_INIT; \
|
||||
x->cur_median_usage = ASSUMED_MEDIAN_INIT; \
|
||||
x->n_writers = 0; \
|
||||
pg_atomic_init_u64(&x->current_wbucket, 0); \
|
||||
pg_atomic_init_u64(&x->prev_bucket_sec, 0); \
|
||||
memset(&x->bucket_entry, 0, MAX_BUCKETS * sizeof(uint64)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#if PG_VERSION_NUM < 140000
|
||||
/*
|
||||
* Struct for tracking locations/lengths of constants during normalization
|
||||
|
@ -456,40 +470,30 @@ typedef struct JumbleState
|
|||
} JumbleState;
|
||||
#endif
|
||||
|
||||
/* Links to shared memory state */
|
||||
|
||||
bool SaveQueryText(uint64 bucketid,
|
||||
uint64 queryid,
|
||||
unsigned char *buf,
|
||||
const char *query,
|
||||
uint64 query_len,
|
||||
size_t *query_pos);
|
||||
|
||||
/* guc.c */
|
||||
void init_guc(void);
|
||||
GucVariable *get_conf(int i);
|
||||
|
||||
/* hash_create.c */
|
||||
dsa_area *get_dsa_area_for_query_text(void);
|
||||
PGSM_HASH_TABLE *get_pgssHash(void);
|
||||
PGSM_HASH_TABLE *get_pgsmHash(void);
|
||||
|
||||
void pgsm_attach_shmem(void);
|
||||
bool IsHashInitialize(void);
|
||||
void pgss_shmem_startup(void);
|
||||
void pgss_shmem_shutdown(int code, Datum arg);
|
||||
bool IsSystemOOM(void);
|
||||
void pgsm_shmem_startup(void);
|
||||
void pgsm_shmem_shutdown(int code, Datum arg);
|
||||
int pgsm_get_bucket_size(void);
|
||||
pgssSharedState *pgsm_get_ss(void);
|
||||
void hash_entry_reset(void);
|
||||
void hash_query_entryies_reset(void);
|
||||
pgsmSharedState *pgsm_get_ss(void);
|
||||
void hash_query_entries();
|
||||
void hash_query_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer[]);
|
||||
void hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer);
|
||||
pgssEntry *hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding);
|
||||
pgsmEntry *hash_entry_alloc(pgsmSharedState *pgsm, pgsmHashKey *key, int encoding);
|
||||
Size pgsm_ShmemSize(void);
|
||||
void pgss_startup(void);
|
||||
void pgsm_startup(void);
|
||||
|
||||
/* hash_query.c */
|
||||
void pgss_startup(void);
|
||||
void pgsm_startup(void);
|
||||
|
||||
/*---- GUC variables ----*/
|
||||
typedef enum
|
||||
|
@ -528,8 +532,8 @@ static const struct config_enum_entry track_options[] =
|
|||
#define HOOK_STATS_SIZE 0
|
||||
#endif
|
||||
|
||||
void *pgsm_hash_find_or_insert(PGSM_HASH_TABLE *shared_hash, pgssHashKey *key, bool* found);
|
||||
void *pgsm_hash_find(PGSM_HASH_TABLE *shared_hash, pgssHashKey *key, bool* found);
|
||||
void *pgsm_hash_find_or_insert(PGSM_HASH_TABLE *shared_hash, pgsmHashKey *key, bool* found);
|
||||
void *pgsm_hash_find(PGSM_HASH_TABLE *shared_hash, pgsmHashKey *key, bool* found);
|
||||
void pgsm_hash_seq_init(PGSM_HASH_SEQ_STATUS *hstat, PGSM_HASH_TABLE *shared_hash, bool lock);
|
||||
void *pgsm_hash_seq_next(PGSM_HASH_SEQ_STATUS *hstat);
|
||||
void pgsm_hash_seq_term(PGSM_HASH_SEQ_STATUS *hstat);
|
||||
|
|
|
@ -23,6 +23,7 @@ SELECT b FROM t2 FOR UPDATE;
|
|||
|
||||
TRUNCATE t1;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
SELECT query, cmd_type, cmd_type_text FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | cmd_type | cmd_type_text
|
||||
--------------------------------+----------+---------------
|
||||
|
@ -30,13 +31,14 @@ SELECT query, cmd_type, cmd_type_text FROM pg_stat_monitor ORDER BY query COLLA
|
|||
CREATE TABLE t2 (b INTEGER) | 0 |
|
||||
DELETE FROM t1 | 4 | DELETE
|
||||
DROP TABLE t1 | 0 |
|
||||
DROP TABLE t2 | 0 |
|
||||
INSERT INTO t1 VALUES(1) | 3 | INSERT
|
||||
SELECT a FROM t1 | 1 | SELECT
|
||||
SELECT b FROM t2 FOR UPDATE | 1 | SELECT
|
||||
SELECT pg_stat_monitor_reset() | 1 | SELECT
|
||||
TRUNCATE t1 | 0 |
|
||||
UPDATE t1 SET a = 2 | 2 | UPDATE
|
||||
(10 rows)
|
||||
(11 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
|
|
|
@ -27,13 +27,15 @@ SELECT * FROM t3,t4 WHERE t3.c = t4.d;
|
|||
(0 rows)
|
||||
|
||||
\c contrib_regression
|
||||
DROP DATABASE db2;
|
||||
SELECT datname, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
datname | query
|
||||
--------------------+---------------------------------------
|
||||
contrib_regression | DROP DATABASE db2
|
||||
db1 | SELECT * FROM t1,t2 WHERE t1.a = t2.b
|
||||
db2 | SELECT * FROM t3,t4 WHERE t3.c = t4.d
|
||||
contrib_regression | SELECT pg_stat_monitor_reset()
|
||||
(3 rows)
|
||||
(4 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
|
@ -44,10 +46,6 @@ SELECT pg_stat_monitor_reset();
|
|||
\c db1
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
\c db2
|
||||
DROP TABLE t3;
|
||||
DROP TABLE t4;
|
||||
\c contrib_regression
|
||||
DROP DATABASE db1;
|
||||
DROP DATABASE db2;
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
CREATE EXTENSION pg_stat_monitor;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT 1/0; -- divide by zero
|
||||
ERROR: division by zero
|
||||
SELECT * FROM unknown; -- unknown table
|
||||
ERROR: relation "unknown" does not exist
|
||||
LINE 1: SELECT * FROM unknown;
|
||||
^
|
||||
ELECET * FROM unknown; -- syntax error
|
||||
ERROR: syntax error at or near "ELECET"
|
||||
LINE 1: ELECET * FROM unknown;
|
||||
^
|
||||
do $$
|
||||
BEGIN
|
||||
RAISE WARNING 'warning message';
|
||||
END $$;
|
||||
WARNING: warning message
|
||||
SELECT query, elevel, sqlcode, message FROM pg_stat_monitor ORDER BY query COLLATE "C",elevel;
|
||||
query | elevel | sqlcode | message
|
||||
----------------------------------+--------+---------+-----------------------------------
|
||||
ELECET * FROM unknown; | 20 | 42601 | syntax error at or near "ELECET"
|
||||
SELECT * FROM unknown; | 20 | 42P01 | relation "unknown" does not exist
|
||||
SELECT 1/0; | 20 | 22012 | division by zero
|
||||
SELECT pg_stat_monitor_reset() | 0 | |
|
||||
do $$ +| 0 | 01000 | warning message
|
||||
BEGIN +| | |
|
||||
RAISE WARNING 'warning message';+| | |
|
||||
END $$; | | |
|
||||
(5 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
DROP EXTENSION pg_stat_monitor;
|
|
@ -1,4 +1,5 @@
|
|||
DROP ROLE IF EXISTS su;
|
||||
NOTICE: role "su" does not exist, skipping
|
||||
CREATE USER su WITH SUPERUSER;
|
||||
SET ROLE su;
|
||||
CREATE EXTENSION pg_stat_monitor;
|
||||
|
@ -29,13 +30,19 @@ SELECT routine_schema, routine_name, routine_type, data_type FROM information_sc
|
|||
|
||||
SET ROLE u1;
|
||||
SELECT routine_schema, routine_name, routine_type, data_type FROM information_schema.routines WHERE routine_schema = 'public' ORDER BY routine_name COLLATE "C";
|
||||
routine_schema | routine_name | routine_type | data_type
|
||||
----------------+-------------------------+--------------+-----------
|
||||
public | histogram | FUNCTION | record
|
||||
public | pg_stat_monitor_reset | FUNCTION | void
|
||||
public | pg_stat_monitor_version | FUNCTION | text
|
||||
(3 rows)
|
||||
routine_schema | routine_name | routine_type | data_type
|
||||
----------------+--------------------------+--------------+-----------
|
||||
public | decode_error_level | FUNCTION | text
|
||||
public | get_cmd_type | FUNCTION | text
|
||||
public | get_histogram_timings | FUNCTION | text
|
||||
public | histogram | FUNCTION | record
|
||||
public | pg_stat_monitor_internal | FUNCTION | record
|
||||
public | pg_stat_monitor_version | FUNCTION | text
|
||||
public | range | FUNCTION | ARRAY
|
||||
(7 rows)
|
||||
|
||||
SET ROLE su;
|
||||
DROP USER u1;
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
DROP USER su;
|
||||
ERROR: current user cannot be dropped
|
||||
|
|
|
@ -24,8 +24,8 @@ COLLATE "C";
|
|||
pg_stat_monitor.pgsm_histogram_buckets | 20 | | postmaster | integer | default | 2 | 50 | | 20 | 20 | f
|
||||
pg_stat_monitor.pgsm_histogram_max | 100000 | | postmaster | integer | default | 10 | 2147483647 | | 100000 | 100000 | f
|
||||
pg_stat_monitor.pgsm_histogram_min | 1 | | postmaster | integer | default | 0 | 2147483647 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_max | 100 | MB | postmaster | integer | default | 1 | 1000 | | 100 | 100 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 10 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_max | 256 | MB | postmaster | integer | default | 10 | 10240 | | 256 | 256 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 20000 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_normalized_query | off | | user | bool | default | | | | off | off | f
|
||||
pg_stat_monitor.pgsm_overflow_target | 1 | | postmaster | integer | default | 0 | 1 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_query_max_len | 2048 | | postmaster | integer | default | 1024 | 2147483647 | | 2048 | 2048 | f
|
||||
|
|
|
@ -24,8 +24,8 @@ COLLATE "C";
|
|||
pg_stat_monitor.pgsm_histogram_buckets | 20 | | postmaster | integer | default | 2 | 50 | | 20 | 20 | f
|
||||
pg_stat_monitor.pgsm_histogram_max | 100000 | | postmaster | integer | default | 10 | 2147483647 | | 100000 | 100000 | f
|
||||
pg_stat_monitor.pgsm_histogram_min | 1 | | postmaster | integer | default | 0 | 2147483647 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_max | 100 | MB | postmaster | integer | default | 1 | 1000 | | 100 | 100 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 10 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_max | 256 | MB | postmaster | integer | default | 10 | 10240 | | 256 | 256 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 20000 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_normalized_query | off | | user | bool | default | | | | off | off | f
|
||||
pg_stat_monitor.pgsm_overflow_target | 1 | | postmaster | integer | default | 0 | 1 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_query_max_len | 2048 | | postmaster | integer | default | 1024 | 2147483647 | | 2048 | 2048 | f
|
||||
|
|
|
@ -40,6 +40,22 @@ SELECT * FROM t2;
|
|||
---
|
||||
(0 rows)
|
||||
|
||||
-- Check that spaces and comments do not generate a different pgsm_query_id
|
||||
SELECT * FROM t2 --WHATEVER;
|
||||
;
|
||||
b
|
||||
---
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM t2 /* ...
|
||||
...
|
||||
More comments to check for spaces.
|
||||
*/
|
||||
;
|
||||
b
|
||||
---
|
||||
(0 rows)
|
||||
|
||||
\c db2
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
|
@ -57,18 +73,18 @@ SELECT * FROM t3;
|
|||
(0 rows)
|
||||
|
||||
\c contrib_regression
|
||||
SELECT datname, pgsm_query_id, query FROM pg_stat_monitor ORDER BY pgsm_query_id, query, datname;
|
||||
datname | pgsm_query_id | query
|
||||
--------------------+----------------------+--------------------------------
|
||||
db2 | -5029137034974447432 | SELECT * FROM t3
|
||||
contrib_regression | 689150021118383254 | SELECT pg_stat_monitor_reset()
|
||||
db1 | 1897482803466821995 | SELECT * FROM t2
|
||||
db1 | 1988437669671417938 | SELECT * FROM t1
|
||||
db2 | 1988437669671417938 | SELECT * FROM t1
|
||||
db1 | 2864453209316739369 | select $1 + $2
|
||||
db2 | 2864453209316739369 | select $1 + $2
|
||||
db1 | 8140395000078788481 | SELECT *, ADD(1, 2) FROM t1
|
||||
db2 | 8140395000078788481 | SELECT *, ADD(1, 2) FROM t1
|
||||
SELECT datname, pgsm_query_id, query, calls FROM pg_stat_monitor ORDER BY pgsm_query_id, query, datname;
|
||||
datname | pgsm_query_id | query | calls
|
||||
--------------------+----------------------+--------------------------------+-------
|
||||
db2 | -5029137034974447432 | SELECT * FROM t3 | 1
|
||||
contrib_regression | 689150021118383254 | SELECT pg_stat_monitor_reset() | 1
|
||||
db1 | 1897482803466821995 | SELECT * FROM t2 | 3
|
||||
db1 | 1988437669671417938 | SELECT * FROM t1 | 1
|
||||
db2 | 1988437669671417938 | SELECT * FROM t1 | 1
|
||||
db1 | 2864453209316739369 | select $1 + $2 | 1
|
||||
db2 | 2864453209316739369 | select $1 + $2 | 1
|
||||
db1 | 8140395000078788481 | SELECT *, ADD(1, 2) FROM t1 | 1
|
||||
db2 | 8140395000078788481 | SELECT *, ADD(1, 2) FROM t1 | 1
|
||||
(9 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
CREATE EXTENSION pg_stat_monitor;
|
||||
CREATE TABLE t1(a int);
|
||||
CREATE TABLE t2(b int);
|
||||
ERROR: relation "t2" already exists
|
||||
INSERT INTO t1 VALUES(generate_series(1,1000));
|
||||
INSERT INTO t2 VALUES(generate_series(1,5000));
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -8557,4 +8556,5 @@ SELECT pg_stat_monitor_reset();
|
|||
(1 row)
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
CREATE USER su WITH SUPERUSER;
|
||||
ERROR: role "su" already exists
|
||||
SET ROLE su;
|
||||
CREATE EXTENSION pg_stat_monitor;
|
||||
CREATE USER u1;
|
||||
CREATE USER u2;
|
||||
GRANT ALL ON SCHEMA public TO u1;
|
||||
GRANT ALL ON SCHEMA public TO u2;
|
||||
SET ROLE su;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SET ROLE u1;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
ERROR: permission denied for function pg_stat_monitor_reset
|
||||
CREATE TABLE t1 (a int);
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
---
|
||||
(0 rows)
|
||||
|
||||
SET ROLE u2;
|
||||
CREATE TABLE t2 (a int);
|
||||
SELECT * FROM t2;
|
||||
a
|
||||
---
|
||||
(0 rows)
|
||||
|
||||
DROP TABLE t2;
|
||||
SET ROLE su;
|
||||
DROP OWNED BY u2;
|
||||
DROP USER u2;
|
||||
SELECT username, query FROM pg_stat_monitor ORDER BY username, query COLLATE "C";
|
||||
username | query
|
||||
----------+---------------------------------
|
||||
su | DROP OWNED BY u2
|
||||
su | DROP USER u2
|
||||
su | SELECT pg_stat_monitor_reset()
|
||||
su | SET ROLE su
|
||||
u1 | CREATE TABLE t1 (a int)
|
||||
u1 | SELECT * FROM t1
|
||||
u1 | SELECT pg_stat_monitor_reset();
|
||||
u1 | SET ROLE u1
|
||||
u2 | CREATE TABLE t2 (a int)
|
||||
u2 | DROP TABLE t2
|
||||
u2 | SELECT * FROM t2
|
||||
u2 | SET ROLE u2
|
||||
(12 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP OWNED BY u1;
|
||||
DROP USER u1;
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
SET ROLE NONE;
|
||||
DROP OWNED BY su;
|
||||
DROP USER su;
|
|
@ -10,6 +10,7 @@ DELETE FROM t1;
|
|||
SELECT b FROM t2 FOR UPDATE;
|
||||
TRUNCATE t1;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
SELECT query, cmd_type, cmd_type_text FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ SELECT * FROM t1,t2 WHERE t1.a = t2.b;
|
|||
SELECT * FROM t3,t4 WHERE t3.c = t4.d;
|
||||
|
||||
\c contrib_regression
|
||||
DROP DATABASE db2;
|
||||
|
||||
SELECT datname, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
||||
|
@ -27,11 +29,6 @@ SELECT pg_stat_monitor_reset();
|
|||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
||||
\c db2
|
||||
DROP TABLE t3;
|
||||
DROP TABLE t4;
|
||||
|
||||
\c contrib_regression
|
||||
DROP DATABASE db1;
|
||||
DROP DATABASE db2;
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
|
|
|
@ -14,3 +14,4 @@ SELECT routine_schema, routine_name, routine_type, data_type FROM information_sc
|
|||
SET ROLE su;
|
||||
DROP USER u1;
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
DROP USER su;
|
||||
|
|
|
@ -29,6 +29,14 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT * FROM t1;
|
||||
SELECT *, ADD(1, 2) FROM t1;
|
||||
SELECT * FROM t2;
|
||||
-- Check that spaces and comments do not generate a different pgsm_query_id
|
||||
SELECT * FROM t2 --WHATEVER;
|
||||
;
|
||||
SELECT * FROM t2 /* ...
|
||||
...
|
||||
More comments to check for spaces.
|
||||
*/
|
||||
;
|
||||
|
||||
\c db2
|
||||
SELECT * FROM t1;
|
||||
|
@ -36,7 +44,7 @@ SELECT *, ADD(1, 2) FROM t1;
|
|||
SELECT * FROM t3;
|
||||
|
||||
\c contrib_regression
|
||||
SELECT datname, pgsm_query_id, query FROM pg_stat_monitor ORDER BY pgsm_query_id, query, datname;
|
||||
SELECT datname, pgsm_query_id, query, calls FROM pg_stat_monitor ORDER BY pgsm_query_id, query, datname;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
||||
\c db1
|
||||
|
|
|
@ -16,4 +16,5 @@ SELECT query, rows FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
|||
SELECT pg_stat_monitor_reset();
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
|
|
|
@ -6,25 +6,37 @@ CREATE EXTENSION pg_stat_monitor;
|
|||
CREATE USER u1;
|
||||
CREATE USER u2;
|
||||
|
||||
SET ROLE su;
|
||||
GRANT ALL ON SCHEMA public TO u1;
|
||||
GRANT ALL ON SCHEMA public TO u2;
|
||||
|
||||
SET ROLE su;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
||||
SET ROLE u1;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
CREATE TABLE t1 (a int);
|
||||
SELECT * FROM t1;
|
||||
|
||||
SET ROLE u2;
|
||||
CREATE TABLE t2 (a int);
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
SET ROLE su;
|
||||
SELECT userid, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
|
||||
DROP OWNED BY u2;
|
||||
DROP USER u2;
|
||||
|
||||
SELECT username, query FROM pg_stat_monitor ORDER BY username, query COLLATE "C";
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
||||
DROP OWNED BY u1;
|
||||
DROP USER u1;
|
||||
DROP USER u2;
|
||||
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
|
||||
SET ROLE NONE;
|
||||
|
||||
DROP OWNED BY su;
|
||||
DROP USER su;
|
||||
|
|
|
@ -36,7 +36,7 @@ my %pg_versions_pgsm_columns = ( 15 => "application_name,blk_read_time," .
|
|||
"shared_blks_written,sqlcode,stddev_exec_time,stddev_plan_time," .
|
||||
"temp_blk_read_time,temp_blk_write_time,temp_blks_read,temp_blks_written," .
|
||||
"top_query,top_queryid,toplevel,total_exec_time,total_plan_time," .
|
||||
"user,userid,wal_bytes,wal_fpi,wal_records",
|
||||
"userid,username,wal_bytes,wal_fpi,wal_records",
|
||||
14 => "application_name,blk_read_time," .
|
||||
"blk_write_time,bucket,bucket_done,bucket_start_time,calls," .
|
||||
"client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time," .
|
||||
|
@ -47,7 +47,7 @@ my %pg_versions_pgsm_columns = ( 15 => "application_name,blk_read_time," .
|
|||
"rows,shared_blks_dirtied,shared_blks_hit,shared_blks_read," .
|
||||
"shared_blks_written,sqlcode,stddev_exec_time,stddev_plan_time," .
|
||||
"temp_blks_read,temp_blks_written,top_query,top_queryid,toplevel," .
|
||||
"total_exec_time,total_plan_time,user,userid,wal_bytes,wal_fpi,wal_records",
|
||||
"total_exec_time,total_plan_time,userid,username,wal_bytes,wal_fpi,wal_records",
|
||||
13 => "application_name,blk_read_time," .
|
||||
"blk_write_time,bucket,bucket_done,bucket_start_time,calls," .
|
||||
"client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time," .
|
||||
|
@ -58,7 +58,7 @@ my %pg_versions_pgsm_columns = ( 15 => "application_name,blk_read_time," .
|
|||
"rows,shared_blks_dirtied,shared_blks_hit,shared_blks_read," .
|
||||
"shared_blks_written,sqlcode,stddev_exec_time,stddev_plan_time," .
|
||||
"temp_blks_read,temp_blks_written,top_query,top_queryid,toplevel," .
|
||||
"total_exec_time,total_plan_time,user,userid,wal_bytes,wal_fpi,wal_records",
|
||||
"total_exec_time,total_plan_time,userid,username,wal_bytes,wal_fpi,wal_records",
|
||||
12 => "application_name,blk_read_time,blk_write_time,bucket,bucket_done," .
|
||||
"bucket_start_time,calls,client_ip,cmd_type,cmd_type_text,comments," .
|
||||
"cpu_sys_time,cpu_user_time,datname,dbid,elevel,local_blks_dirtied," .
|
||||
|
@ -66,7 +66,7 @@ my %pg_versions_pgsm_columns = ( 15 => "application_name,blk_read_time," .
|
|||
"message,min_time,pgsm_query_id,planid,query,query_plan,queryid,relations,resp_calls," .
|
||||
"rows,shared_blks_dirtied,shared_blks_hit,shared_blks_read," .
|
||||
"shared_blks_written,sqlcode,stddev_time,temp_blks_read,temp_blks_written," .
|
||||
"top_query,top_queryid,total_time,user,userid"
|
||||
"top_query,top_queryid,total_time,userid,username"
|
||||
);
|
||||
|
||||
# Start server
|
||||
|
|
|
@ -14,8 +14,8 @@ SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals
|
|||
pg_stat_monitor.pgsm_histogram_buckets | 20 | | postmaster | integer | default | 2 | 50 | | 20 | 20 | f
|
||||
pg_stat_monitor.pgsm_histogram_max | 100000 | | postmaster | integer | default | 10 | 2147483647 | | 100000 | 100000 | f
|
||||
pg_stat_monitor.pgsm_histogram_min | 1 | | postmaster | integer | default | 0 | 2147483647 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_max | 100 | MB | postmaster | integer | default | 1 | 1000 | | 100 | 100 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 10 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_max | 256 | MB | postmaster | integer | default | 10 | 10240 | | 256 | 256 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 20000 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_normalized_query | off | | user | bool | default | | | | off | off | f
|
||||
pg_stat_monitor.pgsm_overflow_target | 1 | | postmaster | integer | default | 0 | 1 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_query_max_len | 2048 | | postmaster | integer | default | 1024 | 2147483647 | | 2048 | 2048 | f
|
||||
|
@ -41,8 +41,8 @@ SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals
|
|||
pg_stat_monitor.pgsm_histogram_buckets | 20 | | postmaster | integer | default | 2 | 50 | | 20 | 20 | f
|
||||
pg_stat_monitor.pgsm_histogram_max | 100000 | | postmaster | integer | default | 10 | 2147483647 | | 100000 | 100000 | f
|
||||
pg_stat_monitor.pgsm_histogram_min | 1 | | postmaster | integer | default | 0 | 2147483647 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_max | 100 | MB | postmaster | integer | default | 1 | 1000 | | 100 | 100 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 10 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_max | 256 | MB | postmaster | integer | default | 10 | 10240 | | 256 | 256 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 20000 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_normalized_query | off | | user | bool | default | | | | off | off | f
|
||||
pg_stat_monitor.pgsm_overflow_target | 1 | | postmaster | integer | default | 0 | 1 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_query_max_len | 2048 | | postmaster | integer | default | 1024 | 2147483647 | | 2048 | 2048 | f
|
||||
|
|
|
@ -14,8 +14,8 @@ SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals
|
|||
pg_stat_monitor.pgsm_histogram_buckets | 20 | | postmaster | integer | default | 2 | 50 | | 20 | 20 | f
|
||||
pg_stat_monitor.pgsm_histogram_max | 100000 | | postmaster | integer | default | 10 | 2147483647 | | 100000 | 100000 | f
|
||||
pg_stat_monitor.pgsm_histogram_min | 1 | | postmaster | integer | default | 0 | 2147483647 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_max | 100 | MB | postmaster | integer | default | 1 | 1000 | | 100 | 100 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 10 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_max | 256 | MB | postmaster | integer | default | 10 | 10240 | | 256 | 256 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 20000 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_normalized_query | off | | user | bool | default | | | | off | off | f
|
||||
pg_stat_monitor.pgsm_overflow_target | 1 | | postmaster | integer | default | 0 | 1 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_query_max_len | 2048 | | postmaster | integer | default | 1024 | 2147483647 | | 2048 | 2048 | f
|
||||
|
@ -40,8 +40,8 @@ SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals
|
|||
pg_stat_monitor.pgsm_histogram_buckets | 20 | | postmaster | integer | default | 2 | 50 | | 20 | 20 | f
|
||||
pg_stat_monitor.pgsm_histogram_max | 100000 | | postmaster | integer | default | 10 | 2147483647 | | 100000 | 100000 | f
|
||||
pg_stat_monitor.pgsm_histogram_min | 1 | | postmaster | integer | default | 0 | 2147483647 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_max | 100 | MB | postmaster | integer | default | 1 | 1000 | | 100 | 100 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 10 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_max | 256 | MB | postmaster | integer | default | 10 | 10240 | | 256 | 256 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 20000 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_normalized_query | off | | user | bool | default | | | | off | off | f
|
||||
pg_stat_monitor.pgsm_overflow_target | 1 | | postmaster | integer | default | 0 | 1 | | 1 | 1 | f
|
||||
pg_stat_monitor.pgsm_query_max_len | 2048 | | postmaster | integer | default | 1024 | 2147483647 | | 2048 | 2048 | f
|
||||
|
|
|
@ -8,7 +8,7 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max_buckets';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
----------------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max_buckets | 1 | | postmaster | integer | configuration file | 1 | 10 | | 10 | 1 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 1 | | postmaster | integer | configuration file | 1 | 20000 | | 10 | 1 | f
|
||||
(1 row)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -20,7 +20,7 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max_buckets';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
----------------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max_buckets | 2 | | postmaster | integer | configuration file | 1 | 10 | | 10 | 2 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 2 | | postmaster | integer | configuration file | 1 | 20000 | | 10 | 2 | f
|
||||
(1 row)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -32,7 +32,7 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max_buckets';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
----------------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max_buckets | 5 | | postmaster | integer | configuration file | 1 | 10 | | 10 | 5 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 5 | | postmaster | integer | configuration file | 1 | 20000 | | 10 | 5 | f
|
||||
(1 row)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -44,7 +44,19 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max_buckets';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
----------------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | configuration file | 1 | 10 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | configuration file | 1 | 20000 | | 10 | 10 | f
|
||||
(1 row)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max_buckets';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
----------------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max_buckets | 11 | | postmaster | integer | configuration file | 1 | 20000 | | 10 | 11 | f
|
||||
(1 row)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -56,19 +68,7 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max_buckets';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
----------------------------------+---------+------+------------+---------+---------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 10 | | 10 | 10 | f
|
||||
(1 row)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max_buckets';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
----------------------------------+---------+------+------------+---------+---------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 10 | | 10 | 10 | f
|
||||
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 20000 | | 10 | 10 | f
|
||||
(1 row)
|
||||
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
|
|
|
@ -8,7 +8,7 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
--------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max | 1000 | MB | postmaster | integer | configuration file | 1 | 1000 | | 100 | 1000 | f
|
||||
pg_stat_monitor.pgsm_max | 1000 | MB | postmaster | integer | configuration file | 10 | 10240 | | 256 | 1000 | f
|
||||
(1 row)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -20,7 +20,7 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
--------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max | 500 | MB | postmaster | integer | configuration file | 1 | 1000 | | 100 | 500 | f
|
||||
pg_stat_monitor.pgsm_max | 500 | MB | postmaster | integer | configuration file | 10 | 10240 | | 256 | 500 | f
|
||||
(1 row)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -32,7 +32,7 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
--------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max | 100 | MB | postmaster | integer | configuration file | 1 | 1000 | | 100 | 100 | f
|
||||
pg_stat_monitor.pgsm_max | 100 | MB | postmaster | integer | configuration file | 10 | 10240 | | 256 | 100 | f
|
||||
(1 row)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -44,7 +44,7 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
--------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max | 10 | MB | postmaster | integer | configuration file | 1 | 1000 | | 100 | 10 | f
|
||||
pg_stat_monitor.pgsm_max | 10 | MB | postmaster | integer | configuration file | 10 | 10240 | | 256 | 10 | f
|
||||
(1 row)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -56,7 +56,7 @@ SELECT pg_stat_monitor_reset();
|
|||
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_max';
|
||||
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||
--------------------------+---------+------+------------+---------+---------+---------+---------+----------+----------+-----------+-----------------
|
||||
pg_stat_monitor.pgsm_max | 100 | MB | postmaster | integer | default | 1 | 1000 | | 100 | 100 | f
|
||||
pg_stat_monitor.pgsm_max | 256 | MB | postmaster | integer | default | 10 | 10240 | | 256 | 256 | f
|
||||
(1 row)
|
||||
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
|
|
Loading…
Reference in New Issue