Fixing code indentation with pgindent

pull/389/head
Hamid Akhtar 2023-02-27 14:18:19 +05:00 committed by Muhammad Usama
parent 1883b05fc7
commit faa938b8f1
4 changed files with 3440 additions and 3576 deletions

466
guc.c
View File

@ -19,23 +19,23 @@
#include "pg_stat_monitor.h" #include "pg_stat_monitor.h"
/* GUC variables */ /* GUC variables */
int pgsm_max; int pgsm_max;
int pgsm_query_max_len; int pgsm_query_max_len;
int pgsm_bucket_time; int pgsm_bucket_time;
int pgsm_max_buckets; int pgsm_max_buckets;
int pgsm_histogram_buckets; int pgsm_histogram_buckets;
double pgsm_histogram_min; double pgsm_histogram_min;
double pgsm_histogram_max; double pgsm_histogram_max;
int pgsm_query_shared_buffer; int pgsm_query_shared_buffer;
bool pgsm_track_planning; bool pgsm_track_planning;
bool pgsm_extract_comments; bool pgsm_extract_comments;
bool pgsm_enable_query_plan; bool pgsm_enable_query_plan;
bool pgsm_enable_overflow; bool pgsm_enable_overflow;
bool pgsm_normalized_query; bool pgsm_normalized_query;
bool pgsm_track_utility; bool pgsm_track_utility;
bool pgsm_enable_pgsm_query_id; bool pgsm_enable_pgsm_query_id;
int pgsm_track; int pgsm_track;
static int pgsm_overflow_target; /* Not used since 2.0 */ static int pgsm_overflow_target; /* Not used since 2.0 */
/* Check hooks to ensure histogram_min < histogram_max */ /* Check hooks to ensure histogram_min < histogram_max */
static bool check_histogram_min(double *newval, void **extra, GucSource source); static bool check_histogram_min(double *newval, void **extra, GucSource source);
@ -48,230 +48,230 @@ void
init_guc(void) init_guc(void)
{ {
DefineCustomIntVariable("pg_stat_monitor.pgsm_max", /* name */ DefineCustomIntVariable("pg_stat_monitor.pgsm_max", /* name */
"Sets the maximum size of shared memory in (MB) used for statement's metadata tracked by pg_stat_monitor.", /* short_desc */ "Sets the maximum size of shared memory in (MB) used for statement's metadata tracked by pg_stat_monitor.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_max, /* value address */ &pgsm_max, /* value address */
256, /* boot value */ 256, /* boot value */
10, /* min value */ 10, /* min value */
10240, /* max value */ 10240, /* max value */
PGC_POSTMASTER, /* context */ PGC_POSTMASTER, /* context */
GUC_UNIT_MB, /* flags */ GUC_UNIT_MB, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomIntVariable("pg_stat_monitor.pgsm_query_max_len", /* name */ DefineCustomIntVariable("pg_stat_monitor.pgsm_query_max_len", /* name */
"Sets the maximum length of query.", /* short_desc */ "Sets the maximum length of query.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_query_max_len, /* value address */ &pgsm_query_max_len, /* value address */
2048, /* boot value */ 2048, /* boot value */
1024, /* min value */ 1024, /* min value */
INT_MAX, /* max value */ INT_MAX, /* max value */
PGC_POSTMASTER, /* context */ PGC_POSTMASTER, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomIntVariable("pg_stat_monitor.pgsm_max_buckets", /* name */ DefineCustomIntVariable("pg_stat_monitor.pgsm_max_buckets", /* name */
"Sets the maximum number of buckets.", /* short_desc */ "Sets the maximum number of buckets.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_max_buckets, /* value address */ &pgsm_max_buckets, /* value address */
10, /* boot value */ 10, /* boot value */
1, /* min value */ 1, /* min value */
20000, /* max value */ 20000, /* max value */
PGC_POSTMASTER, /* context */ PGC_POSTMASTER, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomIntVariable("pg_stat_monitor.pgsm_bucket_time", /* name */ DefineCustomIntVariable("pg_stat_monitor.pgsm_bucket_time", /* name */
"Sets the time in seconds per bucket.", /* short_desc */ "Sets the time in seconds per bucket.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_bucket_time, /* value address */ &pgsm_bucket_time, /* value address */
60, /* boot value */ 60, /* boot value */
1, /* min value */ 1, /* min value */
INT_MAX, /* max value */ INT_MAX, /* max value */
PGC_POSTMASTER, /* context */ PGC_POSTMASTER, /* context */
GUC_UNIT_S, /* flags */ GUC_UNIT_S, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomRealVariable("pg_stat_monitor.pgsm_histogram_min", /* name */ DefineCustomRealVariable("pg_stat_monitor.pgsm_histogram_min", /* name */
"Sets the time in millisecond.", /* short_desc */ "Sets the time in millisecond.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_histogram_min, /* value address */ &pgsm_histogram_min, /* value address */
1, /* boot value */ 1, /* boot value */
0, /* min value */ 0, /* min value */
HISTOGRAM_MAX_TIME, /* max value */ HISTOGRAM_MAX_TIME, /* max value */
PGC_POSTMASTER, /* context */ PGC_POSTMASTER, /* context */
GUC_UNIT_MS, /* flags */ GUC_UNIT_MS, /* flags */
check_histogram_min, /* check_hook */ check_histogram_min, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomRealVariable("pg_stat_monitor.pgsm_histogram_max", /* name */ DefineCustomRealVariable("pg_stat_monitor.pgsm_histogram_max", /* name */
"Sets the time in millisecond.", /* short_desc */ "Sets the time in millisecond.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_histogram_max, /* value address */ &pgsm_histogram_max, /* value address */
100000.0, /* boot value */ 100000.0, /* boot value */
10.0, /* min value */ 10.0, /* min value */
HISTOGRAM_MAX_TIME, /* max value */ HISTOGRAM_MAX_TIME, /* max value */
PGC_POSTMASTER, /* context */ PGC_POSTMASTER, /* context */
GUC_UNIT_MS, /* flags */ GUC_UNIT_MS, /* flags */
check_histogram_max, /* check_hook */ check_histogram_max, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomIntVariable("pg_stat_monitor.pgsm_histogram_buckets", /* name */ DefineCustomIntVariable("pg_stat_monitor.pgsm_histogram_buckets", /* name */
"Sets the maximum number of histogram buckets.", /* short_desc */ "Sets the maximum number of histogram buckets.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_histogram_buckets, /* value address */ &pgsm_histogram_buckets, /* value address */
20, /* boot value */ 20, /* boot value */
2, /* min value */ 2, /* min value */
MAX_RESPONSE_BUCKET, /* max value */ MAX_RESPONSE_BUCKET, /* max value */
PGC_POSTMASTER, /* context */ PGC_POSTMASTER, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomIntVariable("pg_stat_monitor.pgsm_query_shared_buffer", /* name */ DefineCustomIntVariable("pg_stat_monitor.pgsm_query_shared_buffer", /* name */
"Sets the maximum size of shared memory in (MB) used for query tracked by pg_stat_monitor.", /* short_desc */ "Sets the maximum size of shared memory in (MB) used for query tracked by pg_stat_monitor.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_query_shared_buffer, /* value address */ &pgsm_query_shared_buffer, /* value address */
20, /* boot value */ 20, /* boot value */
1, /* min value */ 1, /* min value */
10000, /* max value */ 10000, /* max value */
PGC_POSTMASTER, /* context */ PGC_POSTMASTER, /* context */
GUC_UNIT_MB, /* flags */ GUC_UNIT_MB, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
/* deprecated in V 2.0 */ /* deprecated in V 2.0 */
DefineCustomIntVariable("pg_stat_monitor.pgsm_overflow_target", /* name */ DefineCustomIntVariable("pg_stat_monitor.pgsm_overflow_target", /* name */
"Sets the overflow target for pg_stat_monitor. (Deprecated, use pgsm_enable_overflow)", /* short_desc */ "Sets the overflow target for pg_stat_monitor. (Deprecated, use pgsm_enable_overflow)", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_overflow_target, /* value address */ &pgsm_overflow_target, /* value address */
1, /* boot value */ 1, /* boot value */
0, /* min value */ 0, /* min value */
1, /* max value */ 1, /* max value */
PGC_POSTMASTER, /* context */ PGC_POSTMASTER, /* context */
0, /* flags */ 0, /* flags */
check_overflow_targer, /* check_hook */ check_overflow_targer, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomBoolVariable("pg_stat_monitor.pgsm_track_utility", /* name */ DefineCustomBoolVariable("pg_stat_monitor.pgsm_track_utility", /* name */
"Selects whether utility commands are tracked.", /* short_desc */ "Selects whether utility commands are tracked.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_track_utility, /* value address */ &pgsm_track_utility, /* value address */
true, /* boot value */ true, /* boot value */
PGC_USERSET, /* context */ PGC_USERSET, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomBoolVariable("pg_stat_monitor.pgsm_enable_pgsm_query_id", /* name */ DefineCustomBoolVariable("pg_stat_monitor.pgsm_enable_pgsm_query_id", /* name */
"Enable/disable PGSM specific query id calculation which is very useful in comparing same query across databases and clusters..", /* short_desc */ "Enable/disable PGSM specific query id calculation which is very useful in comparing same query across databases and clusters..", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_enable_pgsm_query_id, /* value address */ &pgsm_enable_pgsm_query_id, /* value address */
true, /* boot value */ true, /* boot value */
PGC_USERSET, /* context */ PGC_USERSET, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomBoolVariable("pg_stat_monitor.pgsm_normalized_query", /* name */ DefineCustomBoolVariable("pg_stat_monitor.pgsm_normalized_query", /* name */
"Selects whether save query in normalized format.", /* short_desc */ "Selects whether save query in normalized format.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_normalized_query, /* value address */ &pgsm_normalized_query, /* value address */
false, /* boot value */ false, /* boot value */
PGC_USERSET, /* context */ PGC_USERSET, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomBoolVariable("pg_stat_monitor.pgsm_enable_overflow", /* name */ DefineCustomBoolVariable("pg_stat_monitor.pgsm_enable_overflow", /* name */
"Enable/Disable pg_stat_monitor to grow beyond shared memory into swap space.", /* short_desc */ "Enable/Disable pg_stat_monitor to grow beyond shared memory into swap space.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_enable_overflow, /* value address */ &pgsm_enable_overflow, /* value address */
true, /* boot value */ true, /* boot value */
PGC_POSTMASTER, /* context */ PGC_POSTMASTER, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomBoolVariable("pg_stat_monitor.pgsm_enable_query_plan", /* name */ DefineCustomBoolVariable("pg_stat_monitor.pgsm_enable_query_plan", /* name */
"Enable/Disable query plan monitoring.", /* short_desc */ "Enable/Disable query plan monitoring.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_enable_query_plan, /* value address */ &pgsm_enable_query_plan, /* value address */
false, /* boot value */ false, /* boot value */
PGC_USERSET, /* context */ PGC_USERSET, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomBoolVariable("pg_stat_monitor.pgsm_extract_comments", /* name */ DefineCustomBoolVariable("pg_stat_monitor.pgsm_extract_comments", /* name */
"Enable/Disable extracting comments from queries.", /* short_desc */ "Enable/Disable extracting comments from queries.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_extract_comments, /* value address */ &pgsm_extract_comments, /* value address */
false, /* boot value */ false, /* boot value */
PGC_USERSET, /* context */ PGC_USERSET, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
DefineCustomEnumVariable("pg_stat_monitor.pgsm_track", /* name */ DefineCustomEnumVariable("pg_stat_monitor.pgsm_track", /* name */
"Selects which statements are tracked by pg_stat_monitor.", /* short_desc */ "Selects which statements are tracked by pg_stat_monitor.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_track, /* value address */ &pgsm_track, /* value address */
PGSM_TRACK_TOP, /* boot value */ PGSM_TRACK_TOP, /* boot value */
track_options, /* enum options */ track_options, /* enum options */
PGC_USERSET, /* context */ PGC_USERSET, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
#if PG_VERSION_NUM >= 130000 #if PG_VERSION_NUM >= 130000
DefineCustomBoolVariable("pg_stat_monitor.pgsm_track_planning", /* name */ DefineCustomBoolVariable("pg_stat_monitor.pgsm_track_planning", /* name */
"Selects whether planning statistics are tracked.", /* short_desc */ "Selects whether planning statistics are tracked.", /* short_desc */
NULL, /* long_desc */ NULL, /* long_desc */
&pgsm_track_planning, /* value address */ &pgsm_track_planning, /* value address */
false, /* boot value */ false, /* boot value */
PGC_USERSET, /* context */ PGC_USERSET, /* context */
0, /* flags */ 0, /* flags */
NULL, /* check_hook */ NULL, /* check_hook */
NULL, /* assign_hook */ NULL, /* assign_hook */
NULL /* show_hook */ NULL /* show_hook */
); );
#endif #endif
} }
@ -280,23 +280,23 @@ init_guc(void)
static bool static bool
check_histogram_min(double *newval, void **extra, GucSource source) check_histogram_min(double *newval, void **extra, GucSource source)
{ {
/* /*
* During module initialization PGSM_HISTOGRAM_MIN is initialized before * During module initialization PGSM_HISTOGRAM_MIN is initialized before
* PGSM_HISTOGRAM_MAX, in this case PGSM_HISTOGRAM_MAX will be zero. * PGSM_HISTOGRAM_MAX, in this case PGSM_HISTOGRAM_MAX will be zero.
*/ */
return (pgsm_histogram_max == 0 || (*newval + 1.0) <= pgsm_histogram_max); return (pgsm_histogram_max == 0 || (*newval + 1.0) <= pgsm_histogram_max);
} }
static bool static bool
check_histogram_max(double *newval, void **extra, GucSource source) check_histogram_max(double *newval, void **extra, GucSource source)
{ {
return (*newval >= (pgsm_histogram_min + 1.0)); return (*newval >= (pgsm_histogram_min + 1.0));
} }
static bool static bool
check_overflow_targer(int *newval, void **extra, GucSource source) check_overflow_targer(int *newval, void **extra, GucSource source)
{ {
if (source != PGC_S_DEFAULT) if (source != PGC_S_DEFAULT)
elog(WARNING,"pg_stat_monitor.pgsm_overflow_target is deprecated, use pgsm_enable_overflow"); elog(WARNING, "pg_stat_monitor.pgsm_overflow_target is deprecated, use pgsm_enable_overflow");
return true; return true;
} }

View File

@ -18,18 +18,18 @@
#include "nodes/pg_list.h" #include "nodes/pg_list.h"
#include "pg_stat_monitor.h" #include "pg_stat_monitor.h"
static pgsmLocalState pgsmStateLocal; static pgsmLocalState pgsmStateLocal;
static PGSM_HASH_TABLE_HANDLE pgsm_create_bucket_hash(pgsmSharedState *pgsm, 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 Size pgsm_get_shared_area_size(void);
static void InitializeSharedState(pgsmSharedState *pgsm); static void InitializeSharedState(pgsmSharedState * pgsm);
#if USE_DYNAMIC_HASH #if USE_DYNAMIC_HASH
/* parameter for the shared hash */ /* parameter for the shared hash */
static dshash_parameters dsh_params = { static dshash_parameters dsh_params = {
sizeof(pgsmHashKey), sizeof(pgsmHashKey),
sizeof(pgsmEntry), sizeof(pgsmEntry),
dshash_memcmp, dshash_memcmp,
dshash_memhash dshash_memhash
}; };
#endif #endif
@ -40,28 +40,26 @@ static dshash_parameters dsh_params = {
*/ */
static Size static Size
pgsm_query_area_size(void) pgsm_query_area_size(void) {
{ Size sz = MAX_QUERY_BUF;
Size sz = MAX_QUERY_BUF; #if USE_DYNAMIC_HASH
#if USE_DYNAMIC_HASH /* Dynamic hash also lives DSA area */
/* Dynamic hash also lives DSA area */ sz = add_size(sz, MAX_BUCKETS_MEM);
sz = add_size(sz, MAX_BUCKETS_MEM); #endif
#endif return MAXALIGN(sz);
return MAXALIGN(sz);
} }
/* /*
* Total shared memory area required by pgsm * Total shared memory area required by pgsm
*/ */
Size Size
pgsm_ShmemSize(void) pgsm_ShmemSize(void) {
{
Size sz = MAXALIGN(sizeof(pgsmSharedState)); Size sz = MAXALIGN(sizeof(pgsmSharedState));
sz = add_size(sz, MAX_QUERY_BUF); sz = add_size(sz, MAX_QUERY_BUF);
#if USE_DYNAMIC_HASH #if USE_DYNAMIC_HASH
sz = add_size(sz, MAX_BUCKETS_MEM); sz = add_size(sz, MAX_BUCKETS_MEM);
#else #else
sz = add_size(sz, hash_estimate_size(MAX_BUCKET_ENTRIES, sizeof(pgsmEntry))); sz = add_size(sz, hash_estimate_size(MAX_BUCKET_ENTRIES, sizeof(pgsmEntry)));
#endif #endif
return MAXALIGN(sz); return MAXALIGN(sz);
} }
@ -72,91 +70,90 @@ pgsm_ShmemSize(void)
* get allocated as a single shared memory chunk. * get allocated as a single shared memory chunk.
*/ */
static Size static Size
pgsm_get_shared_area_size(void) pgsm_get_shared_area_size(void) {
{ Size sz;
Size sz; #if USE_DYNAMIC_HASH
#if USE_DYNAMIC_HASH sz = pgsm_ShmemSize();
sz = pgsm_ShmemSize(); #else
#else sz = MAXALIGN(sizeof(pgsmSharedState));
sz = MAXALIGN(sizeof(pgsmSharedState)); sz = add_size(sz, pgsm_query_area_size());
sz = add_size(sz, pgsm_query_area_size()); #endif
#endif return sz;
return sz;
} }
void void
pgsm_startup(void) pgsm_startup(void)
{ {
bool found = false; bool found = false;
pgsmSharedState *pgsm; pgsmSharedState *pgsm;
/* reset in case this is a restart within the postmaster */ /* reset in case this is a restart within the postmaster */
pgsmStateLocal.dsa = NULL; pgsmStateLocal.dsa = NULL;
pgsmStateLocal.shared_hash = NULL; pgsmStateLocal.shared_hash = NULL;
pgsmStateLocal.shared_pgsmState = NULL; pgsmStateLocal.shared_pgsmState = NULL;
/*
* Create or attach to the shared memory state, including hash table
*/
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
pgsm = ShmemInitStruct("pg_stat_monitor", pgsm_get_shared_area_size(), &found);
if (!found) {
/* First time through ... */
dsa_area *dsa;
char *p = (char *) pgsm;
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());
pgsm->hash_handle = pgsm_create_bucket_hash(pgsm, dsa);
/* /*
* Create or attach to the shared memory state, including hash table * If overflow is enabled, set the DSA size to unlimited, and allow
* the DSA to grow beyond the shared memory space into the swap area
*/ */
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); if (pgsm_enable_overflow)
dsa_set_size_limit(dsa, -1);
pgsm = ShmemInitStruct("pg_stat_monitor", pgsm_get_shared_area_size(), &found); pgsmStateLocal.shared_pgsmState = pgsm;
if (!found) /*
{ * Postmaster will never access the dsa again, thus free it's local
/* First time through ... */ * references.
dsa_area *dsa; */
char *p = (char *) pgsm; dsa_detach(dsa);
}
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());
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
* into the swap area*/
if (pgsm_enable_overflow)
dsa_set_size_limit(dsa, -1);
pgsmStateLocal.shared_pgsmState = pgsm;
/*
* Postmaster will never access the dsa again, thus free it's local
* references.
*/
dsa_detach(dsa);
}
#ifdef BENCHMARK #ifdef BENCHMARK
init_hook_stats(); init_hook_stats();
#endif #endif
LWLockRelease(AddinShmemInitLock); LWLockRelease(AddinShmemInitLock);
/* /*
* If we're in the postmaster (or a standalone backend...), set up a shmem * If we're in the postmaster (or a standalone backend...), set up a shmem
* exit hook to dump the statistics to disk. * exit hook to dump the statistics to disk.
*/ */
on_shmem_exit(pgsm_shmem_shutdown, (Datum) 0); on_shmem_exit(pgsm_shmem_shutdown, (Datum) 0);
} }
static void static void
InitializeSharedState(pgsmSharedState *pgsm) InitializeSharedState(pgsmSharedState * pgsm)
{ {
pg_atomic_init_u64(&pgsm->current_wbucket, 0); pg_atomic_init_u64(&pgsm->current_wbucket, 0);
pg_atomic_init_u64(&pgsm->prev_bucket_sec, 0); pg_atomic_init_u64(&pgsm->prev_bucket_sec, 0);
memset(&pgsm->bucket_entry, 0, MAX_BUCKETS * sizeof(uint64)); memset(&pgsm->bucket_entry, 0, MAX_BUCKETS * sizeof(uint64));
pgsm->pgsm_mem_cxt = AllocSetContextCreate(TopMemoryContext, pgsm->pgsm_mem_cxt = AllocSetContextCreate(TopMemoryContext,
"pg_stat_monitor local store", "pg_stat_monitor local store",
ALLOCSET_DEFAULT_SIZES); ALLOCSET_DEFAULT_SIZES);
} }
@ -164,25 +161,24 @@ InitializeSharedState(pgsmSharedState *pgsm)
* Create the classic or dshahs hash table for storing the query statistics. * Create the classic or dshahs hash table for storing the query statistics.
*/ */
static PGSM_HASH_TABLE_HANDLE static PGSM_HASH_TABLE_HANDLE
pgsm_create_bucket_hash(pgsmSharedState *pgsm, dsa_area *dsa) pgsm_create_bucket_hash(pgsmSharedState * pgsm, dsa_area * dsa) {
{ PGSM_HASH_TABLE_HANDLE bucket_hash;
PGSM_HASH_TABLE_HANDLE bucket_hash;
#if USE_DYNAMIC_HASH #if USE_DYNAMIC_HASH
dshash_table *dsh; dshash_table *dsh;
pgsm->hash_tranche_id = LWLockNewTrancheId(); pgsm->hash_tranche_id = LWLockNewTrancheId();
dsh_params.tranche_id = pgsm->hash_tranche_id; dsh_params.tranche_id = pgsm->hash_tranche_id;
dsh = dshash_create(dsa, &dsh_params, 0); dsh = dshash_create(dsa, &dsh_params, 0);
bucket_hash = dshash_get_hash_table_handle(dsh); bucket_hash = dshash_get_hash_table_handle(dsh);
dshash_detach(dsh); dshash_detach(dsh);
#else #else
HASHCTL info; HASHCTL info;
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.keysize = sizeof(pgsmHashKey); info.keysize = sizeof(pgsmHashKey);
info.entrysize = sizeof(pgsmEntry); info.entrysize = sizeof(pgsmEntry);
bucket_hash = ShmemInitHash("pg_stat_monitor: bucket hashtable", MAX_BUCKET_ENTRIES, MAX_BUCKET_ENTRIES, &info, HASH_ELEM | HASH_BLOBS); bucket_hash = ShmemInitHash("pg_stat_monitor: bucket hashtable", MAX_BUCKET_ENTRIES, MAX_BUCKET_ENTRIES, &info, HASH_ELEM | HASH_BLOBS);
#endif #endif
return bucket_hash; return bucket_hash;
} }
/* /*
@ -197,53 +193,54 @@ pgsm_create_bucket_hash(pgsmSharedState *pgsm, dsa_area *dsa)
void void
pgsm_attach_shmem(void) pgsm_attach_shmem(void)
{ {
MemoryContext oldcontext; MemoryContext oldcontext;
if (pgsmStateLocal.dsa) if (pgsmStateLocal.dsa)
return; return;
/* /*
* We want the dsa to remain valid throughout the lifecycle of this process. * We want the dsa to remain valid throughout the lifecycle of this
* so switch to TopMemoryContext before attaching * process. so switch to TopMemoryContext before attaching
*/ */
oldcontext = MemoryContextSwitchTo(TopMemoryContext); oldcontext = MemoryContextSwitchTo(TopMemoryContext);
pgsmStateLocal.dsa = dsa_attach_in_place(pgsmStateLocal.shared_pgsmState->raw_dsa_area, pgsmStateLocal.dsa = dsa_attach_in_place(pgsmStateLocal.shared_pgsmState->raw_dsa_area,
NULL); NULL);
/* pin the attached area to keep the area attached until end of /*
* session or explicit detach. * pin the attached area to keep the area attached until end of session or
*/ * explicit detach.
dsa_pin_mapping(pgsmStateLocal.dsa); */
dsa_pin_mapping(pgsmStateLocal.dsa);
#if USE_DYNAMIC_HASH #if USE_DYNAMIC_HASH
dsh_params.tranche_id = pgsmStateLocal.shared_pgsmState->hash_tranche_id; dsh_params.tranche_id = pgsmStateLocal.shared_pgsmState->hash_tranche_id;
pgsmStateLocal.shared_hash = dshash_attach(pgsmStateLocal.dsa, &dsh_params, pgsmStateLocal.shared_hash = dshash_attach(pgsmStateLocal.dsa, &dsh_params,
pgsmStateLocal.shared_pgsmState->hash_handle, 0); pgsmStateLocal.shared_pgsmState->hash_handle, 0);
#else #else
pgsmStateLocal.shared_hash = pgsmStateLocal.shared_pgsmState->hash_handle; pgsmStateLocal.shared_hash = pgsmStateLocal.shared_pgsmState->hash_handle;
#endif #endif
MemoryContextSwitchTo(oldcontext); MemoryContextSwitchTo(oldcontext);
} }
dsa_area* dsa_area *
get_dsa_area_for_query_text(void) get_dsa_area_for_query_text(void)
{ {
pgsm_attach_shmem(); pgsm_attach_shmem();
return pgsmStateLocal.dsa; return pgsmStateLocal.dsa;
} }
PGSM_HASH_TABLE* PGSM_HASH_TABLE *
get_pgsmHash(void) get_pgsmHash(void)
{ {
pgsm_attach_shmem(); pgsm_attach_shmem();
return pgsmStateLocal.shared_hash; return pgsmStateLocal.shared_hash;
} }
pgsmSharedState * pgsmSharedState *
pgsm_get_ss(void) pgsm_get_ss(void)
{ {
pgsm_attach_shmem(); pgsm_attach_shmem();
return pgsmStateLocal.shared_pgsmState; return pgsmStateLocal.shared_pgsmState;
} }
@ -256,48 +253,47 @@ pgsm_get_ss(void)
void void
pgsm_shmem_shutdown(int code, Datum arg) pgsm_shmem_shutdown(int code, Datum arg)
{ {
/* Don't try to dump during a crash. */ /* Don't try to dump during a crash. */
elog(LOG,"[pg_stat_monitor] pgsm_shmem_shutdown: Shutdown initiated."); elog(LOG, "[pg_stat_monitor] pgsm_shmem_shutdown: Shutdown initiated.");
if (code) if (code)
return; return;
pgsmStateLocal.shared_pgsmState = NULL; pgsmStateLocal.shared_pgsmState = NULL;
/* Safety check ... shouldn't get here unless shmem is set up. */ /* Safety check ... shouldn't get here unless shmem is set up. */
if (!IsHashInitialize()) if (!IsHashInitialize())
return; return;
} }
pgsmEntry * pgsmEntry *
hash_entry_alloc(pgsmSharedState *pgsm, pgsmHashKey *key, int encoding) hash_entry_alloc(pgsmSharedState * pgsm, pgsmHashKey * key, int encoding)
{ {
pgsmEntry *entry = NULL; pgsmEntry *entry = NULL;
bool found = false; bool found = false;
/* Find or create an entry with desired hash code */ /* Find or create an entry with desired hash code */
entry = (pgsmEntry*) 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) if (entry == NULL)
elog(DEBUG1, "[pg_stat_monitor] hash_entry_alloc: OUT OF MEMORY."); elog(DEBUG1, "[pg_stat_monitor] hash_entry_alloc: OUT OF MEMORY.");
else if (!found) else if (!found) {
{ pgsm->bucket_entry[pg_atomic_read_u64(&pgsm->current_wbucket)]++;
pgsm->bucket_entry[pg_atomic_read_u64(&pgsm->current_wbucket)]++; /* New entry, initialize it */
/* New entry, initialize it */ /* reset the statistics */
/* reset the statistics */ memset(&entry->counters, 0, sizeof(Counters));
memset(&entry->counters, 0, sizeof(Counters)); entry->query_text.query_pos = InvalidDsaPointer;
entry->query_text.query_pos = InvalidDsaPointer; entry->counters.info.parent_query = InvalidDsaPointer;
entry->counters.info.parent_query = InvalidDsaPointer;
/* set the appropriate initial usage count */ /* set the appropriate initial usage count */
/* re-initialize the mutex each time ... we assume no one using it */ /* re-initialize the mutex each time ... we assume no one using it */
SpinLockInit(&entry->mutex); SpinLockInit(&entry->mutex);
/* ... and don't forget the query text metadata */ /* ... and don't forget the query text metadata */
entry->encoding = encoding; entry->encoding = encoding;
} }
#if USE_DYNAMIC_HASH #if USE_DYNAMIC_HASH
if(entry) if (entry)
dshash_release_lock(pgsmStateLocal.shared_hash, entry); dshash_release_lock(pgsmStateLocal.shared_hash, entry);
#endif #endif
return entry; return entry;
} }
/* /*
@ -315,54 +311,52 @@ hash_entry_alloc(pgsmSharedState *pgsm, pgsmHashKey *key, int encoding)
void void
hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer) hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer)
{ {
PGSM_HASH_SEQ_STATUS hstat; PGSM_HASH_SEQ_STATUS hstat;
pgsmEntry *entry = NULL; pgsmEntry *entry = NULL;
/* Store pending query ids from the previous bucket. */ /* Store pending query ids from the previous bucket. */
if (!pgsmStateLocal.shared_hash) if (!pgsmStateLocal.shared_hash)
return; return;
/* Iterate over the hash table. */ /* Iterate over the hash table. */
pgsm_hash_seq_init(&hstat, pgsmStateLocal.shared_hash, true); pgsm_hash_seq_init(&hstat, pgsmStateLocal.shared_hash, true);
while ((entry = pgsm_hash_seq_next(&hstat)) != NULL) while ((entry = pgsm_hash_seq_next(&hstat)) != NULL) {
{ dsa_pointer pdsa;
dsa_pointer pdsa;
/* /*
* Remove all entries if new_bucket_id == -1. Otherwise remove entry * Remove all entries if new_bucket_id == -1. Otherwise remove entry
* in new_bucket_id if it has finished already. * in new_bucket_id if it has finished already.
*/ */
if (new_bucket_id < 0 || if (new_bucket_id < 0 ||
(entry->key.bucket_id == new_bucket_id )) (entry->key.bucket_id == new_bucket_id)) {
{ dsa_pointer parent_qdsa = entry->counters.info.parent_query;
dsa_pointer parent_qdsa = entry->counters.info.parent_query; pdsa = entry->query_text.query_pos;
pdsa = entry->query_text.query_pos;
pgsm_hash_delete_current(&hstat, pgsmStateLocal.shared_hash, &entry->key); pgsm_hash_delete_current(&hstat, pgsmStateLocal.shared_hash, &entry->key);
if (DsaPointerIsValid(pdsa)) if (DsaPointerIsValid(pdsa))
dsa_free(pgsmStateLocal.dsa, pdsa); dsa_free(pgsmStateLocal.dsa, pdsa);
if (DsaPointerIsValid(parent_qdsa)) if (DsaPointerIsValid(parent_qdsa))
dsa_free(pgsmStateLocal.dsa, parent_qdsa); dsa_free(pgsmStateLocal.dsa, parent_qdsa);
pgsmStateLocal.shared_pgsmState->pgsm_oom = false; pgsmStateLocal.shared_pgsmState->pgsm_oom = false;
}
} }
pgsm_hash_seq_term(&hstat); }
pgsm_hash_seq_term(&hstat);
} }
bool bool
IsHashInitialize(void) IsHashInitialize(void)
{ {
return (pgsmStateLocal.shared_pgsmState != NULL); return (pgsmStateLocal.shared_pgsmState != NULL);
} }
bool bool
IsSystemOOM(void) IsSystemOOM(void)
{ {
return (IsHashInitialize() && pgsmStateLocal.shared_pgsmState->pgsm_oom); return (IsHashInitialize() && pgsmStateLocal.shared_pgsmState->pgsm_oom);
} }
/* /*
@ -370,62 +364,62 @@ IsSystemOOM(void)
* API and call the appropriate hash table function based on USE_DYNAMIC_HASH * API and call the appropriate hash table function based on USE_DYNAMIC_HASH
*/ */
void * void *
pgsm_hash_find_or_insert(PGSM_HASH_TABLE *shared_hash, pgsmHashKey *key, bool* found) pgsm_hash_find_or_insert(PGSM_HASH_TABLE * shared_hash, pgsmHashKey * key, bool *found)
{
#if USE_DYNAMIC_HASH
void *entry;
entry = dshash_find_or_insert(shared_hash, key, found);
return entry;
#else
return hash_search(shared_hash, key, HASH_ENTER_NULL, found);
#endif
}
void *
pgsm_hash_find(PGSM_HASH_TABLE *shared_hash, pgsmHashKey *key, bool* found)
{
#if USE_DYNAMIC_HASH
return dshash_find(shared_hash, key, false);
#else
return hash_search(shared_hash, key, HASH_FIND, found);
#endif
}
void
pgsm_hash_seq_init(PGSM_HASH_SEQ_STATUS *hstat, PGSM_HASH_TABLE *shared_hash, bool lock)
{ {
#if USE_DYNAMIC_HASH #if USE_DYNAMIC_HASH
dshash_seq_init(hstat, shared_hash, lock); void *entry;
entry = dshash_find_or_insert(shared_hash, key, found);
return entry;
#else #else
hash_seq_init(hstat, shared_hash); return hash_search(shared_hash, key, HASH_ENTER_NULL, found);
#endif #endif
} }
void* void *
pgsm_hash_seq_next(PGSM_HASH_SEQ_STATUS *hstat) pgsm_hash_find(PGSM_HASH_TABLE * shared_hash, pgsmHashKey * key, bool *found)
{ {
#if USE_DYNAMIC_HASH #if USE_DYNAMIC_HASH
return dshash_seq_next(hstat); return dshash_find(shared_hash, key, false);
#else #else
return hash_seq_search(hstat); return hash_search(shared_hash, key, HASH_FIND, found);
#endif #endif
} }
void void
pgsm_hash_seq_term(PGSM_HASH_SEQ_STATUS *hstat) pgsm_hash_seq_init(PGSM_HASH_SEQ_STATUS * hstat, PGSM_HASH_TABLE * shared_hash, bool lock)
{ {
#if USE_DYNAMIC_HASH #if USE_DYNAMIC_HASH
dshash_seq_term(hstat); dshash_seq_init(hstat, shared_hash, lock);
#else
hash_seq_init(hstat, shared_hash);
#endif
}
void *
pgsm_hash_seq_next(PGSM_HASH_SEQ_STATUS * hstat)
{
#if USE_DYNAMIC_HASH
return dshash_seq_next(hstat);
#else
return hash_seq_search(hstat);
#endif #endif
} }
void void
pgsm_hash_delete_current(PGSM_HASH_SEQ_STATUS *hstat, PGSM_HASH_TABLE *shared_hash, void *key) pgsm_hash_seq_term(PGSM_HASH_SEQ_STATUS * hstat)
{ {
#if USE_DYNAMIC_HASH #if USE_DYNAMIC_HASH
dshash_delete_current(hstat); dshash_seq_term(hstat);
#else #endif
hash_search(shared_hash, key, HASH_REMOVE, NULL); }
#endif
void
pgsm_hash_delete_current(PGSM_HASH_SEQ_STATUS * hstat, PGSM_HASH_TABLE * shared_hash, void *key)
{
#if USE_DYNAMIC_HASH
dshash_delete_current(hstat);
#else
hash_search(shared_hash, key, HASH_REMOVE, NULL);
#endif
} }

File diff suppressed because it is too large Load Diff

View File

@ -66,13 +66,16 @@
/* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */ /* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */
#define USAGE_EXEC(duration) (1.0) #define USAGE_EXEC(duration) (1.0)
#define USAGE_INIT (1.0) /* including initial planning */ #define USAGE_INIT (1.0) /* including initial
#define ASSUMED_LENGTH_INIT 1024 /* initial assumed mean query length */ * planning */
#define ASSUMED_LENGTH_INIT 1024 /* initial assumed mean query
* length */
#define USAGE_DECREASE_FACTOR (0.99) /* decreased every entry_dealloc */ #define USAGE_DECREASE_FACTOR (0.99) /* decreased every entry_dealloc */
#define STICKY_DECREASE_FACTOR (0.50) /* factor for sticky entries */ #define STICKY_DECREASE_FACTOR (0.50) /* factor for sticky entries */
#define USAGE_DEALLOC_PERCENT 5 /* free this % of entries at once */ #define USAGE_DEALLOC_PERCENT 5 /* free this % of entries at once */
#define JUMBLE_SIZE 1024 /* query serialization buffer size */ #define JUMBLE_SIZE 1024 /* query serialization
* buffer size */
#define HISTOGRAM_MAX_TIME 50000000 #define HISTOGRAM_MAX_TIME 50000000
#define MAX_RESPONSE_BUCKET 50 #define MAX_RESPONSE_BUCKET 50
@ -82,7 +85,10 @@
#define ERROR_MESSAGE_LEN 100 #define ERROR_MESSAGE_LEN 100
#define REL_TYPENAME_LEN 64 #define REL_TYPENAME_LEN 64
#define REL_LST 10 #define REL_LST 10
#define REL_LEN 132 /* REL_TYPENAME_LEN * 2 (relname + schema) + 1 (for view indication) + 1 and dot and string terminator */ #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_LST 10
#define CMD_LEN 20 #define CMD_LEN 20
#define APPLICATIONNAME_LEN NAMEDATALEN #define APPLICATIONNAME_LEN NAMEDATALEN
@ -158,43 +164,41 @@ extern volatile bool __pgsm_do_not_capture_error;
* the classic shared memory hash table. * the classic shared memory hash table.
*/ */
#ifdef USE_DYNAMIC_HASH #ifdef USE_DYNAMIC_HASH
#define PGSM_HASH_TABLE dshash_table #define PGSM_HASH_TABLE dshash_table
#define PGSM_HASH_TABLE_HANDLE dshash_table_handle #define PGSM_HASH_TABLE_HANDLE dshash_table_handle
#define PGSM_HASH_SEQ_STATUS dshash_seq_status #define PGSM_HASH_SEQ_STATUS dshash_seq_status
#else #else
#define PGSM_HASH_TABLE HTAB #define PGSM_HASH_TABLE HTAB
#define PGSM_HASH_TABLE_HANDLE HTAB* #define PGSM_HASH_TABLE_HANDLE HTAB*
#define PGSM_HASH_SEQ_STATUS HASH_SEQ_STATUS #define PGSM_HASH_SEQ_STATUS HASH_SEQ_STATUS
#endif #endif
#if PG_VERSION_NUM < 130000 #if PG_VERSION_NUM < 130000
typedef struct WalUsage typedef struct WalUsage {
{ long wal_records; /* # of WAL records produced */
long wal_records; /* # of WAL records produced */ long wal_fpi; /* # of WAL full page images produced */
long wal_fpi; /* # of WAL full page images produced */ uint64 wal_bytes; /* size of WAL records produced */
uint64 wal_bytes; /* size of WAL records produced */ } WalUsage;
} WalUsage;
#endif #endif
typedef enum pgsmStoreKind typedef enum pgsmStoreKind {
{ PGSM_INVALID = -1,
PGSM_INVALID = -1,
/* /*
* PGSM_PLAN and PGSM_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, * reference the underlying values in the arrays in the Counters struct,
* and this order is required in pg_stat_monitor_internal(). * and this order is required in pg_stat_monitor_internal().
*/ */
PGSM_PARSE = 0, PGSM_PARSE = 0,
PGSM_PLAN, PGSM_PLAN,
PGSM_EXEC, PGSM_EXEC,
PGSM_STORE, PGSM_STORE,
PGSM_ERROR, PGSM_ERROR,
PGSM_NUMKIND /* Must be last value of this enum */ PGSM_NUMKIND /* Must be last value of this enum */
} pgsmStoreKind; } pgsmStoreKind;
/* the assumption of query max nested level */ /* the assumption of query max nested level */
#define DEFAULT_MAX_NESTED_LEVEL 10 #define DEFAULT_MAX_NESTED_LEVEL 10
@ -202,313 +206,297 @@ typedef enum pgsmStoreKind
/* /*
* Type of aggregate keys * Type of aggregate keys
*/ */
typedef enum AGG_KEY typedef enum AGG_KEY {
{ AGG_KEY_DATABASE = 0,
AGG_KEY_DATABASE = 0, AGG_KEY_USER,
AGG_KEY_USER, AGG_KEY_HOST
AGG_KEY_HOST } AGG_KEY;
} AGG_KEY;
#define MAX_QUERY_LEN 1024 #define MAX_QUERY_LEN 1024
/* shared memory storage for the query */ /* shared memory storage for the query */
typedef struct CallTime typedef struct CallTime {
{ double total_time; /* total execution time, in msec */
double total_time; /* total execution time, in msec */ double min_time; /* minimum execution time in msec */
double min_time; /* minimum execution time in msec */ double max_time; /* maximum execution time in msec */
double max_time; /* maximum execution time in msec */ double mean_time; /* mean execution time in msec */
double mean_time; /* mean execution time in msec */ double sum_var_time; /* sum of variances in execution time in msec */
double sum_var_time; /* sum of variances in execution time in msec */ } CallTime;
} CallTime;
typedef struct PlanInfo typedef struct PlanInfo {
{ uint64 planid; /* plan identifier */
uint64 planid; /* plan identifier */ char plan_text[PLAN_TEXT_LEN]; /* plan text */
char plan_text[PLAN_TEXT_LEN]; /* plan text */ size_t plan_len; /* strlen(plan_text) */
size_t plan_len; /* strlen(plan_text) */ } PlanInfo;
} PlanInfo;
typedef struct pgsmHashKey typedef struct pgsmHashKey {
{ uint64 bucket_id; /* bucket number */
uint64 bucket_id; /* bucket number */ uint64 queryid; /* query identifier */
uint64 queryid; /* query identifier */ uint64 planid; /* plan identifier */
uint64 planid; /* plan identifier */ uint64 appid; /* hash of application name */
uint64 appid; /* hash of application name */ Oid userid; /* user OID */
Oid userid; /* user OID */ Oid dbid; /* database OID */
Oid dbid; /* database OID */ uint32 ip; /* client ip address */
uint32 ip; /* client ip address */ bool toplevel; /* query executed at top level */
bool toplevel; /* query executed at top level */ } pgsmHashKey;
} pgsmHashKey;
typedef struct QueryInfo typedef struct QueryInfo {
{ uint64 parentid; /* parent queryid of current query */
uint64 parentid; /* parent queryid of current query */ dsa_pointer parent_query;
dsa_pointer parent_query; int64 type; /* type of query, options are query, info,
int64 type; /* type of query, options are query, info, * warning, error, fatal */
* warning, error, fatal */ char application_name[APPLICATIONNAME_LEN];
char application_name[APPLICATIONNAME_LEN]; char comments[COMMENTS_LEN];
char comments[COMMENTS_LEN]; char relations[REL_LST][REL_LEN]; /* List of relation involved
char relations[REL_LST][REL_LEN]; /* List of relation involved * in the query */
* in the query */ int num_relations; /* Number of relation in the query */
int num_relations; /* Number of relation in the query */ CmdType cmd_type; /* query command type
CmdType cmd_type; /* query command type * SELECT/UPDATE/DELETE/INSERT */
* SELECT/UPDATE/DELETE/INSERT */ } QueryInfo;
} QueryInfo;
typedef struct ErrorInfo typedef struct ErrorInfo {
{ int64 elevel; /* error elevel */
int64 elevel; /* error elevel */ char sqlcode[SQLCODE_LEN]; /* error sqlcode */
char sqlcode[SQLCODE_LEN]; /* error sqlcode */ char message[ERROR_MESSAGE_LEN]; /* error message text */
char message[ERROR_MESSAGE_LEN]; /* error message text */ } ErrorInfo;
} ErrorInfo;
typedef struct Calls typedef struct Calls {
{ int64 calls; /* # of times executed */
int64 calls; /* # of times executed */ int64 rows; /* total # of retrieved or affected rows */
int64 rows; /* total # of retrieved or affected rows */ double usage; /* usage factor */
double usage; /* usage factor */ } Calls;
} Calls;
typedef struct Blocks typedef struct Blocks {
{ int64 shared_blks_hit; /* # of shared buffer hits */
int64 shared_blks_hit; /* # of shared buffer hits */ int64 shared_blks_read; /* # of shared disk blocks read */
int64 shared_blks_read; /* # of shared disk blocks read */ int64 shared_blks_dirtied; /* # of shared disk blocks dirtied */
int64 shared_blks_dirtied; /* # of shared disk blocks dirtied */ int64 shared_blks_written; /* # of shared disk blocks written */
int64 shared_blks_written; /* # of shared disk blocks written */ int64 local_blks_hit; /* # of local buffer hits */
int64 local_blks_hit; /* # of local buffer hits */ int64 local_blks_read; /* # of local disk blocks read */
int64 local_blks_read; /* # of local disk blocks read */ int64 local_blks_dirtied; /* # of local disk blocks dirtied */
int64 local_blks_dirtied; /* # of local disk blocks dirtied */ int64 local_blks_written; /* # of local disk blocks written */
int64 local_blks_written; /* # of local disk blocks written */ int64 temp_blks_read; /* # of temp blocks read */
int64 temp_blks_read; /* # of temp blocks read */ int64 temp_blks_written; /* # of temp blocks written */
int64 temp_blks_written; /* # of temp blocks written */ double blk_read_time; /* time spent reading, in msec */
double blk_read_time; /* time spent reading, in msec */ double blk_write_time; /* time spent writing, in msec */
double blk_write_time; /* time spent writing, in msec */
double temp_blk_read_time; /* time spent reading temp blocks, in msec */ double temp_blk_read_time; /* time spent reading temp blocks, in
double temp_blk_write_time; /* time spent writing temp blocks, in * msec */
* 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 * Variables for local entry. The values to be passed to pgsm_update_entry
* from pgsm_store. * from pgsm_store.
*/ */
instr_time instr_blk_read_time; /* time spent reading blocks */ instr_time instr_blk_read_time; /* time spent reading blocks */
instr_time instr_blk_write_time; /* time spent writing 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_read_time; /* time spent reading temp
instr_time instr_temp_blk_write_time; /* time spent writing temp blocks */ * blocks */
} Blocks; instr_time instr_temp_blk_write_time; /* time spent writing temp
* blocks */
} Blocks;
typedef struct JitInfo typedef struct JitInfo {
{ int64 jit_functions; /* total number of JIT functions emitted */
int64 jit_functions; /* total number of JIT functions emitted */ double jit_generation_time; /* total time to generate jit code */
double jit_generation_time; /* total time to generate jit code */ int64 jit_inlining_count; /* number of times inlining time has
int64 jit_inlining_count; /* number of times inlining time has been * been > 0 */
* > 0 */ double jit_inlining_time; /* total time to inline jit code */
double jit_inlining_time; /* total time to inline jit code */ int64 jit_optimization_count; /* number of times optimization time
int64 jit_optimization_count; /* number of times optimization time * has been > 0 */
* has been > 0 */ double jit_optimization_time; /* total time to optimize jit code */
double jit_optimization_time; /* total time to optimize jit code */ int64 jit_emission_count; /* number of times emission time has
int64 jit_emission_count; /* number of times emission time has been * been > 0 */
* > 0 */ double jit_emission_time; /* total time to emit jit code */
double jit_emission_time; /* total time to emit jit code */
/* /*
* Variables for local entry. The values to be passed to pgsm_update_entry * Variables for local entry. The values to be passed to pgsm_update_entry
* from pgsm_store. * from pgsm_store.
*/ */
instr_time instr_generation_counter; /* generation counter */ instr_time instr_generation_counter; /* generation counter */
instr_time instr_inlining_counter; /* inlining counter */ instr_time instr_inlining_counter; /* inlining counter */
instr_time instr_optimization_counter; /* optimization counter */ instr_time instr_optimization_counter; /* optimization counter */
instr_time instr_emission_counter; /* emission counter */ instr_time instr_emission_counter; /* emission counter */
} JitInfo; } JitInfo;
typedef struct SysInfo typedef struct SysInfo {
{ double utime; /* user cpu time */
double utime; /* user cpu time */ double stime; /* system cpu time */
double stime; /* system cpu time */ } SysInfo;
} SysInfo;
typedef struct Wal_Usage typedef struct Wal_Usage {
{ int64 wal_records; /* # of WAL records generated */
int64 wal_records; /* # of WAL records generated */ int64 wal_fpi; /* # of WAL full page images generated */
int64 wal_fpi; /* # of WAL full page images generated */ uint64 wal_bytes; /* total amount of WAL bytes generated */
uint64 wal_bytes; /* total amount of WAL bytes generated */ } Wal_Usage;
} Wal_Usage;
typedef struct Counters typedef struct Counters {
{ Calls calls;
Calls calls; QueryInfo info;
QueryInfo info; CallTime time;
CallTime time;
Calls plancalls; Calls plancalls;
CallTime plantime; CallTime plantime;
PlanInfo planinfo; PlanInfo planinfo;
Blocks blocks; Blocks blocks;
SysInfo sysinfo; SysInfo sysinfo;
JitInfo jitinfo; JitInfo jitinfo;
ErrorInfo error; ErrorInfo error;
Wal_Usage walusage; Wal_Usage walusage;
int resp_calls[MAX_RESPONSE_BUCKET]; /* execution time's in int resp_calls[MAX_RESPONSE_BUCKET]; /* execution time's in
* msec */ * msec */
} Counters; } Counters;
/* Some global structure to get the cpu usage, really don't like the idea of global variable */ /* Some global structure to get the cpu usage, really don't like the idea of global variable */
/* /*
* Statistics per statement * Statistics per statement
*/ */
typedef struct pgsmEntry typedef struct pgsmEntry {
{ pgsmHashKey key; /* hash key of entry - MUST BE FIRST */
pgsmHashKey key; /* hash key of entry - MUST BE FIRST */ uint64 pgsm_query_id; /* pgsm generate normalized query hash */
uint64 pgsm_query_id; /* pgsm generate normalized query hash */ char datname[NAMEDATALEN]; /* database name */
char datname[NAMEDATALEN]; /* database name */ char username[NAMEDATALEN]; /* user name */
char username[NAMEDATALEN]; /* user name */ Counters counters; /* the statistics for this query */
Counters counters; /* the statistics for this query */ int encoding; /* query text encoding */
int encoding; /* query text encoding */ slock_t mutex; /* protects the counters only */
slock_t mutex; /* protects the counters only */ union {
union dsa_pointer query_pos; /* query location within query buffer */
{ char *query_pointer;
dsa_pointer query_pos; /* query location within query buffer */ } query_text;
char* query_pointer; } pgsmEntry;
}query_text;
} pgsmEntry;
/* /*
* Global shared state * Global shared state
*/ */
typedef struct pgsmSharedState typedef struct pgsmSharedState {
{ LWLock *lock; /* protects hashtable search/modification */
LWLock *lock; /* protects hashtable search/modification */ slock_t mutex; /* protects following fields only: */
slock_t mutex; /* protects following fields only: */ pg_atomic_uint64 current_wbucket;
pg_atomic_uint64 current_wbucket; pg_atomic_uint64 prev_bucket_sec;
pg_atomic_uint64 prev_bucket_sec; uint64 bucket_entry[MAX_BUCKETS];
uint64 bucket_entry[MAX_BUCKETS]; TimestampTz bucket_start_time[MAX_BUCKETS]; /* start time of the bucket */
TimestampTz bucket_start_time[MAX_BUCKETS]; /* start time of the bucket */ int hash_tranche_id;
int hash_tranche_id; void *raw_dsa_area; /* DSA area pointer to store query texts.
void *raw_dsa_area; /* DSA area pointer to store query texts. * dshash also lives in this memory when
* dshash also lives in this memory when * USE_DYNAMIC_HASH is enabled */
* USE_DYNAMIC_HASH is enabled */ PGSM_HASH_TABLE_HANDLE hash_handle;
PGSM_HASH_TABLE_HANDLE hash_handle; /*
/* hash table handle. can be either * hash table handle. can be either classic shared memory hash or dshash
* classic shared memory hash or dshash * (if we are using USE_DYNAMIC_HASH)
* (if we are using USE_DYNAMIC_HASH) */
*/ MemoryContext pgsm_mem_cxt;
MemoryContext pgsm_mem_cxt; /*
/* context to store stats in local * context to store stats in local memory until they are pushed to shared
* memory until they are pushed to shared hash * hash
*/ */
int resp_calls[MAX_RESPONSE_BUCKET + 2]; /* execution time's in int resp_calls[MAX_RESPONSE_BUCKET + 2]; /* execution time's in
* msec; including 2 outlier buckets */ * msec; including 2
bool pgsm_oom; * outlier buckets */
} pgsmSharedState; bool pgsm_oom;
} pgsmSharedState;
typedef struct pgsmLocalState typedef struct pgsmLocalState {
{ pgsmSharedState *shared_pgsmState;
pgsmSharedState *shared_pgsmState; dsa_area *dsa; /* local dsa area for backend attached to the
dsa_area *dsa; /* local dsa area for backend attached to the * dsa area created by postmaster at startup. */
* dsa area created by postmaster at startup. PGSM_HASH_TABLE *shared_hash;
*/ } pgsmLocalState;
PGSM_HASH_TABLE *shared_hash;
}pgsmLocalState;
#if PG_VERSION_NUM < 140000 #if PG_VERSION_NUM < 140000
/* /*
* Struct for tracking locations/lengths of constants during normalization * Struct for tracking locations/lengths of constants during normalization
*/ */
typedef struct LocationLen typedef struct LocationLen {
{ int location; /* start offset in query text */
int location; /* start offset in query text */ int length; /* length in bytes, or -1 to ignore */
int length; /* length in bytes, or -1 to ignore */ } LocationLen;
} LocationLen;
/* /*
* Working state for computing a query jumble and producing a normalized * Working state for computing a query jumble and producing a normalized
* query string * query string
*/ */
typedef struct JumbleState typedef struct JumbleState {
{ /* Jumble of current query tree */
/* Jumble of current query tree */ unsigned char *jumble;
unsigned char *jumble;
/* Number of bytes used in jumble[] */ /* Number of bytes used in jumble[] */
Size jumble_len; Size jumble_len;
/* Array of locations of constants that should be removed */ /* Array of locations of constants that should be removed */
LocationLen *clocations; LocationLen *clocations;
/* Allocated length of clocations array */ /* Allocated length of clocations array */
int clocations_buf_size; int clocations_buf_size;
/* Current number of valid entries in clocations array */ /* Current number of valid entries in clocations array */
int clocations_count; int clocations_count;
/* highest Param id we've seen, in order to start normalization correctly */ /* highest Param id we've seen, in order to start normalization correctly */
int highest_extern_param_id; int highest_extern_param_id;
} JumbleState; } JumbleState;
#endif #endif
/* guc.c */ /* guc.c */
void init_guc(void); void init_guc(void);
/* hash_create.c */ /* hash_create.c */
dsa_area *get_dsa_area_for_query_text(void); dsa_area *get_dsa_area_for_query_text(void);
PGSM_HASH_TABLE *get_pgsmHash(void); PGSM_HASH_TABLE *get_pgsmHash(void);
void pgsm_attach_shmem(void); void pgsm_attach_shmem(void);
bool IsHashInitialize(void); bool IsHashInitialize(void);
bool IsSystemOOM(void); bool IsSystemOOM(void);
void pgsm_shmem_startup(void); void pgsm_shmem_startup(void);
void pgsm_shmem_shutdown(int code, Datum arg); void pgsm_shmem_shutdown(int code, Datum arg);
int pgsm_get_bucket_size(void); int pgsm_get_bucket_size(void);
pgsmSharedState *pgsm_get_ss(void); pgsmSharedState *pgsm_get_ss(void);
void hash_query_entries(); void hash_query_entries();
void hash_query_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer[]); 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); void hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer);
pgsmEntry *hash_entry_alloc(pgsmSharedState *pgsm, pgsmHashKey *key, int encoding); pgsmEntry *hash_entry_alloc(pgsmSharedState * pgsm, pgsmHashKey * key, int encoding);
Size pgsm_ShmemSize(void); Size pgsm_ShmemSize(void);
void pgsm_startup(void); void pgsm_startup(void);
/* hash_query.c */ /* hash_query.c */
void pgsm_startup(void); void pgsm_startup(void);
/* guc.c */ /* guc.c */
void init_guc(void); void init_guc(void);
/* GUC variables*/ /* GUC variables*/
/*---- GUC variables ----*/ /*---- GUC variables ----*/
typedef enum typedef enum {
{ PSGM_TRACK_NONE = 0, /* track no statements */
PSGM_TRACK_NONE = 0, /* track no statements */ PGSM_TRACK_TOP, /* only top level statements */
PGSM_TRACK_TOP, /* only top level statements */ PGSM_TRACK_ALL /* all statements, including nested ones */
PGSM_TRACK_ALL /* all statements, including nested ones */ } PGSMTrackLevel;
} PGSMTrackLevel;
static const struct config_enum_entry track_options[] = static const struct config_enum_entry track_options[] =
{ {
{"none", PSGM_TRACK_NONE, false}, {"none", PSGM_TRACK_NONE, false},
{"top", PGSM_TRACK_TOP, false}, {"top", PGSM_TRACK_TOP, false},
{"all", PGSM_TRACK_ALL, false}, {"all", PGSM_TRACK_ALL, false},
{NULL, 0, false} {NULL, 0, false}
}; };
typedef enum typedef enum {
{ HISTOGRAM_START,
HISTOGRAM_START, HISTOGRAM_END,
HISTOGRAM_END, HISTOGRAM_COUNT
HISTOGRAM_COUNT } HistogramTimingType;
} HistogramTimingType;
extern int pgsm_max; extern int pgsm_max;
extern int pgsm_query_max_len; extern int pgsm_query_max_len;
extern int pgsm_bucket_time; extern int pgsm_bucket_time;
extern int pgsm_max_buckets; extern int pgsm_max_buckets;
extern int pgsm_histogram_buckets; extern int pgsm_histogram_buckets;
extern double pgsm_histogram_min; extern double pgsm_histogram_min;
extern double pgsm_histogram_max; extern double pgsm_histogram_max;
extern int pgsm_query_shared_buffer; extern int pgsm_query_shared_buffer;
extern bool pgsm_track_planning; extern bool pgsm_track_planning;
extern bool pgsm_extract_comments; extern bool pgsm_extract_comments;
extern bool pgsm_enable_query_plan; extern bool pgsm_enable_query_plan;
@ -516,7 +504,7 @@ extern bool pgsm_enable_overflow;
extern bool pgsm_normalized_query; extern bool pgsm_normalized_query;
extern bool pgsm_track_utility; extern bool pgsm_track_utility;
extern bool pgsm_enable_pgsm_query_id; extern bool pgsm_enable_pgsm_query_id;
extern int pgsm_track; extern int pgsm_track;
#define DECLARE_HOOK(hook, ...) \ #define DECLARE_HOOK(hook, ...) \
static hook(__VA_ARGS__); static hook(__VA_ARGS__);
@ -524,9 +512,9 @@ extern int pgsm_track;
#define HOOK_STATS_SIZE 0 #define HOOK_STATS_SIZE 0
#endif #endif
void *pgsm_hash_find_or_insert(PGSM_HASH_TABLE *shared_hash, pgsmHashKey *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_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_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_next(PGSM_HASH_SEQ_STATUS * hstat);
void pgsm_hash_seq_term(PGSM_HASH_SEQ_STATUS *hstat); void pgsm_hash_seq_term(PGSM_HASH_SEQ_STATUS * hstat);
void pgsm_hash_delete_current(PGSM_HASH_SEQ_STATUS *hstat, PGSM_HASH_TABLE *shared_hash, void *key); void pgsm_hash_delete_current(PGSM_HASH_SEQ_STATUS * hstat, PGSM_HASH_TABLE * shared_hash, void *key);