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
parent
8e39b02bce
commit
a93ba37ac3
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue