mirror of
https://github.com/postgres/postgres.git
synced 2025-11-18 02:02:55 +03:00
Converge all SQL-level statistics timing values to float8 milliseconds.
This patch adjusts the core statistics views to match the decision already taken for pg_stat_statements, that values representing elapsed time should be represented as float8 and measured in milliseconds. By using float8, we are no longer tied to a specific maximum precision of timing data. (Internally, it's still microseconds, but we could now change that without needing changes at the SQL level.) The columns affected are pg_stat_bgwriter.checkpoint_write_time pg_stat_bgwriter.checkpoint_sync_time pg_stat_database.blk_read_time pg_stat_database.blk_write_time pg_stat_user_functions.total_time pg_stat_user_functions.self_time pg_stat_xact_user_functions.total_time pg_stat_xact_user_functions.self_time The first four of these are new in 9.2, so there is no compatibility issue from changing them. The others require a release note comment that they are now double precision (and can show a fractional part) rather than bigint as before; also their underlying statistics functions now match the column definitions, instead of returning bigint microseconds.
This commit is contained in:
@@ -7511,7 +7511,6 @@ LogCheckpointEnd(bool restartpoint)
|
||||
|
||||
CheckpointStats.ckpt_end_t = GetCurrentTimestamp();
|
||||
|
||||
|
||||
TimestampDifference(CheckpointStats.ckpt_write_t,
|
||||
CheckpointStats.ckpt_sync_t,
|
||||
&write_secs, &write_usecs);
|
||||
@@ -7520,7 +7519,7 @@ LogCheckpointEnd(bool restartpoint)
|
||||
CheckpointStats.ckpt_sync_end_t,
|
||||
&sync_secs, &sync_usecs);
|
||||
|
||||
/* Record checkpoint timing summary data. */
|
||||
/* Accumulate checkpoint timing summary data, in milliseconds. */
|
||||
BgWriterStats.m_checkpoint_write_time +=
|
||||
write_secs * 1000 + write_usecs / 1000;
|
||||
BgWriterStats.m_checkpoint_sync_time +=
|
||||
|
||||
@@ -604,8 +604,8 @@ CREATE VIEW pg_stat_database AS
|
||||
pg_stat_get_db_temp_files(D.oid) AS temp_files,
|
||||
pg_stat_get_db_temp_bytes(D.oid) AS temp_bytes,
|
||||
pg_stat_get_db_deadlocks(D.oid) AS deadlocks,
|
||||
pg_stat_get_db_blk_read_time(D.oid) / 1000 AS blk_read_time,
|
||||
pg_stat_get_db_blk_write_time(D.oid) / 1000 AS blk_write_time,
|
||||
pg_stat_get_db_blk_read_time(D.oid) AS blk_read_time,
|
||||
pg_stat_get_db_blk_write_time(D.oid) AS blk_write_time,
|
||||
pg_stat_get_db_stat_reset_time(D.oid) AS stats_reset
|
||||
FROM pg_database D;
|
||||
|
||||
@@ -626,8 +626,8 @@ CREATE VIEW pg_stat_user_functions AS
|
||||
N.nspname AS schemaname,
|
||||
P.proname AS funcname,
|
||||
pg_stat_get_function_calls(P.oid) AS calls,
|
||||
pg_stat_get_function_time(P.oid) / 1000 AS total_time,
|
||||
pg_stat_get_function_self_time(P.oid) / 1000 AS self_time
|
||||
pg_stat_get_function_total_time(P.oid) AS total_time,
|
||||
pg_stat_get_function_self_time(P.oid) AS self_time
|
||||
FROM pg_proc P LEFT JOIN pg_namespace N ON (N.oid = P.pronamespace)
|
||||
WHERE P.prolang != 12 -- fast check to eliminate built-in functions
|
||||
AND pg_stat_get_function_calls(P.oid) IS NOT NULL;
|
||||
@@ -638,8 +638,8 @@ CREATE VIEW pg_stat_xact_user_functions AS
|
||||
N.nspname AS schemaname,
|
||||
P.proname AS funcname,
|
||||
pg_stat_get_xact_function_calls(P.oid) AS calls,
|
||||
pg_stat_get_xact_function_time(P.oid) / 1000 AS total_time,
|
||||
pg_stat_get_xact_function_self_time(P.oid) / 1000 AS self_time
|
||||
pg_stat_get_xact_function_total_time(P.oid) AS total_time,
|
||||
pg_stat_get_xact_function_self_time(P.oid) AS self_time
|
||||
FROM pg_proc P LEFT JOIN pg_namespace N ON (N.oid = P.pronamespace)
|
||||
WHERE P.prolang != 12 -- fast check to eliminate built-in functions
|
||||
AND pg_stat_get_xact_function_calls(P.oid) IS NOT NULL;
|
||||
|
||||
@@ -848,8 +848,8 @@ pgstat_send_funcstats(void)
|
||||
m_ent = &msg.m_entry[msg.m_nentries];
|
||||
m_ent->f_id = entry->f_id;
|
||||
m_ent->f_numcalls = entry->f_counts.f_numcalls;
|
||||
m_ent->f_time = INSTR_TIME_GET_MICROSEC(entry->f_counts.f_time);
|
||||
m_ent->f_time_self = INSTR_TIME_GET_MICROSEC(entry->f_counts.f_time_self);
|
||||
m_ent->f_total_time = INSTR_TIME_GET_MICROSEC(entry->f_counts.f_total_time);
|
||||
m_ent->f_self_time = INSTR_TIME_GET_MICROSEC(entry->f_counts.f_self_time);
|
||||
|
||||
if (++msg.m_nentries >= PGSTAT_NUM_FUNCENTRIES)
|
||||
{
|
||||
@@ -1467,7 +1467,7 @@ pgstat_init_function_usage(FunctionCallInfoData *fcinfo,
|
||||
fcu->fs = &htabent->f_counts;
|
||||
|
||||
/* save stats for this function, later used to compensate for recursion */
|
||||
fcu->save_f_time = htabent->f_counts.f_time;
|
||||
fcu->save_f_total_time = htabent->f_counts.f_total_time;
|
||||
|
||||
/* save current backend-wide total time */
|
||||
fcu->save_total = total_func_time;
|
||||
@@ -1528,19 +1528,19 @@ pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
|
||||
INSTR_TIME_ADD(total_func_time, f_self);
|
||||
|
||||
/*
|
||||
* Compute the new total f_time as the total elapsed time added to the
|
||||
* pre-call value of f_time. This is necessary to avoid double-counting
|
||||
* any time taken by recursive calls of myself. (We do not need any
|
||||
* similar kluge for self time, since that already excludes any recursive
|
||||
* calls.)
|
||||
* Compute the new f_total_time as the total elapsed time added to the
|
||||
* pre-call value of f_total_time. This is necessary to avoid
|
||||
* double-counting any time taken by recursive calls of myself. (We do
|
||||
* not need any similar kluge for self time, since that already excludes
|
||||
* any recursive calls.)
|
||||
*/
|
||||
INSTR_TIME_ADD(f_total, fcu->save_f_time);
|
||||
INSTR_TIME_ADD(f_total, fcu->save_f_total_time);
|
||||
|
||||
/* update counters in function stats table */
|
||||
if (finalize)
|
||||
fs->f_numcalls++;
|
||||
fs->f_time = f_total;
|
||||
INSTR_TIME_ADD(fs->f_time_self, f_self);
|
||||
fs->f_total_time = f_total;
|
||||
INSTR_TIME_ADD(fs->f_self_time, f_self);
|
||||
|
||||
/* indicate that we have something to send */
|
||||
have_function_stats = true;
|
||||
@@ -4573,8 +4573,8 @@ pgstat_recv_funcstat(PgStat_MsgFuncstat *msg, int len)
|
||||
* we just got.
|
||||
*/
|
||||
funcentry->f_numcalls = funcmsg->f_numcalls;
|
||||
funcentry->f_time = funcmsg->f_time;
|
||||
funcentry->f_time_self = funcmsg->f_time_self;
|
||||
funcentry->f_total_time = funcmsg->f_total_time;
|
||||
funcentry->f_self_time = funcmsg->f_self_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4582,8 +4582,8 @@ pgstat_recv_funcstat(PgStat_MsgFuncstat *msg, int len)
|
||||
* Otherwise add the values to the existing entry.
|
||||
*/
|
||||
funcentry->f_numcalls += funcmsg->f_numcalls;
|
||||
funcentry->f_time += funcmsg->f_time;
|
||||
funcentry->f_time_self += funcmsg->f_time_self;
|
||||
funcentry->f_total_time += funcmsg->f_total_time;
|
||||
funcentry->f_self_time += funcmsg->f_self_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ extern Datum pg_stat_get_analyze_count(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_stat_get_autoanalyze_count(PG_FUNCTION_ARGS);
|
||||
|
||||
extern Datum pg_stat_get_function_calls(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_stat_get_function_time(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_stat_get_function_total_time(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_stat_get_function_self_time(PG_FUNCTION_ARGS);
|
||||
|
||||
extern Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS);
|
||||
@@ -108,7 +108,7 @@ extern Datum pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS);
|
||||
|
||||
extern Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_stat_get_xact_function_time(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_stat_get_xact_function_total_time(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS);
|
||||
|
||||
extern Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS);
|
||||
@@ -439,14 +439,15 @@ pg_stat_get_function_calls(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
Datum
|
||||
pg_stat_get_function_time(PG_FUNCTION_ARGS)
|
||||
pg_stat_get_function_total_time(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid funcid = PG_GETARG_OID(0);
|
||||
PgStat_StatFuncEntry *funcentry;
|
||||
|
||||
if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
|
||||
PG_RETURN_NULL();
|
||||
PG_RETURN_INT64(funcentry->f_time);
|
||||
/* convert counter from microsec to millisec for display */
|
||||
PG_RETURN_FLOAT8(((double) funcentry->f_total_time) / 1000.0);
|
||||
}
|
||||
|
||||
Datum
|
||||
@@ -457,7 +458,8 @@ pg_stat_get_function_self_time(PG_FUNCTION_ARGS)
|
||||
|
||||
if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
|
||||
PG_RETURN_NULL();
|
||||
PG_RETURN_INT64(funcentry->f_time_self);
|
||||
/* convert counter from microsec to millisec for display */
|
||||
PG_RETURN_FLOAT8(((double) funcentry->f_self_time) / 1000.0);
|
||||
}
|
||||
|
||||
Datum
|
||||
@@ -1365,30 +1367,32 @@ Datum
|
||||
pg_stat_get_db_blk_read_time(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid dbid = PG_GETARG_OID(0);
|
||||
int64 result;
|
||||
double result;
|
||||
PgStat_StatDBEntry *dbentry;
|
||||
|
||||
/* convert counter from microsec to millisec for display */
|
||||
if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
|
||||
result = 0;
|
||||
else
|
||||
result = (int64) (dbentry->n_block_read_time);
|
||||
result = ((double) dbentry->n_block_read_time) / 1000.0;
|
||||
|
||||
PG_RETURN_INT64(result);
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
Datum
|
||||
pg_stat_get_db_blk_write_time(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid dbid = PG_GETARG_OID(0);
|
||||
int64 result;
|
||||
double result;
|
||||
PgStat_StatDBEntry *dbentry;
|
||||
|
||||
/* convert counter from microsec to millisec for display */
|
||||
if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
|
||||
result = 0;
|
||||
else
|
||||
result = (int64) (dbentry->n_block_write_time);
|
||||
result = ((double) dbentry->n_block_write_time) / 1000.0;
|
||||
|
||||
PG_RETURN_INT64(result);
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
Datum
|
||||
@@ -1424,13 +1428,15 @@ pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_stat_get_checkpoint_write_time(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_INT64(pgstat_fetch_global()->checkpoint_write_time);
|
||||
/* time is already in msec, just convert to double for presentation */
|
||||
PG_RETURN_FLOAT8((double) pgstat_fetch_global()->checkpoint_write_time);
|
||||
}
|
||||
|
||||
Datum
|
||||
pg_stat_get_checkpoint_sync_time(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_INT64(pgstat_fetch_global()->checkpoint_sync_time);
|
||||
/* time is already in msec, just convert to double for presentation */
|
||||
PG_RETURN_FLOAT8((double) pgstat_fetch_global()->checkpoint_sync_time);
|
||||
}
|
||||
|
||||
Datum
|
||||
@@ -1622,14 +1628,14 @@ pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
Datum
|
||||
pg_stat_get_xact_function_time(PG_FUNCTION_ARGS)
|
||||
pg_stat_get_xact_function_total_time(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid funcid = PG_GETARG_OID(0);
|
||||
PgStat_BackendFunctionEntry *funcentry;
|
||||
|
||||
if ((funcentry = find_funcstat_entry(funcid)) == NULL)
|
||||
PG_RETURN_NULL();
|
||||
PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time));
|
||||
PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(funcentry->f_counts.f_total_time));
|
||||
}
|
||||
|
||||
Datum
|
||||
@@ -1640,7 +1646,7 @@ pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS)
|
||||
|
||||
if ((funcentry = find_funcstat_entry(funcid)) == NULL)
|
||||
PG_RETURN_NULL();
|
||||
PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time_self));
|
||||
PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(funcentry->f_counts.f_self_time));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user