PG-246, PG-211, PG-147: Fix performance issue while querying the pg_stat_monitor.

This performance fix resolves two more issues (PG-211, PG-147).
pull/116/head
Ibrar Ahmed 2021-10-05 20:33:34 +00:00
parent 8e39b02bce
commit a93ba37ac3
2 changed files with 46 additions and 29 deletions

View File

@ -36,6 +36,7 @@ CREATE FUNCTION pg_stat_monitor_internal(IN showtext boolean,
OUT query_plan text, OUT query_plan text,
OUT state_code int8, OUT state_code int8,
OUT top_queryid text, OUT top_queryid text,
OUT top_query text,
OUT application_name text, OUT application_name text,
OUT relations text, -- 11 OUT relations text, -- 11
@ -148,7 +149,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
comments, comments,
planid, planid,
query_plan, query_plan,
(SELECT query from pg_stat_monitor_internal(true) s where s.queryid = p.top_queryid and s.bucket = p.bucket) AS top_query, top_query,
application_name, application_name,
string_to_array(relations, ',') AS relations, string_to_array(relations, ',') AS relations,
cmd_type, cmd_type,
@ -157,17 +158,17 @@ CREATE VIEW pg_stat_monitor AS SELECT
sqlcode, sqlcode,
message, message,
calls, calls,
round( CAST(total_time as numeric), 4)::float8 as total_time, total_time,
round( CAST(min_time as numeric), 4)::float8 as min_time, min_time,
round( CAST(max_time as numeric), 4)::float8 as max_time, max_time,
round( CAST(mean_time as numeric), 4)::float8 as mean_time, mean_time,
round( CAST(stddev_time as numeric), 4)::float8 as stddev_time, stddev_time,
rows_retrieved, rows_retrieved,
plans_calls, plans_calls,
round( CAST(plan_total_time as numeric), 4)::float8 as plan_total_time, plan_total_time,
round( CAST(plan_min_time as numeric), 4)::float8 as plan_min_time, plan_min_time,
round( CAST(plan_max_time as numeric), 4)::float8 as plan_max_time, plan_max_time,
round( CAST(plan_mean_time as numeric), 4)::float8 as plan_mean_time, plan_mean_time,
shared_blks_hit, shared_blks_hit,
shared_blks_read, shared_blks_read,
@ -182,8 +183,8 @@ CREATE VIEW pg_stat_monitor AS SELECT
blk_read_time, blk_read_time,
blk_write_time, blk_write_time,
(string_to_array(resp_calls, ',')) resp_calls, (string_to_array(resp_calls, ',')) resp_calls,
round(cpu_user_time::numeric, 4) as cpu_user_time, cpu_user_time,
round(cpu_sys_time::numeric, 4) as cpu_sys_time, cpu_sys_time,
wal_records, wal_records,
wal_fpi, wal_fpi,
wal_bytes, wal_bytes,

View File

@ -25,9 +25,11 @@
PG_MODULE_MAGIC; PG_MODULE_MAGIC;
#define BUILD_VERSION "0.9.2-beta1" #define BUILD_VERSION "0.9.2-beta1"
#define PG_STAT_STATEMENTS_COLS 52 /* maximum of above */ #define PG_STAT_STATEMENTS_COLS 53 /* maximum of above */
#define PGSM_TEXT_FILE "/tmp/pg_stat_monitor_query" #define PGSM_TEXT_FILE "/tmp/pg_stat_monitor_query"
#define roundf(x,d) ((floor(((x)*pow(10,d))+.5))/pow(10,d))
#define PGUNSIXBIT(val) (((val) & 0x3F) + '0') #define PGUNSIXBIT(val) (((val) & 0x3F) + '0')
#define _snprintf(_str_dst, _str_src, _len, _max_len)\ #define _snprintf(_str_dst, _str_src, _len, _max_len)\
@ -1648,7 +1650,8 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
char parentid_txt[32]; char parentid_txt[32];
pgssSharedState *pgss = pgsm_get_ss(); pgssSharedState *pgss = pgsm_get_ss();
HTAB *pgss_hash = pgsm_get_hash(); HTAB *pgss_hash = pgsm_get_hash();
char *query_txt = (char*) malloc(PGSM_QUERY_MAX_LEN); char *query_txt = (char*) palloc0(PGSM_QUERY_MAX_LEN);
char *parent_query_txt = (char*) palloc0(PGSM_QUERY_MAX_LEN);
/* Safety check... */ /* Safety check... */
if (!IsSystemInitialized()) if (!IsSystemInitialized())
@ -1675,7 +1678,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 != 49) if (tupdesc->natts != 50)
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);
@ -1714,6 +1717,7 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
if (query_entry == NULL) if (query_entry == NULL)
continue; continue;
if (read_query(buf, bucketid, queryid, query_txt) == 0) if (read_query(buf, bucketid, queryid, query_txt) == 0)
{ {
int len; int len;
@ -1734,6 +1738,16 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
if (tmp.state == PGSS_FINISHED) if (tmp.state == PGSS_FINISHED)
continue; continue;
} }
if (tmp.info.parentid != UINT64CONST(0))
{
int len = 0;
if (read_query(buf, bucketid, tmp.info.parentid, parent_query_txt) == 0)
{
len = read_query_buffer(bucketid, tmp.info.parentid, parent_query_txt);
if (len != MAX_QUERY_BUFFER_BUCKET)
snprintf(parent_query_txt, 32, "%s", "<insufficient disk/shared space>");
}
}
/* bucketid at column number 0 */ /* bucketid at column number 0 */
values[i++] = Int64GetDatumFast(bucketid); values[i++] = Int64GetDatumFast(bucketid);
@ -1808,10 +1822,12 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
{ {
snprintf(parentid_txt, 32, "%08lX",tmp.info.parentid); snprintf(parentid_txt, 32, "%08lX",tmp.info.parentid);
values[i++] = CStringGetTextDatum(parentid_txt); values[i++] = CStringGetTextDatum(parentid_txt);
values[i++] = CStringGetTextDatum(parent_query_txt);
} }
else else
{ {
nulls[i++] = true; nulls[i++] = true;
nulls[i++] = true;
} }
/* application_name at column number 9 */ /* application_name at column number 9 */
@ -1880,23 +1896,23 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
values[i++] = Int64GetDatumFast(tmp.calls.calls); values[i++] = Int64GetDatumFast(tmp.calls.calls);
/* total_time at column number 17 */ /* total_time at column number 17 */
values[i++] = Float8GetDatumFast(tmp.time.total_time); values[i++] = Float8GetDatumFast(roundf(tmp.time.total_time, 4));
/* min_time at column number 18 */ /* min_time at column number 18 */
values[i++] = Float8GetDatumFast(tmp.time.min_time); values[i++] = Float8GetDatumFast(roundf(tmp.time.min_time,4));
/* max_time at column number 19 */ /* max_time at column number 19 */
values[i++] = Float8GetDatumFast(tmp.time.max_time); values[i++] = Float8GetDatumFast(roundf(tmp.time.max_time,4));
/* mean_time at column number 20 */ /* mean_time at column number 20 */
values[i++] = Float8GetDatumFast(tmp.time.mean_time); values[i++] = Float8GetDatumFast(roundf(tmp.time.mean_time,4));
if (tmp.calls.calls > 1) if (tmp.calls.calls > 1)
stddev = sqrt(tmp.time.sum_var_time / tmp.calls.calls); stddev = sqrt(tmp.time.sum_var_time / tmp.calls.calls);
else else
stddev = 0.0; stddev = 0.0;
/* calls at column number 21 */ /* calls at column number 21 */
values[i++] = Float8GetDatumFast(stddev); values[i++] = Float8GetDatumFast(roundf(stddev,4));
/* calls at column number 22 */ /* calls at column number 22 */
values[i++] = Int64GetDatumFast(tmp.calls.rows); values[i++] = Int64GetDatumFast(tmp.calls.rows);
@ -1912,23 +1928,23 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
values[i++] = Int64GetDatumFast(tmp.plancalls.calls); values[i++] = Int64GetDatumFast(tmp.plancalls.calls);
/* total_time at column number 24 */ /* total_time at column number 24 */
values[i++] = Float8GetDatumFast(tmp.plantime.total_time); values[i++] = Float8GetDatumFast(roundf(tmp.plantime.total_time,4));
/* min_time at column number 25 */ /* min_time at column number 25 */
values[i++] = Float8GetDatumFast(tmp.plantime.min_time); values[i++] = Float8GetDatumFast(roundf(tmp.plantime.min_time,4));
/* max_time at column number 26 */ /* max_time at column number 26 */
values[i++] = Float8GetDatumFast(tmp.plantime.max_time); values[i++] = Float8GetDatumFast(roundf(tmp.plantime.max_time,4));
/* mean_time at column number 27 */ /* mean_time at column number 27 */
values[i++] = Float8GetDatumFast(tmp.plantime.mean_time); values[i++] = Float8GetDatumFast(roundf(tmp.plantime.mean_time,4));
if (tmp.plancalls.calls > 1) if (tmp.plancalls.calls > 1)
stddev = sqrt(tmp.plantime.sum_var_time / tmp.plancalls.calls); stddev = sqrt(tmp.plantime.sum_var_time / tmp.plancalls.calls);
else else
stddev = 0.0; stddev = 0.0;
/* calls at column number 28 */ /* calls at column number 28 */
values[i++] = Float8GetDatumFast(stddev); values[i++] = Float8GetDatumFast(roundf(stddev,4));
/* blocks are from column number 29 - 40 */ /* blocks are from column number 29 - 40 */
values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_hit); values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_hit);
@ -1948,10 +1964,10 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
values[i++] = IntArrayGetTextDatum(tmp.resp_calls, MAX_RESPONSE_BUCKET); values[i++] = IntArrayGetTextDatum(tmp.resp_calls, MAX_RESPONSE_BUCKET);
/* utime at column number 42 */ /* utime at column number 42 */
values[i++] = Float8GetDatumFast(tmp.sysinfo.utime); values[i++] = Float8GetDatumFast(roundf(tmp.sysinfo.utime,4));
/* stime at column number 43 */ /* stime at column number 43 */
values[i++] = Float8GetDatumFast(tmp.sysinfo.stime); values[i++] = Float8GetDatumFast(roundf(tmp.sysinfo.stime,4));
{ {
char buf[256]; char buf[256];
Datum wal_bytes; Datum wal_bytes;
@ -1980,7 +1996,8 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
} }
tuplestore_putvalues(tupstore, tupdesc, values, nulls); tuplestore_putvalues(tupstore, tupdesc, values, nulls);
} }
free(query_txt); pfree(query_txt);
pfree(parent_query_txt);
/* clean up and return the tuplestore */ /* clean up and return the tuplestore */
LWLockRelease(pgss->lock); LWLockRelease(pgss->lock);
@ -3018,7 +3035,6 @@ read_query(unsigned char *buf, uint64 bucketid, uint64 queryid, char * query)
memcpy(&query_id, &buf[rlen], sizeof (uint64)); /* query id */ memcpy(&query_id, &buf[rlen], sizeof (uint64)); /* query id */
if (query_id == queryid) if (query_id == queryid)
found = true; found = true;
rlen += sizeof (uint64); rlen += sizeof (uint64);
if (buf_len <= rlen) if (buf_len <= rlen)
continue; continue;