feat (WDR): add a new GUC track_stmt_parameter and can get query plan under L1 level
This commit is contained in:
@ -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|
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user