parent
9efa05de97
commit
057150c99b
21
guc.c
21
guc.c
|
@ -80,14 +80,6 @@ init_guc(void)
|
|||
.guc_max = INT_MAX,
|
||||
.guc_restart = true
|
||||
};
|
||||
conf[i++] = (GucVariable) {
|
||||
.guc_name = "pg_stat_monitor.pgsm_object_cache",
|
||||
.guc_desc = "Sets the maximum number of object cache",
|
||||
.guc_default = 50,
|
||||
.guc_min = 50,
|
||||
.guc_max = INT_MAX,
|
||||
.guc_restart = true
|
||||
};
|
||||
|
||||
conf[i++] = (GucVariable) {
|
||||
.guc_name = "pg_stat_monitor.pgsm_respose_time_lower_bound",
|
||||
|
@ -212,19 +204,6 @@ init_guc(void)
|
|||
NULL);
|
||||
|
||||
|
||||
DefineCustomIntVariable("pg_stat_monitor.pgsm_object_cache",
|
||||
"Sets the maximum number of object cache",
|
||||
NULL,
|
||||
&PGSM_OBJECT_CACHE,
|
||||
50,
|
||||
50,
|
||||
INT_MAX,
|
||||
PGC_POSTMASTER,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
DefineCustomIntVariable("pg_stat_monitor.pgsm_respose_time_lower_bound",
|
||||
"Sets the time in millisecond.",
|
||||
NULL,
|
||||
|
|
44
hash_query.c
44
hash_query.c
|
@ -16,7 +16,6 @@
|
|||
|
||||
static pgssSharedState *pgss;
|
||||
static HTAB *pgss_hash;
|
||||
static HTAB *pgss_object_hash;
|
||||
|
||||
static HTAB* hash_init(const char *hash_name, int key_size, int entry_size, int hash_size);
|
||||
|
||||
|
@ -40,7 +39,6 @@ pgss_startup(void)
|
|||
|
||||
pgss = NULL;
|
||||
pgss_hash = NULL;
|
||||
pgss_object_hash = NULL;
|
||||
|
||||
/*
|
||||
* Create or attach to the shared memory state, including hash table
|
||||
|
@ -66,7 +64,6 @@ pgss_startup(void)
|
|||
}
|
||||
|
||||
pgss_hash = hash_init("pg_stat_monitor: Queries hashtable", sizeof(pgssHashKey), sizeof(pgssEntry),PGSM_MAX);
|
||||
pgss_object_hash = hash_init("pg_stat_monitor: Object hashtable", sizeof(pgssObjectHashKey), sizeof(pgssObjectEntry), PGSM_OBJECT_CACHE);
|
||||
|
||||
LWLockRelease(AddinShmemInitLock);
|
||||
|
||||
|
@ -197,44 +194,6 @@ hash_entry_reset()
|
|||
LWLockRelease(pgss->lock);
|
||||
}
|
||||
|
||||
void
|
||||
hash_alloc_object_entry(uint64 queryid, char *objects)
|
||||
{
|
||||
pgssObjectEntry *entry = NULL;
|
||||
bool found;
|
||||
pgssObjectHashKey key;
|
||||
|
||||
LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
|
||||
key.queryid = queryid;
|
||||
entry = (pgssObjectEntry *) hash_search(pgss_object_hash, &key, HASH_ENTER, &found);
|
||||
if (!found)
|
||||
{
|
||||
SpinLockAcquire(&entry->mutex);
|
||||
snprintf(entry->tables_name, MAX_REL_LEN, "%s", objects);
|
||||
SpinLockRelease(&entry->mutex);
|
||||
}
|
||||
LWLockRelease(pgss->lock);
|
||||
}
|
||||
|
||||
/* De-alocate memory */
|
||||
void
|
||||
hash_dealloc_object_entry(uint64 queryid, char *objects)
|
||||
{
|
||||
pgssObjectHashKey key;
|
||||
pgssObjectEntry *entry;
|
||||
|
||||
key.queryid = queryid;
|
||||
|
||||
LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
|
||||
entry = (pgssObjectEntry *) hash_search(pgss_object_hash, &key, HASH_FIND, NULL);
|
||||
if (entry != NULL)
|
||||
{
|
||||
snprintf(objects, MAX_REL_LEN, "%s", entry->tables_name);
|
||||
hash_search(pgss_object_hash, &entry->key, HASH_REMOVE, NULL);
|
||||
}
|
||||
LWLockRelease(pgss->lock);
|
||||
}
|
||||
|
||||
pgssEntry*
|
||||
hash_create_query_entry(unsigned int queryid,
|
||||
unsigned int userid,
|
||||
|
@ -270,7 +229,6 @@ bool
|
|||
IsHashInitialize(void)
|
||||
{
|
||||
return (pgss != NULL &&
|
||||
pgss_hash != NULL &&
|
||||
pgss_object_hash !=NULL);
|
||||
pgss_hash != NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ CREATE FUNCTION pg_stat_monitor(IN showtext boolean,
|
|||
|
||||
OUT queryid text,
|
||||
OUT query text,
|
||||
OUT relations text,
|
||||
OUT cmd_type text,
|
||||
OUT elevel int,
|
||||
OUT sqlcode int,
|
||||
|
@ -58,8 +59,7 @@ CREATE FUNCTION pg_stat_monitor(IN showtext boolean,
|
|||
OUT blk_write_time float8,
|
||||
OUT resp_calls text,
|
||||
OUT cpu_user_time float8,
|
||||
OUT cpu_sys_time float8,
|
||||
OUT tables_names text
|
||||
OUT cpu_sys_time float8
|
||||
)
|
||||
RETURNS SETOF record
|
||||
AS 'MODULE_PATHNAME', 'pg_stat_monitor'
|
||||
|
@ -97,6 +97,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||
queryid,
|
||||
query,
|
||||
(string_to_array(relations, ',')) relations,
|
||||
(string_to_array(cmd_type, ',')) cmd_type,
|
||||
elevel,
|
||||
sqlcode,
|
||||
|
@ -128,8 +129,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
|
|||
blk_write_time,
|
||||
(string_to_array(resp_calls, ',')) resp_calls,
|
||||
cpu_user_time,
|
||||
cpu_sys_time,
|
||||
(string_to_array(tables_names, ',')) tables_names
|
||||
cpu_sys_time
|
||||
FROM pg_stat_monitor(TRUE);
|
||||
|
||||
CREATE FUNCTION decode_error_level(elevel int)
|
||||
|
|
|
@ -240,7 +240,6 @@ static void
|
|||
pgss_post_parse_analyze(ParseState *pstate, Query *query)
|
||||
{
|
||||
pgssJumbleState jstate;
|
||||
char tables_name[MAX_REL_LEN] = {0};
|
||||
|
||||
if (prev_post_parse_analyze_hook)
|
||||
prev_post_parse_analyze_hook(pstate, query);
|
||||
|
@ -264,40 +263,6 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query)
|
|||
}
|
||||
|
||||
query->queryId = get_query_id(&jstate, query);
|
||||
if (query->rtable)
|
||||
{
|
||||
ListCell *lc;
|
||||
bool first = true;
|
||||
foreach(lc, query->rtable)
|
||||
{
|
||||
RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc);
|
||||
if (rte->rtekind == RTE_RELATION)
|
||||
{
|
||||
char *relname = get_rel_name(rte->relid);
|
||||
char *relspacename = get_namespace_name(get_rel_namespace(rte->relid));
|
||||
if (relname)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
if (relspacename)
|
||||
snprintf(tables_name, MAX_REL_LEN, "%s.%s", relspacename, relname);
|
||||
else
|
||||
snprintf(tables_name, MAX_REL_LEN, "%s", relname);
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (relspacename)
|
||||
snprintf(tables_name, MAX_REL_LEN, "%s,%s.%s", tables_name, relspacename, relname);
|
||||
else
|
||||
snprintf(tables_name, MAX_REL_LEN, "%s,%s", tables_name, relname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
hash_alloc_object_entry(query->queryId, tables_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are unlucky enough to get a hash of zero, use 1 instead, to
|
||||
* prevent confusion with the utility-statement case.
|
||||
|
@ -463,15 +428,29 @@ pgss_ExecutorCheckPerms(List *rt, bool abort)
|
|||
{
|
||||
ListCell *lr;
|
||||
pgssSharedState *pgss = pgsm_get_ss();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
|
||||
memset(pgss->cmdTag, 0x0, sizeof(pgss->cmdTag));
|
||||
|
||||
foreach(lr, rt)
|
||||
{
|
||||
bool found = false;
|
||||
RangeTblEntry *rte = lfirst(lr);
|
||||
if (rte->rtekind != RTE_RELATION)
|
||||
continue;
|
||||
|
||||
if (i < REL_LST)
|
||||
{
|
||||
for(j = 0; j < i; j++)
|
||||
{
|
||||
if (pgss->relations[j] == rte->relid)
|
||||
found = true;
|
||||
}
|
||||
if (!found)
|
||||
pgss->relations[i++] = rte->relid;
|
||||
}
|
||||
if (rte->requiredPerms & ACL_INSERT) snprintf(pgss->cmdTag[0],CMD_LEN,"%s", "INSERT");
|
||||
if (rte->requiredPerms & ACL_UPDATE) snprintf(pgss->cmdTag[1],CMD_LEN,"%s", "UPDATE");
|
||||
if (rte->requiredPerms & ACL_DELETE) snprintf(pgss->cmdTag[2],CMD_LEN,"%s", "DELETE");
|
||||
|
@ -748,8 +727,6 @@ static void pgss_store(uint64 queryId,
|
|||
bool reset = false;
|
||||
bool found = false;
|
||||
int i,j;
|
||||
char tables_name[MAX_REL_LEN] = {0};
|
||||
int len;
|
||||
pgssSharedState *pgss = pgsm_get_ss();
|
||||
HTAB *pgss_hash = pgsm_get_hash();
|
||||
int message_len = message ? strlen(message) : 0;
|
||||
|
@ -800,9 +777,6 @@ static void pgss_store(uint64 queryId,
|
|||
if (queryId == UINT64CONST(0))
|
||||
queryId = pgss_hash_string(query, query_len);
|
||||
|
||||
hash_dealloc_object_entry(queryId, tables_name);
|
||||
len = strlen(tables_name);
|
||||
|
||||
for (i = 0; i < CMD_LST; i++)
|
||||
cmd_len[i] = strlen(pgss->cmdTag[i]);
|
||||
|
||||
|
@ -925,6 +899,15 @@ static void pgss_store(uint64 queryId,
|
|||
e->counters.resp_calls[MAX_RESPONSE_BUCKET - 1]++;
|
||||
}
|
||||
|
||||
for (i = 0; i < REL_LST; i++)
|
||||
if (e->counters.info.relations[i] != 0)
|
||||
found = true;
|
||||
|
||||
if (!found)
|
||||
for (i = 0; i < REL_LST; i++)
|
||||
e->counters.info.relations[i] = pgss->relations[i];
|
||||
|
||||
found = false;
|
||||
/* This is bit ugly hack to check we already updated the counter or not */
|
||||
for (i = 0; i < CMD_LST; i++)
|
||||
if (e->counters.info.cmd_type[i][0] != 0)
|
||||
|
@ -964,8 +947,6 @@ static void pgss_store(uint64 queryId,
|
|||
e->counters.info.host = pg_get_client_addr();
|
||||
e->counters.sysinfo.utime = utime;
|
||||
e->counters.sysinfo.stime = stime;
|
||||
for(i = 0; i < len; i++)
|
||||
e->counters.info.tables_name[i] = tables_name[i];
|
||||
SpinLockRelease(&e->mutex);
|
||||
}
|
||||
}
|
||||
|
@ -1064,13 +1045,14 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
|||
hash_seq_init(&hash_seq, pgss_hash);
|
||||
while ((entry = hash_seq_search(&hash_seq)) != NULL)
|
||||
{
|
||||
Datum values[PG_STAT_STATEMENTS_COLS];
|
||||
bool nulls[PG_STAT_STATEMENTS_COLS];
|
||||
int i = 0;
|
||||
int kind;
|
||||
Counters tmp;
|
||||
double stddev;
|
||||
int64 queryid = entry->key.queryid;
|
||||
Datum values[PG_STAT_STATEMENTS_COLS];
|
||||
bool nulls[PG_STAT_STATEMENTS_COLS];
|
||||
int i = 0,j;
|
||||
int len = 0;
|
||||
int kind;
|
||||
Counters tmp;
|
||||
double stddev;
|
||||
int64 queryid = entry->key.queryid;
|
||||
|
||||
memset(values, 0, sizeof(values));
|
||||
memset(nulls, 0, sizeof(nulls));
|
||||
|
@ -1130,6 +1112,17 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
|||
else
|
||||
nulls[i++] = true;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
for (j = 0; j < REL_LST; j++)
|
||||
if (tmp.info.relations[j] != 0)
|
||||
len++;
|
||||
|
||||
if (len == 0)
|
||||
nulls[i++] = true;
|
||||
else
|
||||
values[i++] = IntArrayGetTextDatum(tmp.info.relations, len);
|
||||
|
||||
values[i++] = TextArrayGetTextDatum(tmp.info.cmd_type, CMD_LST);
|
||||
values[i++] = Int64GetDatumFast(tmp.error.elevel);
|
||||
values[i++] = Int64GetDatumFast(tmp.error.sqlcode);
|
||||
|
@ -1169,10 +1162,6 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
|||
values[i++] = IntArrayGetTextDatum(tmp.resp_calls, 10);
|
||||
values[i++] = Float8GetDatumFast(tmp.sysinfo.utime);
|
||||
values[i++] = Float8GetDatumFast(tmp.sysinfo.stime);
|
||||
if (strlen(tmp.info.tables_name) == 0)
|
||||
nulls[i++] = true;
|
||||
else
|
||||
values[i++] = CStringGetTextDatum(tmp.info.tables_name);
|
||||
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
|
||||
}
|
||||
free(query_txt);
|
||||
|
@ -2165,7 +2154,7 @@ intarray_get_datum(int32 arr[], int len)
|
|||
first = false;
|
||||
continue;
|
||||
}
|
||||
snprintf(tmp, 10, ", %d", arr[j]);
|
||||
snprintf(tmp, 10, ",%d", arr[j]);
|
||||
strcat(str,tmp);
|
||||
}
|
||||
return CStringGetTextDatum(str);
|
||||
|
|
|
@ -59,9 +59,9 @@
|
|||
#define MAX_RESPONSE_BUCKET 10
|
||||
#define MAX_REL_LEN 255
|
||||
#define MAX_BUCKETS 10
|
||||
#define MAX_OBJECT_CACHE 100
|
||||
#define TEXT_LEN 255
|
||||
#define ERROR_MESSAGE_LEN 100
|
||||
#define REL_LST 10
|
||||
#define CMD_LST 10
|
||||
#define CMD_LEN 20
|
||||
|
||||
|
@ -102,18 +102,6 @@ typedef enum AGG_KEY
|
|||
AGG_KEY_HOST
|
||||
} AGG_KEY;
|
||||
|
||||
typedef struct pgssObjectHashKey
|
||||
{
|
||||
uint64 queryid; /* query id */
|
||||
} pgssObjectHashKey;
|
||||
|
||||
typedef struct pgssObjectEntry
|
||||
{
|
||||
pgssObjectHashKey key; /* hash key of entry - MUST BE FIRST */
|
||||
char tables_name[MAX_REL_LEN]; /* table names involved in the query */
|
||||
slock_t mutex; /* protects the counters only */
|
||||
} pgssObjectEntry;
|
||||
|
||||
#define MAX_QUERY_LEN 1024
|
||||
|
||||
/* shared nenory storage for the query */
|
||||
|
@ -133,8 +121,8 @@ typedef struct QueryInfo
|
|||
Oid dbid; /* database OID */
|
||||
uint host; /* client IP */
|
||||
int64 type; /* type of query, options are query, info, warning, error, fatal */
|
||||
char cmd_type[CMD_LST][CMD_LEN]; /* query command type SELECT/UPDATE/DELETE/INSERT */
|
||||
char tables_name[MAX_REL_LEN]; /* table names involved in the query */
|
||||
int32 relations[REL_LST];
|
||||
char cmd_type[CMD_LST][CMD_LEN]; /* query command type SELECT/UPDATE/DELETE/INSERT */
|
||||
} QueryInfo;
|
||||
|
||||
typedef struct ErrorInfo
|
||||
|
@ -220,13 +208,14 @@ typedef struct pgssSharedState
|
|||
double cur_median_usage; /* current median usage in hashtable */
|
||||
slock_t mutex; /* protects following fields only: */
|
||||
Size extent; /* current extent of query file */
|
||||
int n_writers; /* number of active writers to query file */
|
||||
int64 n_writers; /* number of active writers to query file */
|
||||
uint64 current_wbucket;
|
||||
uint64 prev_bucket_usec;
|
||||
uint64 bucket_overflow[MAX_BUCKETS];
|
||||
uint64 bucket_entry[MAX_BUCKETS];
|
||||
int query_buf_size_bucket;
|
||||
char cmdTag[CMD_LST][20];
|
||||
int64 query_buf_size_bucket;
|
||||
int32 relations[REL_LST];
|
||||
char cmdTag[CMD_LST][CMD_LEN];
|
||||
Timestamp bucket_start_time[MAX_BUCKETS]; /* start time of the bucket */
|
||||
} pgssSharedState;
|
||||
|
||||
|
@ -285,8 +274,6 @@ void init_guc(void);
|
|||
GucVariable *get_conf(int i);
|
||||
|
||||
/* hash_create.c */
|
||||
void hash_alloc_object_entry(uint64 queryid, char *objects);
|
||||
void hash_dealloc_object_entry(uint64 queryid, char *objects);
|
||||
bool IsHashInitialize(void);
|
||||
void pgss_shmem_startup(void);
|
||||
void pgss_shmem_shutdown(int code, Datum arg);
|
||||
|
@ -313,10 +300,9 @@ void pgss_startup(void);
|
|||
#define PGSM_NORMALIZED_QUERY get_conf(4)->guc_variable
|
||||
#define PGSM_MAX_BUCKETS get_conf(5)->guc_variable
|
||||
#define PGSM_BUCKET_TIME get_conf(6)->guc_variable
|
||||
#define PGSM_OBJECT_CACHE get_conf(7)->guc_variable
|
||||
#define PGSM_RESPOSE_TIME_LOWER_BOUND get_conf(8)->guc_variable
|
||||
#define PGSM_RESPOSE_TIME_STEP get_conf(9)->guc_variable
|
||||
#define PGSM_QUERY_BUF_SIZE get_conf(10)->guc_variable
|
||||
#define PGSM_TRACK_PLANNING get_conf(11)->guc_variable
|
||||
#define PGSM_RESPOSE_TIME_LOWER_BOUND get_conf(7)->guc_variable
|
||||
#define PGSM_RESPOSE_TIME_STEP get_conf(8)->guc_variable
|
||||
#define PGSM_QUERY_BUF_SIZE get_conf(9)->guc_variable
|
||||
#define PGSM_TRACK_PLANNING get_conf(10)->guc_variable
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue