PG-310: Bucket is “Done” vs still being current/last. (#321)

A new column is added to mention that bucket is active or done. there is    
some timing based adjustment was required with that too.   

Co-authored-by: Hamid Akhtar <hamid.akhtar@percona.com>
pull/325/head
Ibrar Ahmed 2022-11-23 02:23:28 +05:00 committed by GitHub
parent b4ab2ccc84
commit f7860b472f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 21 deletions

View File

@ -69,7 +69,8 @@ CREATE FUNCTION pg_stat_monitor_internal(
OUT wal_fpi int8, OUT wal_fpi int8,
OUT wal_bytes numeric, OUT wal_bytes numeric,
OUT comments TEXT, OUT comments TEXT,
OUT toplevel BOOLEAN OUT toplevel BOOLEAN,
OUT bucket_done BOOLEAN
) )
RETURNS SETOF record RETURNS SETOF record
AS 'MODULE_PATHNAME', 'pg_stat_monitor_2_0' AS 'MODULE_PATHNAME', 'pg_stat_monitor_2_0'
@ -124,7 +125,8 @@ CREATE VIEW pg_stat_monitor AS SELECT
cpu_sys_time, cpu_sys_time,
wal_records, wal_records,
wal_fpi, wal_fpi,
wal_bytes wal_bytes,
bucket_done
FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid
ORDER BY bucket_start_time; ORDER BY bucket_start_time;
RETURN 0; RETURN 0;
@ -242,6 +244,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
wal_records, wal_records,
wal_fpi, wal_fpi,
wal_bytes, wal_bytes,
bucket_done,
plans_calls, plans_calls,
total_plan_time, total_plan_time,

View File

@ -178,7 +178,8 @@ CREATE FUNCTION pg_stat_monitor_internal(
OUT wal_fpi int8, OUT wal_fpi int8,
OUT wal_bytes numeric, OUT wal_bytes numeric,
OUT comments TEXT, OUT comments TEXT,
OUT toplevel BOOLEAN OUT toplevel BOOLEAN,
OUT bucket_done BOOLEAN
) )
RETURNS SETOF record RETURNS SETOF record
AS 'MODULE_PATHNAME', 'pg_stat_monitor' AS 'MODULE_PATHNAME', 'pg_stat_monitor'

View File

@ -126,7 +126,7 @@ CREATE FUNCTION pg_stat_monitor_internal(
OUT elevel int, OUT elevel int,
OUT sqlcode TEXT, OUT sqlcode TEXT,
OUT message text, OUT message text,
OUT bucket_start_time timestamp, OUT bucket_start_time timestamptz,
OUT calls int8, -- 16 OUT calls int8, -- 16
@ -165,7 +165,8 @@ CREATE FUNCTION pg_stat_monitor_internal(
OUT wal_fpi int8, OUT wal_fpi int8,
OUT wal_bytes numeric, OUT wal_bytes numeric,
OUT comments TEXT, OUT comments TEXT,
OUT toplevel BOOLEAN OUT toplevel BOOLEAN,
OUT bucket_done BOOLEAN
) )
RETURNS SETOF record RETURNS SETOF record
AS 'MODULE_PATHNAME', 'pg_stat_monitor_2_0' AS 'MODULE_PATHNAME', 'pg_stat_monitor_2_0'
@ -219,7 +220,8 @@ CREATE VIEW pg_stat_monitor AS SELECT
cpu_sys_time, cpu_sys_time,
wal_records, wal_records,
wal_fpi, wal_fpi,
wal_bytes wal_bytes,
bucket_done
FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid FROM pg_stat_monitor_internal(TRUE) p, pg_database d WHERE dbid = oid
ORDER BY bucket_start_time; ORDER BY bucket_start_time;
RETURN 0; RETURN 0;
@ -276,6 +278,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
wal_records, wal_records,
wal_fpi, wal_fpi,
wal_bytes, wal_bytes,
bucket_done,
-- PostgreSQL-13 Specific Coulumns -- PostgreSQL-13 Specific Coulumns
plans_calls, plans_calls,
total_plan_time, total_plan_time,
@ -338,6 +341,7 @@ CREATE VIEW pg_stat_monitor AS SELECT
wal_records, wal_records,
wal_fpi, wal_fpi,
wal_bytes, wal_bytes,
bucket_done,
plans_calls, plans_calls,
total_plan_time, total_plan_time,

View File

