PG-400: pg_stat_monitor: Timezone in msgtime column...
The bucket start time reported by pg_stat_monitor does not match the PG time and timezone. The fix is to use TimestampTz for recording the bucket start time.pull/356/head
parent
f9ef1455ae
commit
a75e47add9
|
@ -1697,16 +1697,14 @@ pg_stat_monitor(PG_FUNCTION_ARGS)
|
||||||
static bool
|
static bool
|
||||||
IsBucketValid(uint64 bucketid)
|
IsBucketValid(uint64 bucketid)
|
||||||
{
|
{
|
||||||
time_t bucket_t,
|
long secs;
|
||||||
current_t;
|
int microsecs;
|
||||||
double diff_t;
|
TimestampTz current_tz = GetCurrentTimestamp();
|
||||||
pgssSharedState *pgss = pgsm_get_ss();
|
pgssSharedState *pgss = pgsm_get_ss();
|
||||||
|
|
||||||
bucket_t = mktime(&pgss->bucket_start_time[bucketid]);
|
TimestampDifference(pgss->bucket_start_time[bucketid], current_tz,&secs, µsecs);
|
||||||
|
|
||||||
time(¤t_t);
|
if (secs > (PGSM_BUCKET_TIME * PGSM_MAX_BUCKETS))
|
||||||
diff_t = difftime(current_t, bucket_t);
|
|
||||||
if (diff_t > (PGSM_BUCKET_TIME * PGSM_MAX_BUCKETS))
|
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1984,11 +1982,8 @@ 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++] = TimestampTzGetDatum(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 */
|
||||||
|
@ -2142,7 +2137,7 @@ get_next_wbucket(pgssSharedState *pgss)
|
||||||
uint64 current_bucket_sec;
|
uint64 current_bucket_sec;
|
||||||
uint64 new_bucket_id;
|
uint64 new_bucket_id;
|
||||||
uint64 prev_bucket_id;
|
uint64 prev_bucket_id;
|
||||||
struct tm *lt;
|
struct tm;
|
||||||
bool update_bucket = false;
|
bool update_bucket = false;
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
|
@ -2187,18 +2182,14 @@ get_next_wbucket(pgssSharedState *pgss)
|
||||||
|
|
||||||
LWLockRelease(pgss->lock);
|
LWLockRelease(pgss->lock);
|
||||||
|
|
||||||
tv.tv_sec = (tv.tv_sec) - (tv.tv_sec % PGSM_BUCKET_TIME);
|
|
||||||
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 */
|
||||||
|
tv.tv_sec = (tv.tv_sec) - (tv.tv_sec % PGSM_BUCKET_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));
|
|
||||||
|
pgss->bucket_start_time[new_bucket_id] = (TimestampTz) tv.tv_sec -
|
||||||
|
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
|
||||||
|
pgss->bucket_start_time[new_bucket_id] = pgss->bucket_start_time[new_bucket_id] * USECS_PER_SEC;
|
||||||
return new_bucket_id;
|
return new_bucket_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -352,7 +352,7 @@ 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];
|
||||||
struct tm bucket_start_time[MAX_BUCKETS]; /* start time of the bucket */
|
TimestampTz bucket_start_time[MAX_BUCKETS]; /* start time of the bucket */
|
||||||
LWLock *errors_lock; /* protects errors hashtable
|
LWLock *errors_lock; /* protects errors hashtable
|
||||||
* search/modification */
|
* search/modification */
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue