Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PG-564: Added a column to display bind variables when used with the n… #350

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bb6f2fa
PG-564: Added a column to display bind variables when used with the n…
kayform Jan 9, 2023
ae7bbc3
PG-564: Added a column to display bind variables when used with the n…
kayform Jan 16, 2023
18bd18f
PG-564: fix the memory overflow
kayform Jan 20, 2023
e5669ff
PG-564: Added TAP test for bind parameter. update pg_stat_monitor-1.0…
kayform Feb 7, 2023
2437997
PG-564: Change the delimiter from ',' to '|' between variable and var…
Mar 14, 2023
84c9f46
resolve conflict with upstream/main
kayform Aug 11, 2023
70728c8
Add files via upload
ksjj97inzent Nov 28, 2023
d868bd4
Add files via upload
ksjj97inzent Nov 28, 2023
0295a53
Update 001_settings_default.out
ksjj97inzent Nov 28, 2023
214d137
Update 018_column_names.pl
ksjj97inzent Nov 28, 2023
1e1df9d
Update guc.out
ksjj97inzent Dec 21, 2023
4c072fc
Update guc_1.out
ksjj97inzent Dec 21, 2023
bdedf9f
Update guc_2.out
ksjj97inzent Dec 21, 2023
6568237
Update guc_1.out
ksjj97inzent Dec 21, 2023
ace7038
Update guc.out
ksjj97inzent Dec 21, 2023
ba60e25
Update guc_1.out
ksjj97inzent Dec 21, 2023
8ecdd12
Update guc_2.out
ksjj97inzent Dec 21, 2023
2359bf6
Merge branch 'percona:main' into PG-564
ksjj97inzent Dec 21, 2023
9bdd0d1
Merge branch 'percona:main' into main
ksjj97inzent Dec 21, 2023
17e1a7e
Update guc_2.out
ksjj97inzent Dec 21, 2023
add00ae
Update guc_1.out
ksjj97inzent Dec 21, 2023
d25adb3
Update guc_2.out
ksjj97inzent Dec 21, 2023
7193d4d
Update guc_2.out
ksjj97inzent Dec 21, 2023
3050d5d
Update guc_2.out
ksjj97inzent Dec 21, 2023
71311b6
Update guc_1.out
ksjj97inzent Dec 21, 2023
6ad4c2d
Update guc_2.out
ksjj97inzent Dec 22, 2023
dfb31ec
Update guc_1.out
ksjj97inzent Dec 22, 2023
2e72e54
Update guc_1.out
ksjj97inzent Dec 22, 2023
71832f3
Update 001_settings_default.out.12
ksjj97inzent Dec 22, 2023
a711aa7
Merge branch 'main' into PG-564
ksjj97inzent Jan 15, 2024
dce21c1
Merge pull request #1 from experdb/PG-564
ksjj97inzent Jan 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ PGFILEDESC = "pg_stat_monitor - execution statistics of SQL statements"

LDFLAGS_SL += $(filter -lm, $(LIBS))

PG_CPPFLAGS += -std=c99 -g -ggdb

TAP_TESTS = 1
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf --inputdir=regression
REGRESS = basic version guc pgsm_query_id functions counters relations database error_insert application_name application_name_unique top_query cmd_type error rows tags
Expand Down
13 changes: 13 additions & 0 deletions guc.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,19 @@ init_guc(void)
.guc_value = &PGSM_TRACK_PLANNING
};
DefineBoolGUC(&conf[i++]);

conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_extract_bind_variables",
.guc_desc = "Selects whether extracting bind variables from queries.",
.guc_default = 0,
.guc_min = 0,
.guc_max = 0,
.guc_restart = false,
.guc_unit = 0,
.guc_value = &PGSM_EXTRACT_VARIABLES
};
DefineBoolGUC(&conf[i++]);
#endif
}

Expand Down
6 changes: 5 additions & 1 deletion pg_stat_monitor--2.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ CREATE FUNCTION pg_stat_monitor_internal(
OUT top_queryid text,
OUT top_query text,
OUT application_name text,

OUT bind_variables text,
OUT relations text, -- 11
OUT cmd_type int,
OUT elevel int,
Expand Down Expand Up @@ -180,6 +180,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
query_plan,
top_query,
application_name,
bind_variables,
string_to_array(relations, ',') AS relations,
cmd_type,
get_cmd_type(cmd_type) AS cmd_type_text,
Expand Down Expand Up @@ -235,6 +236,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
query_plan,
top_query,
application_name,
bind_variables,
string_to_array(relations, ',') AS relations,
cmd_type,
get_cmd_type(cmd_type) AS cmd_type_text,
Expand Down Expand Up @@ -299,6 +301,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
query_plan,
top_query,
application_name,
bind_variables,
string_to_array(relations, ',') AS relations,
cmd_type,
get_cmd_type(cmd_type) AS cmd_type_text,
Expand Down Expand Up @@ -363,6 +366,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
query_plan,
top_query,
application_name,
bind_variables,
string_to_array(relations, ',') AS relations,
cmd_type,
get_cmd_type(cmd_type) AS cmd_type_text,
Expand Down
49 changes: 43 additions & 6 deletions pg_stat_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ PG_MODULE_MAGIC;

/* Number of output arguments (columns) for various API versions */
#define PG_STAT_MONITOR_COLS_V1_0 52
#define PG_STAT_MONITOR_COLS_V2_0 62
#define PG_STAT_MONITOR_COLS 62 /* maximum of above */
#define PG_STAT_MONITOR_COLS_V2_0 63
#define PG_STAT_MONITOR_COLS 63 /* maximum of above */

#define PGSM_TEXT_FILE PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat_monitor_query"

Expand Down Expand Up @@ -214,7 +214,8 @@ static const char *CleanQuerytext(const char *query, int *location, int *len);
#endif

static char *generate_normalized_query(JumbleState *jstate, const char *query,
int query_loc, int *query_len_p, int encoding);
int query_loc, int *query_len_p, int encoding,
char* bind_variables, int *bind_var_len_p);
static void fill_in_constant_lengths(JumbleState *jstate, const char *query, int query_loc);
static int comp_location(const void *a, const void *b);

