From 56db28d1292213e4641bb7e7bfe603dbd9ba9b65 Mon Sep 17 00:00:00 2001 From: wangtq Date: Fri, 14 May 2021 16:30:27 +0800 Subject: [PATCH] feat (WDR): add a new GUC track_stmt_parameter and can get query plan under L1 level --- src/bin/gs_guc/cluster_guc.conf | 1 + src/common/backend/utils/misc/guc.cpp | 10 ++- .../instruments/statement/instr_statement.cpp | 42 ++++++++--- .../unique_sql/instr_unique_sql.cpp | 70 +++++++++++++++++++ src/include/instruments/instr_statement.h | 1 + .../knl/knl_guc/knl_session_attr_common.h | 1 + 6 files changed, 114 insertions(+), 11 deletions(-) diff --git a/src/bin/gs_guc/cluster_guc.conf b/src/bin/gs_guc/cluster_guc.conf index 6e1138d28..fc01750d6 100755 --- a/src/bin/gs_guc/cluster_guc.conf +++ b/src/bin/gs_guc/cluster_guc.conf @@ -346,6 +346,7 @@ wdr_snapshot_query_timeout|int|100,2147483647|s|NULL| enable_wdr_snapshot|bool|0,0|NULL|NULL| enable_asp|bool|0,0|NULL|NULL| enable_stmt_track|bool|0,0|NULL|NULL| +track_stmt_parameter|bool|0,0|NULL|NULL| asp_sample_num|int|10000,100000|NULL|NULL| asp_sample_interval|int|1,10|s|NULL| asp_flush_rate|int|1,10|NULL|NULL| diff --git a/src/common/backend/utils/misc/guc.cpp b/src/common/backend/utils/misc/guc.cpp index 4d362b5b1..9c666fe29 100644 --- a/src/common/backend/utils/misc/guc.cpp +++ b/src/common/backend/utils/misc/guc.cpp @@ -1610,7 +1610,15 @@ static void InitConfigureNamesBool() NULL, NULL, NULL}, - + {{"track_stmt_parameter", + PGC_SIGHUP, + INSTRUMENTS_OPTIONS, + gettext_noop("Enable to track the parameter of statements"), NULL}, + &u_sess->attr.attr_common.track_stmt_parameter, + false, + NULL, + NULL, + NULL}, {{"support_extended_features", PGC_POSTMASTER, DEVELOPER_OPTIONS, diff --git a/src/gausskernel/cbb/instruments/statement/instr_statement.cpp b/src/gausskernel/cbb/instruments/statement/instr_statement.cpp index 58462c159..ad876e7df 100644 --- a/src/gausskernel/cbb/instruments/statement/instr_statement.cpp +++ b/src/gausskernel/cbb/instruments/statement/instr_statement.cpp @@ -1453,6 +1453,20 @@ void instr_stmt_report_debug_query_id(uint64 debug_query_id) CURRENT_STMT_METRIC_HANDLE->debug_query_id = debug_query_id; } +void instr_stmt_track_param_query(const char *query) +{ + if (CURRENT_STMT_METRIC_HANDLE->params == NULL) { + CURRENT_STMT_METRIC_HANDLE->query = pstrdup(query); + } else { + Size len = strlen(query) + strlen(CURRENT_STMT_METRIC_HANDLE->params) + 2; + CURRENT_STMT_METRIC_HANDLE->query = (char *)palloc(len * sizeof(char)); + errno_t rc = sprintf_s(CURRENT_STMT_METRIC_HANDLE->query, len, "%s;%s", + query, CURRENT_STMT_METRIC_HANDLE->params); + securec_check_ss_c(rc, "\0", "\0"); + pfree_ext(CURRENT_STMT_METRIC_HANDLE->params); + } +} + /* using unique query */ void instr_stmt_report_query(uint64 unique_query_id) { @@ -1460,13 +1474,23 @@ void instr_stmt_report_query(uint64 unique_query_id) CURRENT_STMT_METRIC_HANDLE->unique_query_id = unique_query_id; CURRENT_STMT_METRIC_HANDLE->unique_sql_cn_id = u_sess->unique_sql_cxt.unique_sql_cn_id; - if (is_local_unique_sql()) { - MemoryContext old_ctx = MemoryContextSwitchTo(u_sess->statement_cxt.stmt_stat_cxt); - if (CURRENT_STMT_METRIC_HANDLE->query == NULL) { - CURRENT_STMT_METRIC_HANDLE->query = FindCurrentUniqueSQL(); - } - (void)MemoryContextSwitchTo(old_ctx); + if (!is_local_unique_sql() || CURRENT_STMT_METRIC_HANDLE->query) { + return; } + + MemoryContext old_ctx = MemoryContextSwitchTo(u_sess->statement_cxt.stmt_stat_cxt); + + if (!u_sess->attr.attr_common.track_stmt_parameter) { + CURRENT_STMT_METRIC_HANDLE->query = FindCurrentUniqueSQL(); + } else { + if (u_sess->unique_sql_cxt.curr_single_unique_sql != NULL) { + instr_stmt_track_param_query(u_sess->unique_sql_cxt.curr_single_unique_sql); + } else { + instr_stmt_track_param_query(t_thrd.postgres_cxt.debug_query_string); + } + } + + (void)MemoryContextSwitchTo(old_ctx); } void instr_stmt_report_txid(uint64 txid) @@ -1592,8 +1616,7 @@ void instr_stmt_report_unique_sql_info(const PgStat_TableCounts *agg_table_stat, bool instr_stmt_need_track_plan() { - if (CURRENT_STMT_METRIC_HANDLE == NULL || CURRENT_STMT_METRIC_HANDLE->level <= STMT_TRACK_L0 || - CURRENT_STMT_METRIC_HANDLE->level > STMT_TRACK_L2) + if (CURRENT_STMT_METRIC_HANDLE == NULL || CURRENT_STMT_METRIC_HANDLE->level > STMT_TRACK_L2) return false; return true; @@ -1602,8 +1625,7 @@ bool instr_stmt_need_track_plan() void instr_stmt_report_query_plan(QueryDesc *queryDesc) { StatementStatContext *ssctx = (StatementStatContext *)u_sess->statement_cxt.curStatementMetrics; - if (queryDesc == NULL || ssctx == NULL || ssctx->level <= STMT_TRACK_L0 - || ssctx->level > STMT_TRACK_L2 || ssctx->plan_size != 0) { + if (queryDesc == NULL || ssctx == NULL || ssctx->level > STMT_TRACK_L2 || ssctx->plan_size != 0) { return; } diff --git a/src/gausskernel/cbb/instruments/unique_sql/instr_unique_sql.cpp b/src/gausskernel/cbb/instruments/unique_sql/instr_unique_sql.cpp index 22f79a44a..52dab071d 100644 --- a/src/gausskernel/cbb/instruments/unique_sql/instr_unique_sql.cpp +++ b/src/gausskernel/cbb/instruments/unique_sql/instr_unique_sql.cpp @@ -1823,6 +1823,74 @@ static void SetLocalUniqueSQLId(List* query_list) } } +/* Set parameters from portal */ +void SetParamsFromPortal(Portal portal) +{ + CHECK_STMT_HANDLE(); + Assert(portal); + ParamListInfo params = portal->portalParams; + + if (!u_sess->attr.attr_common.track_stmt_parameter || CURRENT_STMT_METRIC_HANDLE->params) { + return; + } + + /* We mustn't call user-defined I/O functions when in an aborted xact */ + if (params && params->numParams > 0 && !IsAbortedTransactionBlockState()) { + StringInfoData param_str; + MemoryContext oldcontext; + int paramno; + + initStringInfo(¶m_str); + + for (paramno = 0; paramno < params->numParams; paramno++) { + ParamExternData* prm = ¶ms->params[paramno]; + Oid typoutput; + bool typisvarlena = false; + char* pstring = NULL; + char* p = NULL; + + appendStringInfo(¶m_str, "%s$%d = ", (paramno > 0) ? ", " : "parameters: ", paramno + 1); + + if (prm->isnull || !OidIsValid(prm->ptype)) { + appendStringInfoString(¶m_str, "NULL"); + continue; + } + + getTypeOutputInfo(prm->ptype, &typoutput, &typisvarlena); + + pstring = OidOutputFunctionCall(typoutput, prm->value); + + appendStringInfoCharMacro(¶m_str, '\''); + for (p = pstring; *p; p++) { + if (*p == '\'') /* double single quotes */ + appendStringInfoCharMacro(¶m_str, *p); + } + appendStringInfoCharMacro(¶m_str, '\''); + + pfree(pstring); + } + + oldcontext = MemoryContextSwitchTo(u_sess->statement_cxt.stmt_stat_cxt); + + CURRENT_STMT_METRIC_HANDLE->params = pstrdup(param_str.data); + + pfree(param_str.data); + + if (CURRENT_STMT_METRIC_HANDLE->query) { + Size len = strlen(CURRENT_STMT_METRIC_HANDLE->query) + strlen(CURRENT_STMT_METRIC_HANDLE->params) + 2; + char *tmpstr = (char *)palloc(len * sizeof(char)); + errno_t rc = sprintf_s(tmpstr, len, "%s;%s", CURRENT_STMT_METRIC_HANDLE->query, + CURRENT_STMT_METRIC_HANDLE->params); + securec_check_ss_c(rc, "\0", "\0"); + pfree(CURRENT_STMT_METRIC_HANDLE->query); + pfree_ext(CURRENT_STMT_METRIC_HANDLE->params); + CURRENT_STMT_METRIC_HANDLE->query = tmpstr; + } + + MemoryContextSwitchTo(oldcontext); + } +} + /* * set current prepared statement's unique sql id * @@ -1840,6 +1908,8 @@ void SetUniqueSQLIdFromPortal(Portal portal, CachedPlanSource* unnamed_psrc) return; } + SetParamsFromPortal(portal); + List* query_list = NULL; if (portal->prepStmtName && portal->prepStmtName[0] != '\0') { /* for named prepared statement */ diff --git a/src/include/instruments/instr_statement.h b/src/include/instruments/instr_statement.h index 009ee360e..7c343374a 100644 --- a/src/include/instruments/instr_statement.h +++ b/src/include/instruments/instr_statement.h @@ -180,6 +180,7 @@ typedef struct StatementStatContext { TransactionId txn_id; UniqueSQLParse parse; char* query_plan; /* query plan */ + char* params; /* params for pbe statements */ uint64 plan_size; LockSummaryStat lock_summary; StatementDetail details; diff --git a/src/include/knl/knl_guc/knl_session_attr_common.h b/src/include/knl/knl_guc/knl_session_attr_common.h index 60becb840..82fff11be 100644 --- a/src/include/knl/knl_guc/knl_session_attr_common.h +++ b/src/include/knl/knl_guc/knl_session_attr_common.h @@ -179,6 +179,7 @@ typedef struct knl_session_attr_common { int instr_rt_percentile_interval; bool enable_instr_rt_percentile; + bool track_stmt_parameter; char* percentile_values; /* instr - full sql/slow sql */