@ -36,7 +36,7 @@
PG_MODULE_MAGIC; PG_MODULE_MAGIC;
#define BUILD_VERSION "2.0.0-dev" #define BUILD_VERSION "2.0.0-dev"
#define PG_STAT_STATEMENTS_COLS 52 /* maximum of above */ #define PG_STAT_STATEMENTS_COLS 53 /* maximum of above */
#define PGSM_TEXT_FILE PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat_monitor_query" #define PGSM_TEXT_FILE PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat_monitor_query"
#define roundf(x,d) ((floor(((x)*pow(10,d))+.5))/pow(10,d)) #define roundf(x,d) ((floor(((x)*pow(10,d))+.5))/pow(10,d))
@ -1613,15 +1613,12 @@ pg_stat_monitor(PG_FUNCTION_ARGS)
static bool static bool
IsBucketValid(uint64 bucketid) IsBucketValid(uint64 bucketid)
{ {
struct tm tm;
time_t bucket_t, time_t bucket_t,
current_t; current_t;
double diff_t; double diff_t;
pgssSharedState *pgss = pgsm_get_ss(); pgssSharedState *pgss = pgsm_get_ss();
memset(&tm, 0, sizeof(tm)); bucket_t = mktime(&pgss->bucket_start_time[bucketid]);
strptime(pgss->bucket_start_time[bucketid], "%Y-%m-%d %H:%M:%S", &tm);
bucket_t = mktime(&tm);
time(&current_t); time(&current_t);
diff_t = difftime(current_t, bucket_t); diff_t = difftime(current_t, bucket_t);
@ -1674,7 +1671,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 != 51) if (tupdesc->natts != 52)
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);
@ -1892,7 +1889,11 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
values[i++] = CStringGetTextDatum(tmp.error.message); values[i++] = CStringGetTextDatum(tmp.error.message);
/* bucket_start_time at column number 15 */ /* bucket_start_time at column number 15 */
values[i++] = CStringGetDatum(pgss->bucket_start_time[entry->key.bucket_id]); {
TimestampTz tm;
tm2timestamp((struct pg_tm*) &pgss->bucket_start_time[entry->key.bucket_id], 0, NULL, &tm);
values[i++] = TimestampGetDatum(tm);
}
if (tmp.calls.calls == 0) if (tmp.calls.calls == 0)
{ {
/* Query of pg_stat_monitor itslef started from zero count */ /* Query of pg_stat_monitor itslef started from zero count */
@ -2003,6 +2004,9 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
nulls[i++] = true; nulls[i++] = true;
} }
values[i++] = BoolGetDatum(toplevel); values[i++] = BoolGetDatum(toplevel);
values[i++] = BoolGetDatum(pg_atomic_read_u64(&pgss->current_wbucket) != bucketid);
/* clean up and return the tuplestore */
tuplestore_putvalues(tupstore, tupdesc, values, nulls); tuplestore_putvalues(tupstore, tupdesc, values, nulls);
} }
/* clean up and return the tuplestore */ /* clean up and return the tuplestore */
@ -2086,13 +2090,16 @@ get_next_wbucket(pgssSharedState *pgss)
tv.tv_sec = (tv.tv_sec) - (tv.tv_sec % PGSM_BUCKET_TIME); tv.tv_sec = (tv.tv_sec) - (tv.tv_sec % PGSM_BUCKET_TIME);
lt = localtime(&tv.tv_sec); lt = localtime(&tv.tv_sec);
/*
* Year is 1900 behind and month is 0 based, therefore we need to
* adjust that.
*/
lt->tm_year += 1900;
lt->tm_mon += 1;
/* Allign the value in prev_bucket_sec to the bucket start time */ /* Allign the value in prev_bucket_sec to the bucket start time */
pg_atomic_exchange_u64(&pgss->prev_bucket_sec, (uint64)tv.tv_sec); pg_atomic_exchange_u64(&pgss->prev_bucket_sec, (uint64)tv.tv_sec);
memcpy(&pgss->bucket_start_time[new_bucket_id], lt, sizeof(struct tm));
snprintf(pgss->bucket_start_time[new_bucket_id], sizeof(pgss->bucket_start_time[new_bucket_id]),
"%04d-%02d-%02d %02d:%02d:%02d", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);
return new_bucket_id; return new_bucket_id;
} }

View File

@ -317,11 +317,9 @@ typedef struct pgssSharedState
pg_atomic_uint64 current_wbucket; pg_atomic_uint64 current_wbucket;
pg_atomic_uint64 prev_bucket_sec; pg_atomic_uint64 prev_bucket_sec;
uint64 bucket_entry[MAX_BUCKETS]; uint64 bucket_entry[MAX_BUCKETS];
char bucket_start_time[MAX_BUCKETS][60]; /* start time of the struct tm bucket_start_time[MAX_BUCKETS]; /* start time of the bucket */
* bucket */
LWLock *errors_lock; /* protects errors hashtable LWLock *errors_lock; /* protects errors hashtable
* search/modification */ * search/modification */
/* /*
* These variables are used when pgsm_overflow_target is ON. * These variables are used when pgsm_overflow_target is ON.
* *