Expand Down Expand Up @@ -1155,6 +1156,7 @@ pgss_update_entry(pgssEntry *entry,
uint64 queryid,
const char *query,
const char *comments,
const char *bind_variables,
PlanInfo * plan_info,
CmdType cmd_type,
SysInfo * sys_info,
Expand All @@ -1173,6 +1175,7 @@ pgss_update_entry(pgssEntry *entry,
double old_mean;
int message_len = error_info ? strlen(error_info->message) : 0;
int comments_len = comments ? strlen(comments) : 0;
int bind_variables_len = bind_variables ? strlen(bind_variables): 0;
int sqlcode_len = error_info ? strlen(error_info->sqlcode) : 0;
int plan_text_len = plan_info ? plan_info->plan_len : 0;

Expand Down Expand Up @@ -1246,6 +1249,9 @@ pgss_update_entry(pgssEntry *entry,
if (plan_text_len > 0 && !e->counters.planinfo.plan_text[0])
_snprintf(e->counters.planinfo.plan_text, plan_info->plan_text, plan_text_len + 1, PLAN_TEXT_LEN);

if (bind_variables_len > 0 && !e->counters.info.bind_variables[0])
_snprintf(e->counters.info.bind_variables, bind_variables, bind_variables_len + 1, VAR_LEN);

if (app_name_len > 0 && !e->counters.info.application_name[0])
_snprintf(e->counters.info.application_name, app_name, app_name_len + 1, APPLICATIONNAME_LEN);

Expand Down Expand Up @@ -1395,6 +1401,9 @@ pgss_store(uint64 queryid,
int norm_query_len = 0;
char *norm_query = NULL;
char comments[512] = "";
char bind_variables[VAR_LEN] = "";
char *bind_variables_ptr = &bind_variables[0];
int bind_var_len = 0;
bool found_app_name = false;
bool found_client_addr = false;
uint client_addr = 0;
Expand Down Expand Up @@ -1514,7 +1523,9 @@ pgss_store(uint64 queryid,
norm_query = generate_normalized_query(jstate, query,
query_location,
&norm_query_len,
GetDatabaseEncoding());
GetDatabaseEncoding(),
bind_variables_ptr,
&bind_var_len);
LWLockAcquire(pgss->lock, LW_SHARED);

pgsm_query_id = pgss_hash_string(norm_query, norm_query_len);
Expand Down Expand Up @@ -1599,12 +1610,13 @@ pgss_store(uint64 queryid,
entry->pgsm_query_id = pgsm_query_id;
}

if (jstate == NULL)
if (jstate == NULL || (PGSM_EXTRACT_VARIABLES && bind_var_len > 0))
pgss_update_entry(entry, /* entry */
bucketid, /* bucketid */
queryid, /* queryid */
query, /* query */
comments, /* comments */
bind_variables_ptr, /* bind variables */
plan_info, /* PlanInfo */
cmd_type, /* CmdType */
sys_info, /* SysInfo */
Expand Down Expand Up @@ -1904,6 +1916,12 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
else
nulls[i++] = true;

/* bind_variables at column number 48 */
if (strlen(tmp.info.bind_variables) > 0)
values[i++] = CStringGetTextDatum(tmp.info.bind_variables);
else
nulls[i++] = true;

/* relations at column number 10 */
if (tmp.info.num_relations > 0)
{
Expand Down Expand Up @@ -2917,15 +2935,18 @@ CleanQuerytext(const char *query, int *location, int *len)
*/
static char *
generate_normalized_query(JumbleState *jstate, const char *query,
int query_loc, int *query_len_p, int encoding)
int query_loc, int *query_len_p, int encoding,
char* bind_variables, int *bind_var_len_p)
{
char *norm_query;
int query_len = *query_len_p;
int bind_var_len;
int i,
norm_query_buflen, /* Space allowed for norm_query */
len_to_wrt, /* Length (in bytes) to write */
quer_loc = 0, /* Source query byte location */
n_quer_loc = 0, /* Normalized query byte location */
n_var_loc = 0, /* bind_variables byte location */
last_off = 0, /* Offset from start for previous tok */
last_tok_len = 0; /* Length (in bytes) of that tok */

Expand Down Expand Up @@ -2976,6 +2997,16 @@ generate_normalized_query(JumbleState *jstate, const char *query,
quer_loc = off + tok_len;
last_off = off;
last_tok_len = tok_len;

if (PGSM_EXTRACT_VARIABLES){
if (n_var_loc+tok_len + 1 < VAR_LEN-1){
memcpy(bind_variables + n_var_loc, query + quer_loc - tok_len, tok_len);
n_var_loc += tok_len;
memcpy(bind_variables + n_var_loc , ",", 1);
n_var_loc ++;
}

}
}

/*
Expand All @@ -2992,6 +3023,12 @@ generate_normalized_query(JumbleState *jstate, const char *query,
norm_query[n_quer_loc] = '\0';

*query_len_p = n_quer_loc;

if (PGSM_EXTRACT_VARIABLES){
bind_var_len = n_var_loc-1;
bind_variables[bind_var_len] = '\0';
*bind_var_len_p = bind_var_len;
}
return norm_query;
}

Expand Down
7 changes: 5 additions & 2 deletions pg_stat_monitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
#define COMMENTS_LEN 512
#define PGSM_OVER_FLOW_MAX 10
#define PLAN_TEXT_LEN 1024
#define VAR_LEN COMMENTS_LEN
/* the assumption of query max nested level */
#define DEFAULT_MAX_NESTED_LEVEL 10

Expand All @@ -96,9 +97,9 @@
#define SQLCODE_LEN 20

#if PG_VERSION_NUM >= 130000
#define MAX_SETTINGS 15
#define MAX_SETTINGS 16
#else
#define MAX_SETTINGS 14
#define MAX_SETTINGS 15
#endif

/* Update this if need a enum GUC with more options. */
Expand Down Expand Up @@ -219,6 +220,7 @@ typedef struct QueryInfo
int64 type; /* type of query, options are query, info,
* warning, error, fatal */
char application_name[APPLICATIONNAME_LEN];
char bind_variables[VAR_LEN];
char comments[COMMENTS_LEN];
char relations[REL_LST][REL_LEN]; /* List of relation involved
* in the query */
Expand Down Expand Up @@ -474,6 +476,7 @@ static const struct config_enum_entry track_options[] =
#define PGSM_TRACK get_conf(12)->guc_variable
#define PGSM_EXTRACT_COMMENTS get_conf(13)->guc_variable
#define PGSM_TRACK_PLANNING get_conf(14)->guc_variable
#define PGSM_EXTRACT_VARIABLES get_conf(15)->guc_variable

#define DECLARE_HOOK(hook, ...) \
static hook(__VA_ARGS__);
Expand Down
39 changes: 39 additions & 0 deletions regression/expected/guc_2.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
CREATE EXTENSION pg_stat_monitor;
SELECT name
, setting
, unit
, context
, vartype
, source
, min_val
, max_val
, enumvals
, boot_val
, reset_val
, pending_restart
FROM pg_settings
WHERE name LIKE 'pg_stat_monitor.%'
ORDER
BY name
COLLATE "C";
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
---------------------------------------------+---------+------+------------+---------+--------------------+---------+------------+----------------+----------+-----------+-----------------
pg_stat_monitor.pgsm_bucket_time | 60 | | postmaster | integer | default | 1 | 2147483647 | | 60 | 60 | f
pg_stat_monitor.pgsm_enable_query_plan | off | | user | bool | configuration file | | | | off | off | f
pg_stat_monitor.pgsm_extract_bind_variables | off | | user | bool | configuration file | | | | off | off | f
pg_stat_monitor.pgsm_extract_comments | off | | user | bool | configuration file | | | | off | off | f
pg_stat_monitor.pgsm_histogram_buckets | 20 | | postmaster | integer | default | 2 | 50 | | 20 | 20 | f
pg_stat_monitor.pgsm_histogram_max | 100000 | | postmaster | integer | default | 10 | 2147483647 | | 100000 | 100000 | f
pg_stat_monitor.pgsm_histogram_min | 1 | | postmaster | integer | default | 0 | 2147483647 | | 1 | 1 | f
pg_stat_monitor.pgsm_max | 100 | MB | postmaster | integer | default | 1 | 1000 | | 100 | 100 | f
pg_stat_monitor.pgsm_max_buckets | 10 | | postmaster | integer | default | 1 | 10 | | 10 | 10 | f
pg_stat_monitor.pgsm_normalized_query | off | | user | bool | configuration file | | | | off | off | f
pg_stat_monitor.pgsm_overflow_target | 1 | | postmaster | integer | default | 0 | 1 | | 1 | 1 | f
pg_stat_monitor.pgsm_query_max_len | 2048 | | postmaster | integer | default | 1024 | 2147483647 | | 2048 | 2048 | f
pg_stat_monitor.pgsm_query_shared_buffer | 20 | MB | postmaster | integer | default | 1 | 10000 | | 20 | 20 | f
pg_stat_monitor.pgsm_track | top | | user | enum | default | | | {none,top,all} | top | top | f
pg_stat_monitor.pgsm_track_planning | off | | user | bool | default | | | | off | off | f
pg_stat_monitor.pgsm_track_utility | on | | user | bool | default | | | | on | on | f
(16 rows)

DROP EXTENSION pg_stat_monitor;