PG-200: Add application name to the bucket ID.
Add application name to the key used to identify queries in the hash table, this allows different applications to have separate entries in pg_stat_monitor view if they issued the same query.pull/87/head
parent
7934ccbbdf
commit
99f01d37e3
|
@ -268,7 +268,7 @@ hash_entry_reset()
|
||||||
|
|
||||||
/* Caller must accuire lock */
|
/* Caller must accuire lock */
|
||||||
pgssQueryEntry*
|
pgssQueryEntry*
|
||||||
hash_create_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 userid, uint64 ip)
|
hash_create_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 userid, uint64 ip, uint64 appid)
|
||||||
{
|
{
|
||||||
pgssQueryHashKey key;
|
pgssQueryHashKey key;
|
||||||
pgssQueryEntry *entry;
|
pgssQueryEntry *entry;
|
||||||
|
@ -279,6 +279,7 @@ hash_create_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 us
|
||||||
key.dbid = dbid;
|
key.dbid = dbid;
|
||||||
key.userid = userid;
|
key.userid = userid;
|
||||||
key.ip = ip;
|
key.ip = ip;
|
||||||
|
key.appid = appid;
|
||||||
|
|
||||||
entry = (pgssQueryEntry *) hash_search(pgss_query_hash, &key, HASH_ENTER, &found);
|
entry = (pgssQueryEntry *) hash_search(pgss_query_hash, &key, HASH_ENTER, &found);
|
||||||
return entry;
|
return entry;
|
||||||
|
@ -286,7 +287,7 @@ hash_create_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 us
|
||||||
|
|
||||||
/* Caller must accuire lock */
|
/* Caller must accuire lock */
|
||||||
pgssQueryEntry*
|
pgssQueryEntry*
|
||||||
hash_find_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 userid, uint64 ip)
|
hash_find_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 userid, uint64 ip, uint64 appid)
|
||||||
{
|
{
|
||||||
pgssQueryHashKey key;
|
pgssQueryHashKey key;
|
||||||
pgssQueryEntry *entry;
|
pgssQueryEntry *entry;
|
||||||
|
@ -297,6 +298,7 @@ hash_find_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 user
|
||||||
key.dbid = dbid;
|
key.dbid = dbid;
|
||||||
key.userid = userid;
|
key.userid = userid;
|
||||||
key.ip = ip;
|
key.ip = ip;
|
||||||
|
key.appid = appid;
|
||||||
|
|
||||||
/* Lookup the hash table entry with shared lock. */
|
/* Lookup the hash table entry with shared lock. */
|
||||||
entry = (pgssQueryEntry *) hash_search(pgss_query_hash, &key, HASH_FIND, &found);
|
entry = (pgssQueryEntry *) hash_search(pgss_query_hash, &key, HASH_FIND, &found);
|
||||||
|
|
|
@ -152,6 +152,7 @@ static pgssQueryEntry *pgss_store_query_info(uint64 bucketid,
|
||||||
uint64 dbid,
|
uint64 dbid,
|
||||||
uint64 userid,
|
uint64 userid,
|
||||||
uint64 ip,
|
uint64 ip,
|
||||||
|
uint64 appid,
|
||||||
const char *query,
|
const char *query,
|
||||||
uint64 query_len,
|
uint64 query_len,
|
||||||
pgssStoreKind kind);
|
pgssStoreKind kind);
|
||||||
|
@ -210,6 +211,9 @@ pgss_store_query(uint64 queryid,
|
||||||
#if PG_VERSION_NUM < 140000
|
#if PG_VERSION_NUM < 140000
|
||||||
static uint64 get_query_id(JumbleState *jstate, Query *query);
|
static uint64 get_query_id(JumbleState *jstate, Query *query);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Daniel J. Bernstein's hash algorithm: see http://www.cse.yorku.ca/~oz/hash.html */
|
||||||
|
static uint64 djb2_hash(unsigned char *str, size_t len);
|
||||||
/*
|
/*
|
||||||
* Module load callback
|
* Module load callback
|
||||||
*/
|
*/
|
||||||
|
@ -1172,7 +1176,8 @@ pgss_get_entry(uint64 bucket_id,
|
||||||
uint64 dbid,
|
uint64 dbid,
|
||||||
uint64 queryid,
|
uint64 queryid,
|
||||||
uint64 ip,
|
uint64 ip,
|
||||||
uint64 planid)
|
uint64 planid,
|
||||||
|
uint64 appid)
|
||||||
{
|
{
|
||||||
pgssEntry *entry;
|
pgssEntry *entry;
|
||||||
pgssHashKey key;
|
pgssHashKey key;
|
||||||
|
@ -1185,6 +1190,7 @@ pgss_get_entry(uint64 bucket_id,
|
||||||
key.queryid = queryid;
|
key.queryid = queryid;
|
||||||
key.ip = pg_get_client_addr();
|
key.ip = pg_get_client_addr();
|
||||||
key.planid = planid;
|
key.planid = planid;
|
||||||
|
key.appid = appid;
|
||||||
|
|
||||||
entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_FIND, NULL);
|
entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_FIND, NULL);
|
||||||
if(!entry)
|
if(!entry)
|
||||||
|
@ -1338,12 +1344,15 @@ pgss_store(uint64 queryid,
|
||||||
{
|
{
|
||||||
pgssEntry *entry;
|
pgssEntry *entry;
|
||||||
pgssSharedState *pgss = pgsm_get_ss();
|
pgssSharedState *pgss = pgsm_get_ss();
|
||||||
|
char application_name[APPLICATIONNAME_LEN];
|
||||||
|
int application_name_len = pg_get_application_name(application_name);
|
||||||
bool reset = false;
|
bool reset = false;
|
||||||
uint64 bucketid;
|
uint64 bucketid;
|
||||||
uint64 userid = GetUserId();
|
uint64 userid = GetUserId();
|
||||||
uint64 dbid = MyDatabaseId;
|
uint64 dbid = MyDatabaseId;
|
||||||
uint64 ip = pg_get_client_addr();
|
uint64 ip = pg_get_client_addr();
|
||||||
uint64 planid = plan_info ? plan_info->planid: 0;
|
uint64 planid = plan_info ? plan_info->planid: 0;
|
||||||
|
uint64 appid = djb2_hash((unsigned char *)application_name, application_name_len);
|
||||||
char *comments;
|
char *comments;
|
||||||
/* Monitoring is disabled */
|
/* Monitoring is disabled */
|
||||||
if (!PGSM_ENABLED)
|
if (!PGSM_ENABLED)
|
||||||
|
@ -1372,7 +1381,7 @@ pgss_store(uint64 queryid,
|
||||||
case PGSS_PLAN:
|
case PGSS_PLAN:
|
||||||
{
|
{
|
||||||
pgssQueryEntry *query_entry;
|
pgssQueryEntry *query_entry;
|
||||||
query_entry = pgss_store_query_info(bucketid, queryid, dbid, userid, ip, query, strlen(query), kind);
|
query_entry = pgss_store_query_info(bucketid, queryid, dbid, userid, ip, appid, query, strlen(query), kind);
|
||||||
if (query_entry == NULL)
|
if (query_entry == NULL)
|
||||||
elog(DEBUG1, "pg_stat_monitor: out of memory");
|
elog(DEBUG1, "pg_stat_monitor: out of memory");
|
||||||
break;
|
break;
|
||||||
|
@ -1382,13 +1391,13 @@ pgss_store(uint64 queryid,
|
||||||
case PGSS_FINISHED:
|
case PGSS_FINISHED:
|
||||||
{
|
{
|
||||||
pgssQueryEntry *query_entry;
|
pgssQueryEntry *query_entry;
|
||||||
query_entry = pgss_store_query_info(bucketid, queryid, dbid, userid, ip, query, strlen(query), kind);
|
query_entry = pgss_store_query_info(bucketid, queryid, dbid, userid, ip, appid, query, strlen(query), kind);
|
||||||
if (query_entry == NULL)
|
if (query_entry == NULL)
|
||||||
{
|
{
|
||||||
elog(DEBUG1, "pg_stat_monitor: out of memory");
|
elog(DEBUG1, "pg_stat_monitor: out of memory");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
entry = pgss_get_entry(bucketid, userid, dbid, queryid, ip, planid);
|
entry = pgss_get_entry(bucketid, userid, dbid, queryid, ip, planid, appid);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
{
|
{
|
||||||
elog(DEBUG1, "pg_stat_monitor: out of memory");
|
elog(DEBUG1, "pg_stat_monitor: out of memory");
|
||||||
|
@ -1535,6 +1544,7 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
uint64 userid = entry->key.userid;
|
uint64 userid = entry->key.userid;
|
||||||
uint64 ip = entry->key.ip;
|
uint64 ip = entry->key.ip;
|
||||||
uint64 planid = entry->key.planid;
|
uint64 planid = entry->key.planid;
|
||||||
|
uint64 appid = entry->key.appid;
|
||||||
unsigned char *buf = pgss_qbuf[bucketid];
|
unsigned char *buf = pgss_qbuf[bucketid];
|
||||||
char *query_txt = (char*) malloc(PGSM_QUERY_MAX_LEN);
|
char *query_txt = (char*) malloc(PGSM_QUERY_MAX_LEN);
|
||||||
#if PG_VERSION_NUM < 140000
|
#if PG_VERSION_NUM < 140000
|
||||||
|
@ -1542,7 +1552,7 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
#else
|
#else
|
||||||
bool is_allowed_role = is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS);
|
bool is_allowed_role = is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS);
|
||||||
#endif
|
#endif
|
||||||
query_entry = hash_find_query_entry(bucketid, queryid, dbid, userid, ip);
|
query_entry = hash_find_query_entry(bucketid, queryid, dbid, userid, ip, appid);
|
||||||
if (query_entry == NULL)
|
if (query_entry == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2851,6 +2861,7 @@ pgss_store_query_info(uint64 bucketid,
|
||||||
uint64 dbid,
|
uint64 dbid,
|
||||||
uint64 userid,
|
uint64 userid,
|
||||||
uint64 ip,
|
uint64 ip,
|
||||||
|
uint64 appid,
|
||||||
const char *query,
|
const char *query,
|
||||||
uint64 query_len,
|
uint64 query_len,
|
||||||
pgssStoreKind kind)
|
pgssStoreKind kind)
|
||||||
|
@ -2865,11 +2876,11 @@ pgss_store_query_info(uint64 bucketid,
|
||||||
/* Already have query in the shared buffer, there
|
/* Already have query in the shared buffer, there
|
||||||
* is no need to add that again.
|
* is no need to add that again.
|
||||||
*/
|
*/
|
||||||
entry = hash_find_query_entry(bucketid, queryid, dbid, userid, ip);
|
entry = hash_find_query_entry(bucketid, queryid, dbid, userid, ip, appid);
|
||||||
if (entry)
|
if (entry)
|
||||||
return entry;
|
return entry;
|
||||||
|
|
||||||
entry = hash_create_query_entry(bucketid, queryid, dbid, userid, ip);
|
entry = hash_create_query_entry(bucketid, queryid, dbid, userid, ip, appid);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return NULL;
|
return NULL;
|
||||||
entry->state = kind;
|
entry->state = kind;
|
||||||
|
@ -3226,3 +3237,13 @@ get_query_id(JumbleState *jstate, Query *query)
|
||||||
return queryid;
|
return queryid;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static uint64 djb2_hash(unsigned char *str, size_t len)
|
||||||
|
{
|
||||||
|
uint64 hash = 5381LLU;
|
||||||
|
|
||||||
|
while (len--)
|
||||||
|
hash = ((hash << 5) + hash) ^ *str++; // hash(i - 1) * 33 ^ str[i]
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
|
@ -178,6 +178,7 @@ typedef struct pgssQueryHashKey
|
||||||
uint64 userid; /* user OID */
|
uint64 userid; /* user OID */
|
||||||
uint64 dbid; /* database OID */
|
uint64 dbid; /* database OID */
|
||||||
uint64 ip; /* client ip address */
|
uint64 ip; /* client ip address */
|
||||||
|
uint64 appid; /* hash of application name */
|
||||||
} pgssQueryHashKey;
|
} pgssQueryHashKey;
|
||||||
|
|
||||||
typedef struct pgssQueryEntry
|
typedef struct pgssQueryEntry
|
||||||
|
@ -201,6 +202,7 @@ typedef struct pgssHashKey
|
||||||
uint64 dbid; /* database OID */
|
uint64 dbid; /* database OID */
|
||||||
uint64 ip; /* client ip address */
|
uint64 ip; /* client ip address */
|
||||||
uint64 planid; /* plan identifier */
|
uint64 planid; /* plan identifier */
|
||||||
|
uint64 appid; /* hash of application name */
|
||||||
} pgssHashKey;
|
} pgssHashKey;
|
||||||
|
|
||||||
typedef struct QueryInfo
|
typedef struct QueryInfo
|
||||||
|
@ -388,8 +390,8 @@ Size hash_memsize(void);
|
||||||
|
|
||||||
int read_query_buffer(int bucket_id, uint64 queryid, char *query_txt);
|
int read_query_buffer(int bucket_id, uint64 queryid, char *query_txt);
|
||||||
uint64 read_query(unsigned char *buf, uint64 bucketid, uint64 queryid, char * query);
|
uint64 read_query(unsigned char *buf, uint64 bucketid, uint64 queryid, char * query);
|
||||||
pgssQueryEntry* hash_find_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 userid, uint64 ip);
|
pgssQueryEntry* hash_find_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 userid, uint64 ip, uint64 appid);
|
||||||
pgssQueryEntry* hash_create_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 userid, uint64 ip);
|
pgssQueryEntry* hash_create_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 userid, uint64 ip, uint64 appid);
|
||||||
void pgss_startup(void);
|
void pgss_startup(void);
|
||||||
void set_qbuf(int i, unsigned char *);
|
void set_qbuf(int i, unsigned char *);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue