Merging the 1.1.0 branch back to main branch (#303)

* PG-475: Inconsistent behaviour of PGSM

Reverting the bucket locking mechanism to previous behavior. This has
a lot of room for improvement that needs to be part of a major refactoring
in the 2.x release.

* PG-481 Release notes 1.1.0 (#294)

modified:   RELEASE_NOTES.md

* PG-500: Bump the version of pg_stat_monitor to 1.1.0 (#297)

* PG-501: Missing Buckets and incorrect calls count. (#298)

prev_bucket_sec holds the actual time at which the previous bucket was created
and it is used to compute if the previous bucket time has elapsed and when is
the time to create a new one. But since the bucket start time is rounded down
to logical time window start, that makes the prev_bucket_sec and bucket start
time out of sync with each other, and depending on the query arrival time there
is a high probability that a bucket gets missed especially when the last bucket
was created around the end of the bucket time window.

Solution is to keep the prev_bucket_sec and bucket start time in-sync.

Moreover, we are using the unint64 for storing the prev_bucket_sec which is kind
of an overkill and a simple uint should be good enough for the purpose. But that
change can be taken up as part of the create-bucket function refactoring task.

* PG-501: Missing Buckets and incorrect calls count.

Ensuring the outer bound for the bucket is an exclusive boundary and it
as it belongs to the next bucket. To explain the point further, a set of
five second bucket would be:
    Bucket 1: 00:00:00.00 -> 00:00:04.99...
    Bucket 2: 00:00:00.05 -> 00:00:09.99...
    Bucket 3: 00:00:00.10 -> 00:00:14.99...
    ...

Co-authored-by: Ibrar Ahmed <ibrar.ahmed@percona.com>
Co-authored-by: Anastasia Alexandrova <anastasia.alexandrova@percona.com>
Co-authored-by: Muhammad Usama <m.usama@gmail.com>
pull/304/head
Hamid Akhtar 2022-09-13 15:59:39 +05:00 committed by GitHub
parent 16536ae07d
commit b920224e0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 46 deletions

View File

@ -2,7 +2,7 @@
"name": "pg_stat_monitor",
"abstract": "PostgreSQL Query Performance Monitoring Tool",
"description": "pg_stat_monitor is a PostgreSQL Query Performance Monitoring tool, based on PostgreSQL's contrib module pg_stat_statements. PostgreSQLs pg_stat_statements provides the basic statistics, which is sometimes not enough. The major shortcoming in pg_stat_statements is that it accumulates all the queries and their statistics and does not provide aggregated statistics nor histogram information. In this case, a user would need to calculate the aggregates, which is quite an expensive operation.",
"version": "1.1.0-dev",
"version": "1.1.0",
"maintainer": [
"ibrar.ahmed@percona.com"
],
@ -12,7 +12,7 @@
"abstract": "PostgreSQL Query Performance Monitoring Tool",
"file": "pg_stat_monitor--1.0.sql",
"docfile": "README.md",
"version": "1.1.0-dev"
"version": "1.1.0"
}
},
"prereqs": {

View File

@ -2,6 +2,26 @@
Below is the complete list of release notes for every version of ``pg_stat_monitor``.
## 1.1.0
### Improvements
[PG-474](https://jira.percona.com/browse/PG-474): Make pg_stat_monitor compiled with CLANG
[PG-159](https://jira.percona.com/browse/PG-159): Change the bucket start time scheme to align with the bucket time size
[PG-293](https://jira.percona.com/browse/PG-293): Add the ability to control features added on top of `pg_stat_monitor` using GUC (Grand Unified Configuration) parameters
[PG-300](https://jira.percona.com/browse/PG-300): Improve compatibility with PMM by making QueryIDs persistent for the same queries across different buckets and regardless of the node / client a query is executed on.
[PG-362](https://jira.percona.com/browse/PG-362): Fix the `pgsm_normalized_query` default value to provide query examples in the `pg_stat_monitor` view by default.
[PG-439](https://jira.percona.com/browse/PG-439): Remove warning of comparison of unsigned enum expression
### Bugs Fixed
[PG-221](https://jira.percona.com/browse/PG-221): Fixed the issue with pg_stat_monitor crashing when querying JSON with parallel workers enabled
[PG-289](https://jira.percona.com/browse/PG-289): Fixed the issue with pg_stat_monitor failing to build on C11 compilers by removing 'for' loop initial declarations
[PG-449](https://jira.percona.com/browse/PG-449): Fix comments visibility by correcting the behavior of the `pgsm_extract_comments` parameter
[PG-453](https://jira.percona.com/browse/PG-453): Fixed query normalization for INSERT statements in PostgreSQL 13 and earlier versions
[PG-455](https://jira.percona.com/browse/PG-455): Fixed the issue with data collection for any value specified for `pgsm_bucket_time` parameter within the min / max range
## 1.0.1
### Bugs Fixed

View File

@ -28,7 +28,7 @@
PG_MODULE_MAGIC;
#define BUILD_VERSION "1.1.0-dev"
#define BUILD_VERSION "1.1.0"
#define PG_STAT_STATEMENTS_COLS 53 /* maximum of above */
#define PGSM_TEXT_FILE PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat_monitor_query"
@ -2146,15 +2146,13 @@ static uint64
get_next_wbucket(pgssSharedState *pgss)
{
struct timeval tv;
uint64 current_sec;
uint64 current_bucket_sec;
uint64 new_bucket_id;
uint64 prev_bucket_id;
struct tm *lt;
char file_name[1024];
bool update_bucket = false;
gettimeofday(&tv, NULL);
current_sec = (TimestampTz) tv.tv_sec - ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
current_bucket_sec = pg_atomic_read_u64(&pgss->prev_bucket_sec);
/*
@ -2172,28 +2170,27 @@ get_next_wbucket(pgssSharedState *pgss)
* definitely make the while condition to fail, we can stop the loop as
* another thread has already updated prev_bucket_sec.
*/
if ((current_sec - current_bucket_sec) < (uint64)PGSM_BUCKET_TIME)
while ((tv.tv_sec - (uint)current_bucket_sec) >= ((uint)PGSM_BUCKET_TIME))
{
return pg_atomic_read_u64(&pgss->current_wbucket);
if (pg_atomic_compare_exchange_u64(&pgss->prev_bucket_sec, &current_bucket_sec, (uint64)tv.tv_sec))
{
update_bucket = true;
break;
}
current_bucket_sec = pg_atomic_read_u64(&pgss->prev_bucket_sec);
}
if (update_bucket)
{
char file_name[1024];
new_bucket_id = (tv.tv_sec / PGSM_BUCKET_TIME) % PGSM_MAX_BUCKETS;
/* Update bucket id and retrieve the previous one. */
prev_bucket_id = pg_atomic_exchange_u64(&pgss->current_wbucket, new_bucket_id);
tv.tv_sec = (tv.tv_sec) - (tv.tv_sec % PGSM_BUCKET_TIME);
lt = localtime(&tv.tv_sec);
LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
/* Reconfirm that no other backend has created the bucket while we waited */
if (new_bucket_id == prev_bucket_id)
{
LWLockRelease(pgss->lock);
return new_bucket_id;
}
hash_entry_dealloc(new_bucket_id, prev_bucket_id, pgss_qbuf);
if (pgss->overflow)
@ -2202,9 +2199,9 @@ get_next_wbucket(pgssSharedState *pgss)
if (pgss->n_bucket_cycles >= PGSM_MAX_BUCKETS)
{
/*
* A full rotation of PGSM_MAX_BUCKETS buckets happened since we
* detected a query buffer overflow. Reset overflow state and
* remove the dump file.
* A full rotation of PGSM_MAX_BUCKETS buckets happened since
* we detected a query buffer overflow.
* Reset overflow state and remove the dump file.
*/
pgss->overflow = false;
pgss->n_bucket_cycles = 0;
@ -2213,14 +2210,23 @@ get_next_wbucket(pgssSharedState *pgss)
}
}
LWLockRelease(pgss->lock);
tv.tv_sec = (tv.tv_sec) - (tv.tv_sec % PGSM_BUCKET_TIME);
lt = localtime(&tv.tv_sec);
/* Allign the value in prev_bucket_sec to the bucket start time */
pg_atomic_exchange_u64(&pgss->prev_bucket_sec, (uint64)tv.tv_sec);
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);
LWLockRelease(pgss->lock);
return new_bucket_id;
}
return pg_atomic_read_u64(&pgss->current_wbucket);
}
#if PG_VERSION_NUM < 140000
/*
* AppendJumble: Append a value that is substantive in a given query to

View File

@ -2,7 +2,7 @@ CREATE EXTENSION pg_stat_monitor;
SELECT pg_stat_monitor_version();
pg_stat_monitor_version
-------------------------
1.1.0-dev
1.1.0
(1 row)
DROP EXTENSION pg_stat_monitor;