PG-193: Comment based tags to identify different parameters.

pull/82/head
Ibrar Ahmed 2021-05-19 22:15:37 +05:00
parent 89614e442b
commit 67b3d961ca
6 changed files with 80 additions and 5 deletions

View File

@ -11,7 +11,7 @@ PGFILEDESC = "pg_stat_monitor - execution statistics of SQL statements"
LDFLAGS_SL += $(filter -lm, $(LIBS)) LDFLAGS_SL += $(filter -lm, $(LIBS))
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf --inputdir=regression REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf --inputdir=regression
REGRESS = basic version guc counters relations database top_query application_name cmd_type error state rows REGRESS = basic version guc counters relations database top_query application_name cmd_type error state rows tags
# Disabled because these tests require "shared_preload_libraries=pg_stat_statements", # Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
# which typical installcheck users do not have (e.g. buildfarm clients). # which typical installcheck users do not have (e.g. buildfarm clients).

View File

@ -77,7 +77,8 @@ CREATE FUNCTION pg_stat_monitor_internal(IN showtext boolean,
OUT cpu_sys_time float8, OUT cpu_sys_time float8,
OUT wal_records int8, OUT wal_records int8,
OUT wal_fpi int8, OUT wal_fpi int8,
OUT wal_bytes numeric OUT wal_bytes numeric,
OUT comments TEXT
) )
RETURNS SETOF record RETURNS SETOF record
AS 'MODULE_PATHNAME', 'pg_stat_monitor' AS 'MODULE_PATHNAME', 'pg_stat_monitor'
@ -144,6 +145,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
queryid, queryid,
top_queryid, top_queryid,
query, query,
comments,
planid, planid,
query_plan, query_plan,
(SELECT query from pg_stat_monitor_internal(true) s where s.queryid = p.top_queryid) AS top_query, (SELECT query from pg_stat_monitor_internal(true) s where s.queryid = p.top_queryid) AS top_query,

View File

@ -15,13 +15,14 @@
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include <regex.h>
#include "commands/explain.h" #include "commands/explain.h"
#include "pg_stat_monitor.h" #include "pg_stat_monitor.h"
PG_MODULE_MAGIC; PG_MODULE_MAGIC;
#define BUILD_VERSION "devel" #define BUILD_VERSION "devel"
#define PG_STAT_STATEMENTS_COLS 51 /* maximum of above */ #define PG_STAT_STATEMENTS_COLS 52 /* maximum of above */
#define PGSM_TEXT_FILE "/tmp/pg_stat_monitor_query" #define PGSM_TEXT_FILE "/tmp/pg_stat_monitor_query"
#define PGUNSIXBIT(val) (((val) & 0x3F) + '0') #define PGUNSIXBIT(val) (((val) & 0x3F) + '0')
@ -73,6 +74,7 @@ static struct rusage rusage_end;
static unsigned char *pgss_qbuf[MAX_BUCKETS]; static unsigned char *pgss_qbuf[MAX_BUCKETS];
static char *pgss_explain(QueryDesc *queryDesc); static char *pgss_explain(QueryDesc *queryDesc);
static char *extract_query_comments(const char *query);
static int get_histogram_bucket(double q_time); static int get_histogram_bucket(double q_time);
static bool IsSystemInitialized(void); static bool IsSystemInitialized(void);
static void dump_queries_buffer(int bucket_id, unsigned char *buf, int buf_len); static void dump_queries_buffer(int bucket_id, unsigned char *buf, int buf_len);
@ -893,6 +895,7 @@ pgss_update_entry(pgssEntry *entry,
int bucketid, int bucketid,
uint64 queryid, uint64 queryid,
const char *query, const char *query,
const char *comments,
PlanInfo *plan_info, PlanInfo *plan_info,
CmdType cmd_type, CmdType cmd_type,
SysInfo *sys_info, SysInfo *sys_info,
@ -910,6 +913,7 @@ pgss_update_entry(pgssEntry *entry,
pgssSharedState *pgss = pgsm_get_ss(); pgssSharedState *pgss = pgsm_get_ss();
double old_mean; double old_mean;
int message_len = error_info ? strlen (error_info->message) : 0; int message_len = error_info ? strlen (error_info->message) : 0;
int comments_len = comments ? strlen (comments) : 0;
int sqlcode_len = error_info ? strlen (error_info->sqlcode) : 0; int sqlcode_len = error_info ? strlen (error_info->sqlcode) : 0;
int plan_text_len = plan_info ? strlen (plan_info->plan_text) : 0; int plan_text_len = plan_info ? strlen (plan_info->plan_text) : 0;
@ -922,6 +926,7 @@ pgss_update_entry(pgssEntry *entry,
if (reset) if (reset)
memset(&entry->counters, 0, sizeof(Counters)); memset(&entry->counters, 0, sizeof(Counters));
_snprintf(e->counters.info.comments, comments, comments_len, COMMENTS_LEN);
e->counters.state = kind; e->counters.state = kind;
if (kind == PGSS_PLAN) if (kind == PGSS_PLAN)
{ {
@ -1204,13 +1209,15 @@ pgss_store(uint64 queryid,
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;
char *comments;
/* Monitoring is disabled */ /* Monitoring is disabled */
if (!PGSM_ENABLED) if (!PGSM_ENABLED)
return; return;
Assert(query != NULL); Assert(query != NULL);
comments = extract_query_comments(query);
/* Safety check... */ /* Safety check... */
if (!IsSystemInitialized() || !pgss_qbuf[pgss->current_wbucket]) if (!IsSystemInitialized() || !pgss_qbuf[pgss->current_wbucket])
return; return;
@ -1258,6 +1265,7 @@ pgss_store(uint64 queryid,
bucketid, /* bucketid */ bucketid, /* bucketid */
queryid, /* queryid */ queryid, /* queryid */
query, /* query */ query, /* query */
comments, /* comments */
plan_info, /* PlanInfo */ plan_info, /* PlanInfo */
cmd_type, /* CmdType */ cmd_type, /* CmdType */
sys_info, /* SysInfo */ sys_info, /* SysInfo */
@ -1364,7 +1372,7 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "pg_stat_monitor: return type must be a row type"); elog(ERROR, "pg_stat_monitor: return type must be a row type");
if (tupdesc->natts != 48) if (tupdesc->natts != 49)
elog(ERROR, "pg_stat_monitor: incorrect number of output arguments, required %d", tupdesc->natts); elog(ERROR, "pg_stat_monitor: incorrect number of output arguments, required %d", tupdesc->natts);
tupstore = tuplestore_begin_heap(true, false, work_mem); tupstore = tuplestore_begin_heap(true, false, work_mem);
@ -1658,6 +1666,12 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
Int32GetDatum(-1)); Int32GetDatum(-1));
/* wal_bytes at column number 46 */ /* wal_bytes at column number 46 */
values[i++] = wal_bytes; values[i++] = wal_bytes;
/* application_name at column number 47 */
if (strlen(tmp.info.comments) > 0)
values[i++] = CStringGetTextDatum(tmp.info.comments);
else
nulls[i++] = true;
} }
tuplestore_putvalues(tupstore, tupdesc, values, nulls); tuplestore_putvalues(tupstore, tupdesc, values, nulls);
} }
@ -3049,3 +3063,26 @@ get_histogram_timings(PG_FUNCTION_ARGS)
return CStringGetTextDatum(text_str); return CStringGetTextDatum(text_str);
} }
char *
extract_query_comments(const char *query)
{
regex_t preg;
char *pattern = "/\\*.*\\*/";
int rc;
size_t nmatch = 1;
regmatch_t pmatch;
char *comments = palloc0(512);
rc = regcomp(&preg, pattern, 0);
if (rc != 0)
{
printf("regcomp() failed, returning nonzero (%d)\n", rc);
return "";
}
rc = regexec(&preg, query, nmatch, &pmatch, 0);
if (rc != 0)
return "";
sprintf(comments, "%.*s", pmatch.rm_eo - pmatch.rm_so -4, &query[pmatch.rm_so + 2]);
regfree(&preg);
return comments;
}

View File

@ -78,6 +78,7 @@
#define CMD_LST 10 #define CMD_LST 10
#define CMD_LEN 20 #define CMD_LEN 20
#define APPLICATIONNAME_LEN 100 #define APPLICATIONNAME_LEN 100
#define COMMENTS_LEN 512
#define PGSM_OVER_FLOW_MAX 10 #define PGSM_OVER_FLOW_MAX 10
#define PLAN_TEXT_LEN 1024 #define PLAN_TEXT_LEN 1024
/* the assumption of query max nested level */ /* the assumption of query max nested level */
@ -211,6 +212,7 @@ typedef struct QueryInfo
uint64 parentid; /* parent queryid of current query*/ uint64 parentid; /* parent queryid of current query*/
int64 type; /* type of query, options are query, info, warning, error, fatal */ int64 type; /* type of query, options are query, info, warning, error, fatal */
char application_name[APPLICATIONNAME_LEN]; char application_name[APPLICATIONNAME_LEN];
char comments[COMMENTS_LEN];
char relations[REL_LST][REL_LEN]; /* List of relation involved in the query */ char relations[REL_LST][REL_LEN]; /* List of relation involved 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 SELECT/UPDATE/DELETE/INSERT */ CmdType cmd_type; /* query command type SELECT/UPDATE/DELETE/INSERT */

View File

@ -0,0 +1,28 @@
CREATE EXTENSION pg_stat_monitor;
SELECT pg_stat_monitor_reset();
pg_stat_monitor_reset
-----------------------
(1 row)
SELECT 1 AS num /* { "application", psql_app, "real_ip", 192.168.1.3) */;
num
-----
1
(1 row)
SELECT query, comments FROM pg_stat_monitor ORDER BY query COLLATE "C";
query | comments
-------------------------------------------------------------------------+------------------------------------------------------
SELECT $1 AS num | { "application", psql_app, "real_ip", 192.168.1.3)
SELECT pg_stat_monitor_reset(); |
SELECT query, comments FROM pg_stat_monitor ORDER BY query COLLATE "C"; |
(3 rows)
SELECT pg_stat_monitor_reset();
pg_stat_monitor_reset
-----------------------
(1 row)
DROP EXTENSION pg_stat_monitor;

6
regression/sql/tags.sql Normal file
View File

@ -0,0 +1,6 @@
CREATE EXTENSION pg_stat_monitor;
SELECT pg_stat_monitor_reset();
SELECT 1 AS num /* { "application", psql_app, "real_ip", 192.168.1.3) */;
SELECT query, comments FROM pg_stat_monitor ORDER BY query COLLATE "C";
SELECT pg_stat_monitor_reset();
DROP EXTENSION pg_stat_monitor;