Merge pull request #184 from EngineeredVirus/REL1_0_STABLE
Cherry picking changes from the master branch for REL1_0_STABLE branchpull/189/head
commit
cb5aab89b3
|
@ -6,7 +6,7 @@ We're glad that you would like to become a Percona community member and particip
|
|||
|
||||
You can contribute in one of the following ways:
|
||||
|
||||
1. Reach us on our [Forums](https://forums.percona.com/) and Discord.
|
||||
1. Reach us on our [Forums](https://forums.percona.com/c/postgresql/pg-stat-monitor/69).
|
||||
2. [Submit a bug report or a feature request](#submit-a-bug-report-or-a-feature-request)
|
||||
3. [Submit a pull request (PR) with the code patch](#submit-a-pull-request)
|
||||
4. [Contribute to documentation](#contributing-to-documentation)
|
||||
|
|
30
Makefile
30
Makefile
|
@ -11,7 +11,7 @@ PGFILEDESC = "pg_stat_monitor - execution statistics of SQL statements"
|
|||
LDFLAGS_SL += $(filter -lm, $(LIBS))
|
||||
|
||||
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf --inputdir=regression
|
||||
REGRESS = basic version guc counters relations database top_query application_name cmd_type error state rows tags
|
||||
REGRESS = basic version guc counters relations database error_insert application_name application_name_unique top_query cmd_type error rows tags histogram
|
||||
|
||||
# Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
|
||||
# which typical installcheck users do not have (e.g. buildfarm clients).
|
||||
|
@ -23,19 +23,39 @@ PG_VERSION := $(shell pg_config --version | awk {'print $$1 $$2'})
|
|||
MAJOR := $(shell echo $(PG_VERSION) | sed -e 's/\.[^./]*$$//')
|
||||
|
||||
ifneq (,$(findstring PostgreSQL14,$(MAJOR)))
|
||||
CP := $(shell cp pg_stat_monitor--1.0.14.sql.in pg_stat_monitor--1.0.sql)
|
||||
ifneq (,$(wildcard ../pg_stat_monitor--1.0.14.sql.in))
|
||||
CP := $(shell cp ../pg_stat_monitor--1.0.14.sql.in ../pg_stat_monitor--1.0.sql)
|
||||
endif
|
||||
ifneq (,$(wildcard pg_stat_monitor--1.0.14.sql.in))
|
||||
CP := $(shell cp pg_stat_monitor--1.0.14.sql.in pg_stat_monitor--1.0.sql)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring PostgreSQL13,$(MAJOR)))
|
||||
CP := $(shell cp pg_stat_monitor--1.0.13.sql.in pg_stat_monitor--1.0.sql)
|
||||
ifneq (,$(wildcard ../pg_stat_monitor--1.0.13.sql.in))
|
||||
CP := $(shell cp ../pg_stat_monitor--1.0.13.sql.in ../pg_stat_monitor--1.0.sql)
|
||||
endif
|
||||
ifneq (,$(wildcard pg_stat_monitor--1.0.13.sql.in))
|
||||
CP := $(shell cp pg_stat_monitor--1.0.13.sql.in pg_stat_monitor--1.0.sql)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring PostgreSQL12,$(MAJOR)))
|
||||
CP := $(shell cp pg_stat_monitor--1.0.sql.in pg_stat_monitor--1.0.sql)
|
||||
ifneq (,$(wildcard ../pg_stat_monitor--1.0.sql.in))
|
||||
CP := $(shell cp ../pg_stat_monitor--1.0.sql.in ../pg_stat_monitor--1.0.sql)
|
||||
endif
|
||||
ifneq (,$(wildcard pg_stat_monitor--1.0.sql.in))
|
||||
CP := $(shell cp pg_stat_monitor--1.0.sql.in pg_stat_monitor--1.0.sql)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring PostgreSQL11,$(MAJOR)))
|
||||
CP := $(shell cp pg_stat_monitor--1.0.sql.in pg_stat_monitor--1.0.sql)
|
||||
ifneq (,$(wildcard ../pg_stat_monitor--1.0.sql.in))
|
||||
CP := $(shell cp ../pg_stat_monitor--1.0.sql.in ../pg_stat_monitor--1.0.sql)
|
||||
endif
|
||||
ifneq (,$(wildcard pg_stat_monitor--1.0.sql.in))
|
||||
CP := $(shell cp pg_stat_monitor--1.0.sql.in pg_stat_monitor--1.0.sql)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_PGXS
|
||||
|
|
109
README.md
109
README.md
|
@ -10,25 +10,32 @@
|
|||
|
||||
## Table of Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
* [Supported versions](#supported-versions)
|
||||
* [Features](#features)
|
||||
* [Documentation](#documentation)
|
||||
* [Supported platforms](#supported-platforms)
|
||||
* [Installation guidelines](#installation-guidelines)
|
||||
* [Configuration](#configuration)
|
||||
* [Setup](#setup)
|
||||
* [Building from source code](#building-from-source)
|
||||
* [How to contribute](#how-to-contribute)
|
||||
* [Support, discussions and forums](#support-discussions-and-forums)
|
||||
* [License](#license)
|
||||
* [Copyright notice](#copyright-notice)
|
||||
- [pg_stat_monitor: Query Performance Monitoring Tool for PostgreSQL](#pg_stat_monitor-query-performance-monitoring-tool-for-postgresql)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Overview](#overview)
|
||||
- [Supported versions](#supported-versions)
|
||||
- [Features](#features)
|
||||
- [Documentation](#documentation)
|
||||
- [Supported platforms](#supported-platforms)
|
||||
- [Installation guidelines](#installation-guidelines)
|
||||
- [Installing from Percona repositories](#installing-from-percona-repositories)
|
||||
- [Installing from PostgreSQL `yum` repositories](#installing-from-postgresql-yum-repositories)
|
||||
- [Installing from PGXN](#installing-from-pgxn)
|
||||
- [Configuration](#configuration)
|
||||
- [Setup](#setup)
|
||||
- [Building from source](#building-from-source)
|
||||
- [Uninstall `pg_stat_monitor`](#uninstall-pg_stat_monitor)
|
||||
- [How to contribute](#how-to-contribute)
|
||||
- [Report a bug](#report-a-bug)
|
||||
- [Support, discussions and forums](#support-discussions-and-forums)
|
||||
- [License](#license)
|
||||
- [Copyright notice](#copyright-notice)
|
||||
|
||||
## Overview
|
||||
|
||||
**NOTE**: This is a beta release and is subject to further changes. We recommend using it in testing environments only.
|
||||
|
||||
The `pg_stat_monitor` is a **_Query Performance Monitoring_** tool for PostgreSQL. It attempts to provide a more holistic picture by providing much-needed query performance insights in a single view.
|
||||
The `pg_stat_monitor` is a **_Query Performance Monitoring_** tool for PostgreSQL. It attempts to provide a more holistic picture by providing much-needed query performance insights in a [single view](https://github.com/percona/pg_stat_monitor/blob/master/docs/REFERENCE.md).
|
||||
|
||||
`pg_stat_monitor` provides improved insights that allow database users to understand query origins, execution, planning statistics and details, query information, and metadata. This significantly improves observability, enabling users to debug and tune query performance. `pg_stat_monitor` is developed on the basis of `pg_stat_statements` as its more advanced replacement.
|
||||
|
||||
|
@ -38,7 +45,7 @@ To learn about other features, available in `pg_stat_monitor`, see the [Features
|
|||
|
||||
`pg_stat_monitor` supports PostgreSQL versions 11 and above. It is compatible with both PostgreSQL provided by PostgreSQL Global Development Group (PGDG) and [Percona Distribution for PostgreSQL](https://www.percona.com/software/postgresql-distribution).
|
||||
|
||||
The RPM (for RHEL and CentOS) and the DEB (for Debian and Ubuntu) packages are available from Percona repositories for PostgreSQL versions [11](https://www.percona.com/downloads/percona-postgresql-11/LATEST/), [12](https://www.percona.com/downloads/postgresql-distribution-12/LATEST/), and [13](https://www.percona.com/downloads/postgresql-distribution-13/LATEST/).
|
||||
The `RPM` (for RHEL and CentOS) and the `DEB` (for Debian and Ubuntu) packages are available from Percona repositories for PostgreSQL versions [11](https://www.percona.com/downloads/percona-postgresql-11/LATEST/), [12](https://www.percona.com/downloads/postgresql-distribution-12/LATEST/), and [13](https://www.percona.com/downloads/postgresql-distribution-13/LATEST/).
|
||||
|
||||
The RPM packages are also available in the official PostgreSQL (PGDG) yum repositories.
|
||||
|
||||
|
@ -48,8 +55,8 @@ The `pg_stat_monitor` should work on the latest version of both [Percona Distrib
|
|||
|
||||
| **Distribution** | **Version** | **Provider** |
|
||||
| ---------------- | --------------- | ------------ |
|
||||
|[Percona Distribution for PostgreSQL](https://www.percona.com/software/postgresql-distribution)| [11](https://www.percona.com/downloads/percona-postgresql-11/LATEST/), [12](https://www.percona.com/downloads/postgresql-distribution-12/LATEST/) and [13](https://www.percona.com/downloads/postgresql-distribution-13/LATEST/)| Percona|
|
||||
| PostgreSQL | 11, 12, and 13 | PostgreSQL Global Development Group (PGDG) |
|
||||
|[Percona Distribution for PostgreSQL](https://www.percona.com/software/postgresql-distribution)| [11](https://www.percona.com/downloads/percona-postgresql-11/LATEST/), [12](https://www.percona.com/downloads/postgresql-distribution-12/LATEST/), [13](https://www.percona.com/downloads/postgresql-distribution-13/LATEST/) and [14](https://www.percona.com/downloads/postgresql-distribution-14/LATEST/)| Percona|
|
||||
| PostgreSQL | 11, 12, 13 and 14 | PostgreSQL Global Development Group (PGDG) |
|
||||
|
||||
|
||||
### Features
|
||||
|
@ -68,10 +75,10 @@ The `pg_stat_monitor` should work on the latest version of both [Percona Distrib
|
|||
### Documentation
|
||||
|
||||
1. [User guide](https://github.com/percona/pg_stat_monitor/blob/master/docs/USER_GUIDE.md)
|
||||
2. pg_stat_monitor vs pg_stat_statements
|
||||
3. pg_stat_monitor view reference
|
||||
2. [Comparing `pg_stat_monitor` and `pg_stat_statements`](https://github.com/percona/pg_stat_monitor/blob/master/docs/COMPARISON.md)
|
||||
3. [pg_stat_monitor view reference](https://github.com/percona/pg_stat_monitor/blob/master/docs/REFERENCE.md)
|
||||
4. [Release notes](https://github.com/percona/pg_stat_monitor/blob/master/docs/RELEASE_NOTES.md)
|
||||
5. Contributing guide (https://github.com/percona/pg_stat_monitor/blob/master/CONTRIBUTING.md)
|
||||
5. [Contributing guide](https://github.com/percona/pg_stat_monitor/blob/master/CONTRIBUTING.md)
|
||||
|
||||
|
||||
### Supported platforms
|
||||
|
@ -84,7 +91,7 @@ The PostgreSQL YUM repository supports `pg_stat_monitor` for all [supported vers
|
|||
Find the list of supported platforms for `pg_stat_monitor` within [Percona Distribution for PostgreSQL](https://www.percona.com/software/postgresql-distribution) on the [Percona Release Lifecycle Overview](https://www.percona.com/services/policies/percona-software-support-lifecycle#pgsql) page.
|
||||
|
||||
|
||||
### Installation Guidelines
|
||||
### Installation guidelines
|
||||
|
||||
You can install `pg_stat_monitor` from the following sources:
|
||||
|
||||
|
@ -117,7 +124,7 @@ Replace XX with the desired PostgreSQL version. For example, to install `pg_stat
|
|||
yum install percona-pg-stat-monitor13
|
||||
```
|
||||
|
||||
#### Installing from PostgreSQL yum repositories
|
||||
#### Installing from PostgreSQL `yum` repositories
|
||||
|
||||
Install the PostgreSQL repositories following the instructions in the [Linux downloads (Red Hat family)](https://www.postgresql.org/download/linux/redhat/) chapter in PostgreSQL documentation.
|
||||
|
||||
|
@ -153,10 +160,8 @@ You can enable `pg_stat_monitor` when your `postgresql` instance is not running.
|
|||
|
||||
Use the [ALTER SYSTEM](https://www.postgresql.org/docs/current/sql-altersystem.html)command from `psql` terminal to modify the `shared_preload_libraries` parameter.
|
||||
|
||||
```
|
||||
```sql
|
||||
ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_monitor';
|
||||
|
||||
ALTER SYSTEM
|
||||
```
|
||||
|
||||
> **NOTE**: If you’ve added other modules to the `shared_preload_libraries` parameter (for example, `pg_stat_statements`), list all of them separated by commas for the `ALTER SYSTEM` command.
|
||||
|
@ -169,23 +174,22 @@ Start or restart the `postgresql` instance to apply the changes.
|
|||
|
||||
* On Debian and Ubuntu:
|
||||
|
||||
```
|
||||
```sh
|
||||
sudo systemctl restart postgresql.service
|
||||
```
|
||||
|
||||
* On Red Hat Enterprise Linux and CentOS:
|
||||
|
||||
|
||||
```
|
||||
```sh
|
||||
sudo systemctl restart postgresql-13
|
||||
```
|
||||
|
||||
Create the extension using the [CREATE EXTENSION](https://www.postgresql.org/docs/current/sql-createextension.html) command. Using this command requires the privileges of a superuser or a database owner. Connect to `psql` as a superuser for a database and run the following command:
|
||||
|
||||
|
||||
```
|
||||
```sql
|
||||
CREATE EXTENSION pg_stat_monitor;
|
||||
CREATE EXTENSION
|
||||
```
|
||||
|
||||
|
||||
|
@ -235,16 +239,61 @@ make USE_PGXS=1
|
|||
make USE_PGXS=1 install
|
||||
```
|
||||
|
||||
### Uninstall `pg_stat_monitor`
|
||||
|
||||
To uninstall `pg_stat_monitor`, do the following:
|
||||
|
||||
1. Disable statistics collection. From the `psql` terminal, run the following command:
|
||||
|
||||
```sql
|
||||
ALTER SYSTEM SET pg_stat_monitor.pgsm_enable = 0;
|
||||
```
|
||||
|
||||
2. Drop `pg_stat_monitor` extension:
|
||||
|
||||
```sql
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
```
|
||||
|
||||
3. Remove `pg_stat_monitor` from the `shared_preload_libraries` configuration parameter:
|
||||
|
||||
```sql
|
||||
ALTER SYSTEM SET shared_preload_libraries = '';
|
||||
```
|
||||
|
||||
**Important**: If the `shared_preload_libraries` parameter includes other modules, specify them all for the `ALTER SYSTEM SET` command to keep using them.
|
||||
|
||||
4. Restart the `postgresql` instance to apply the changes. The following command restarts PostgreSQL 13. Replace the version value with the one you are using.
|
||||
|
||||
* On Debian and Ubuntu:
|
||||
|
||||
```sh
|
||||
sudo systemctl restart postgresql.service
|
||||
```
|
||||
|
||||
* On Red Hat Enterprise Linux and CentOS:
|
||||
|
||||
|
||||
```sh
|
||||
sudo systemctl restart postgresql-13
|
||||
```
|
||||
|
||||
### How to contribute
|
||||
|
||||
We welcome and strongly encourage community participation and contributions, and are always looking for new members that are as dedicated to serving the community as we are.
|
||||
|
||||
The [Contributing Guide](https://github.com/percona/pg_stat_monitor/blob/master/CONTRIBUTING.md) contains the guidelines on how you can contribute.
|
||||
|
||||
### Report a bug
|
||||
|
||||
If you would like to suggest a new feature / an improvement or you found a bug in `pg_stat_monitor`, please submit the report to the [Percona Jira issue tracker](https://jira.percona.com/projects/PG).
|
||||
|
||||
Refer to the [Submit a bug report or a feature request](https://github.com/percona/pg_stat_monitor/blob/master/CONTRIBUTING.md#submit-a-bug-report-or-a-feature-request) section for bug reporting guidelines.
|
||||
|
||||
|
||||
### Support, discussions and forums
|
||||
|
||||
We welcome your feedback on your experience with `pg_stat_monitor`. Join our [technical forum](https://forums.percona.com/) or [Discord](https://discord.gg/mQEyGPkNbR) channel for help with `pg_stat_monitor` and Percona's open source software for MySQL®, [PostgreSQL](https://www.percona.com/software/postgresql-distribution), and MongoDB® databases.
|
||||
We welcome your feedback on your experience with `pg_stat_monitor`. Join our [technical forum](https://forums.percona.com/c/postgresql/pg-stat-monitor/69) for help with `pg_stat_monitor`.
|
||||
|
||||
|
||||
### License
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
Source: percona-pg-stat-monitor
|
||||
Section: database
|
||||
Priority: optional
|
||||
Maintainer: Percona Development Team <info@percona.com>
|
||||
Build-Depends:
|
||||
debhelper (>= 9),
|
||||
postgresql-server-dev-all (>= 153~) | percona-postgresql-server-dev-all (>= 153~),
|
||||
|
||||
Package: percona-pg-stat-monitorPGVERSION
|
||||
Architecture: any
|
||||
Depends:
|
||||
postgresql-PGVERSION,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Description: enhancement query planning and execution statistics collector
|
||||
The pg_stat_monitor is a Query Performance Monitoring tool for PostgreSQL.
|
||||
It attempts to provide a more holistic picture by providing much-needed query
|
||||
performance insights in a single view.
|
||||
.
|
||||
pg_stat_monitor provides improved insights that allow database users to
|
||||
understand query origins, execution, planning statistics and details, query
|
||||
information, and metadata. This significantly improves observability, enabling
|
||||
users to debug and tune query performance. pg_stat_monitor is developed on the
|
||||
basis of pg_stat_statements as its more advanced replacement.
|
|
@ -0,0 +1,24 @@
|
|||
Source: percona-pg-stat-monitor
|
||||
Section: database
|
||||
Priority: optional
|
||||
Maintainer: Percona Development Team <info@percona.com>
|
||||
Build-Depends:
|
||||
debhelper (>= 9),
|
||||
postgresql-server-dev-all (>= 153~) | percona-postgresql-server-dev-all (>= 153~),
|
||||
|
||||
Package: percona-pg-stat-monitorPGVERSION
|
||||
Architecture: any
|
||||
Depends:
|
||||
postgresql-PGVERSION,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Description: enhancement query planning and execution statistics collector
|
||||
The pg_stat_monitor is a Query Performance Monitoring tool for PostgreSQL.
|
||||
It attempts to provide a more holistic picture by providing much-needed query
|
||||
performance insights in a single view.
|
||||
.
|
||||
pg_stat_monitor provides improved insights that allow database users to
|
||||
understand query origins, execution, planning statistics and details, query
|
||||
information, and metadata. This significantly improves observability, enabling
|
||||
users to debug and tune query performance. pg_stat_monitor is developed on the
|
||||
basis of pg_stat_statements as its more advanced replacement.
|
|
@ -0,0 +1,26 @@
|
|||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: pg_stat_monitor
|
||||
Source: https://github.com/percona/pg_stat_monitor
|
||||
|
||||
Files: *
|
||||
Copyright: Portions Copyright © 2018-2021, Percona LLC and/or its affiliates
|
||||
Portions Copyright © 1996-2021, The PostgreSQL Global Development Group
|
||||
Portions Copyright © 1994, The Regents of the University of California
|
||||
|
||||
License: PostgreSQL
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose, without fee, and without a written agreement
|
||||
is hereby granted, provided that the above copyright notice and this
|
||||
paragraph and the following two paragraphs appear in all copies.
|
||||
.
|
||||
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
|
||||
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
|
||||
LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
|
||||
DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
.
|
||||
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
|
||||
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
129
hash_query.c
129
hash_query.c
|
@ -22,19 +22,8 @@
|
|||
|
||||
static pgssSharedState *pgss;
|
||||
static HTAB *pgss_hash;
|
||||
static HTAB *pgss_query_hash;
|
||||
|
||||
static HTAB* hash_init(const char *hash_name, int key_size, int entry_size, int hash_size);
|
||||
/*
|
||||
* Copy query from src_buffer to dst_buff.
|
||||
* Use query_id and query_pos to fast locate query in source buffer.
|
||||
* Store updated query position in the destination buffer into param query_pos.
|
||||
*/
|
||||
static bool copy_query(uint64 bucket_id,
|
||||
uint64 query_id,
|
||||
uint64 query_pos,
|
||||
unsigned char *dst_buf,
|
||||
unsigned char *src_buf,
|
||||
size_t *new_query_pos);
|
||||
|
||||
static HTAB*
|
||||
hash_init(const char *hash_name, int key_size, int entry_size, int hash_size)
|
||||
|
@ -50,7 +39,6 @@ void
|
|||
pgss_startup(void)
|
||||
{
|
||||
bool found = false;
|
||||
int32 i;
|
||||
|
||||
/* reset in case this is a restart within the postmaster */
|
||||
|
||||
|
@ -75,16 +63,10 @@ pgss_startup(void)
|
|||
init_hook_stats();
|
||||
#endif
|
||||
|
||||
pgss->query_buf_size_bucket = MAX_QUERY_BUF / PGSM_MAX_BUCKETS;
|
||||
|
||||
for (i = 0; i < PGSM_MAX_BUCKETS; i++)
|
||||
{
|
||||
unsigned char *buf = (unsigned char *)ShmemAlloc(pgss->query_buf_size_bucket);
|
||||
set_qbuf(i, buf);
|
||||
memset(buf, 0, sizeof (uint64));
|
||||
}
|
||||
set_qbuf((unsigned char *)ShmemAlloc(MAX_QUERY_BUF));
|
||||
|
||||
pgss_hash = hash_init("pg_stat_monitor: bucket hashtable", sizeof(pgssHashKey), sizeof(pgssEntry), MAX_BUCKET_ENTRIES);
|
||||
pgss_query_hash = hash_init("pg_stat_monitor: queryID hashtable", sizeof(uint64), sizeof(pgssQueryEntry), MAX_BUCKET_ENTRIES);
|
||||
|
||||
LWLockRelease(AddinShmemInitLock);
|
||||
|
||||
|
@ -107,6 +89,12 @@ pgsm_get_hash(void)
|
|||
return pgss_hash;
|
||||
}
|
||||
|
||||
HTAB*
|
||||
pgsm_get_query_hash(void)
|
||||
{
|
||||
return pgss_query_hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* shmem_shutdown hook: Dump statistics into file.
|
||||
*
|
||||
|
@ -152,7 +140,9 @@ hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding)
|
|||
}
|
||||
/* Find or create an entry with desired hash code */
|
||||
entry = (pgssEntry *) hash_search(pgss_hash, key, HASH_ENTER_NULL, &found);
|
||||
if (!found)
|
||||
if (entry == NULL)
|
||||
pgsm_log_error("hash_entry_alloc: OUT OF MEMORY");
|
||||
else if (!found)
|
||||
{
|
||||
pgss->bucket_entry[pg_atomic_read_u64(&pgss->current_wbucket)]++;
|
||||
/* New entry, initialize it */
|
||||
|
@ -164,8 +154,7 @@ hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding)
|
|||
/* ... and don't forget the query text metadata */
|
||||
entry->encoding = encoding;
|
||||
}
|
||||
if (entry == NULL)
|
||||
elog(DEBUG1, "%s", "pg_stat_monitor: out of memory");
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
@ -182,22 +171,15 @@ hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding)
|
|||
* Caller must hold an exclusive lock on pgss->lock.
|
||||
*/
|
||||
void
|
||||
hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer[])
|
||||
hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer)
|
||||
{
|
||||
HASH_SEQ_STATUS hash_seq;
|
||||
pgssEntry *entry = NULL;
|
||||
pgssSharedState *pgss = pgsm_get_ss();
|
||||
|
||||
/* Store pending query ids from the previous bucket. */
|
||||
List *pending_entries = NIL;
|
||||
ListCell *pending_entry;
|
||||
|
||||
if (new_bucket_id != -1)
|
||||
{
|
||||
/* Clear all queries in the query buffer for the new bucket. */
|
||||
memset(query_buffer[new_bucket_id], 0, pgss->query_buf_size_bucket);
|
||||
}
|
||||
|
||||
/* Iterate over the hash table. */
|
||||
hash_seq_init(&hash_seq, pgss_hash);
|
||||
while ((entry = hash_seq_search(&hash_seq)) != NULL)
|
||||
|
@ -210,6 +192,11 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
|
|||
(entry->key.bucket_id == new_bucket_id &&
|
||||
(entry->counters.state == PGSS_FINISHED || entry->counters.state == PGSS_ERROR)))
|
||||
{
|
||||
if (new_bucket_id == -1) {
|
||||
/* pg_stat_monitor_reset(), remove entry from query hash table too. */
|
||||
hash_search(pgss_query_hash, &(entry->key.queryid), HASH_REMOVE, NULL);
|
||||
}
|
||||
|
||||
entry = hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL);
|
||||
}
|
||||
|
||||
|
@ -229,9 +216,21 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
|
|||
pgssEntry *bkp_entry = malloc(sizeof(pgssEntry));
|
||||
if (!bkp_entry)
|
||||
{
|
||||
/* No memory, remove pending query entry from the previous bucket. */
|
||||
elog(ERROR, "hash_entry_dealloc: out of memory");
|
||||
entry = hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL);
|
||||
pgsm_log_error("hash_entry_dealloc: out of memory");
|
||||
/*
|
||||
* No memory, If the entry has calls > 1 then we change the state to finished,
|
||||
* as the pending query will likely finish execution during the new bucket
|
||||
* time window. The pending query will vanish in this case, can't list it
|
||||
* until it completes.
|
||||
*
|
||||
* If there is only one call to the query and it's pending, remove the
|
||||
* entry from the previous bucket and allow it to finish in the new bucket,
|
||||
* in order to avoid the query living in the old bucket forever.
|
||||
*/
|
||||
if (entry->counters.calls.calls > 1)
|
||||
entry->counters.state = PGSS_FINISHED;
|
||||
else
|
||||
entry = hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -244,8 +243,20 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
|
|||
/* Add the entry to a list of nodes to be processed later. */
|
||||
pending_entries = lappend(pending_entries, bkp_entry);
|
||||
|
||||
/* Finally remove the pending query from the expired bucket id. */
|
||||
entry = hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL);
|
||||
/*
|
||||
* If the entry has calls > 1 then we change the state to finished in
|
||||
* the previous bucket, as the pending query will likely finish execution
|
||||
* during the new bucket time window. Can't remove it from the previous bucket
|
||||
* as it may have many calls and we would lose the query statistics.
|
||||
*
|
||||
* If there is only one call to the query and it's pending, remove the entry
|
||||
* from the previous bucket and allow it to finish in the new bucket,
|
||||
* in order to avoid the query living in the old bucket forever.
|
||||
*/
|
||||
if (entry->counters.calls.calls > 1)
|
||||
entry->counters.state = PGSS_FINISHED;
|
||||
else
|
||||
entry = hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,13 +279,7 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
|
|||
new_entry->counters = old_entry->counters;
|
||||
SpinLockInit(&new_entry->mutex);
|
||||
new_entry->encoding = old_entry->encoding;
|
||||
/* copy query's text from previous bucket to the new one. */
|
||||
copy_query(new_bucket_id,
|
||||
new_entry->key.queryid, /* query id */
|
||||
old_entry->query_pos, /* query position in buffer */
|
||||
query_buffer[new_bucket_id], /* destination query buffer */
|
||||
query_buffer[old_bucket_id], /* source query buffer */
|
||||
&new_entry->query_pos); /* position in which query was inserted into destination buffer */
|
||||
new_entry->query_pos = old_entry->query_pos;
|
||||
}
|
||||
|
||||
free(old_entry);
|
||||
|
@ -310,39 +315,3 @@ IsHashInitialize(void)
|
|||
return (pgss != NULL &&
|
||||
pgss_hash != NULL);
|
||||
}
|
||||
|
||||
static bool copy_query(uint64 bucket_id,
|
||||
uint64 query_id,
|
||||
uint64 query_pos,
|
||||
unsigned char *dst_buf,
|
||||
unsigned char *src_buf,
|
||||
size_t *new_query_pos)
|
||||
{
|
||||
uint64 query_len = 0;
|
||||
uint64 buf_len = 0;
|
||||
|
||||
memcpy(&buf_len, src_buf, sizeof (uint64));
|
||||
if (buf_len <= 0)
|
||||
return false;
|
||||
|
||||
/* Try to locate the query directly. */
|
||||
if (query_pos != 0 && (query_pos + sizeof(uint64) + sizeof(uint64)) < buf_len)
|
||||
{
|
||||
if (*(uint64 *)&src_buf[query_pos] != query_id)
|
||||
return false;
|
||||
|
||||
query_pos += sizeof(uint64);
|
||||
|
||||
memcpy(&query_len, &src_buf[query_pos], sizeof(uint64)); /* query len */
|
||||
query_pos += sizeof(uint64);
|
||||
|
||||
if (query_pos + query_len > buf_len) /* avoid reading past buffer's length. */
|
||||
return false;
|
||||
|
||||
return SaveQueryText(bucket_id, query_id, dst_buf,
|
||||
(const char *)&src_buf[query_pos],
|
||||
query_len, new_query_pos);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
Source: percona-pg-stat-monitor
|
||||
Section: database
|
||||
Priority: optional
|
||||
Maintainer: Percona Development Team <info@percona.com>
|
||||
Build-Depends:
|
||||
debhelper (>= 9),
|
||||
percona-postgresql-server-dev-all (>= 153~),
|
||||
|
||||
Package: percona-pg-stat-monitor@@PG_REL@@
|
||||
Architecture: any
|
||||
Depends:
|
||||
percona-postgresql-@@PG_REL@@ | postgresql-@@PG_REL@@,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Description: The pg_stat_monitor is statistics collector tool
|
||||
based on PostgreSQL's contrib module "pg_stat_statements".
|
||||
.
|
||||
pg_stat_monitor is developed on the basis of pg_stat_statments
|
||||
as more advanced replacement for pg_stat_statment.
|
||||
It provides all the features of pg_stat_statment plus its own feature set.
|
|
@ -1,20 +0,0 @@
|
|||
Source: percona-pg-stat-monitor
|
||||
Section: database
|
||||
Priority: optional
|
||||
Maintainer: Percona Development Team <info@percona.com>
|
||||
Build-Depends:
|
||||
debhelper (>= 9),
|
||||
percona-postgresql-server-dev-all (>= 153~),
|
||||
|
||||
Package: percona-pg-stat-monitor@@PG_REL@@
|
||||
Architecture: any
|
||||
Depends:
|
||||
percona-postgresql-@@PG_REL@@ | postgresql-@@PG_REL@@,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends},
|
||||
Description: The pg_stat_monitor is statistics collector tool
|
||||
based on PostgreSQL's contrib module "pg_stat_statements".
|
||||
.
|
||||
pg_stat_monitor is developed on the basis of pg_stat_statments
|
||||
as more advanced replacement for pg_stat_statment.
|
||||
It provides all the features of pg_stat_statment plus its own feature set.
|
|
@ -1,27 +0,0 @@
|
|||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: PostgreSQL
|
||||
Source: https://github.com/percona/pg_stat_monitor
|
||||
|
||||
pg_stat_monitor - Statistics collector for PostgreSQL.
|
||||
|
||||
Portions Copyright © 2018-2020, Percona LLC and/or its affiliates
|
||||
|
||||
Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
||||
|
||||
Portions Copyright (c) 1994, The Regents of the University of California
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose, without fee, and without a written agreement is
|
||||
hereby granted, provided that the above copyright notice and this paragraph and
|
||||
the following two paragraphs appear in all copies.
|
||||
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR DIRECT,
|
||||
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
|
||||
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
|
||||
COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
|
||||
THE COPYRIGHT HOLDER HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
|
||||
UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
|
@ -128,9 +128,6 @@ get_sources(){
|
|||
fi
|
||||
REVISION=$(git rev-parse --short HEAD)
|
||||
echo "REVISION=${REVISION}" >> ${WORKDIR}/pg-stat-monitor.properties
|
||||
rm -rf rpm debian
|
||||
cp -r percona-packaging/rpm ./
|
||||
cp -r percona-packaging/debian ./
|
||||
|
||||
EDITFILES="debian/control debian/control.in debian/rules rpm/pg-stat-monitor.spec"
|
||||
for file in $EDITFILES; do
|
||||
|
@ -193,9 +190,10 @@ install_deps() {
|
|||
percona-release enable ppg-12 release
|
||||
fi
|
||||
yum -y install git wget
|
||||
PKGLIST="percona-postgresql-common percona-postgresql${PG_RELEASE}-devel"
|
||||
PKGLIST+=" clang-devel git clang llvm-devel rpmdevtools vim wget"
|
||||
PKGLIST+=" perl binutils gcc gcc-c++"
|
||||
PKGLIST+=" percona-postgresql-common clang-devel llvm-devel percona-postgresql${PG_RELEASE}-devel git rpm-build rpmdevtools wget gcc make autoconf"
|
||||
PKGLIST+=" clang-devel llvm-devel git rpm-build rpmdevtools wget gcc make autoconf"
|
||||
if [[ "${RHEL}" -eq 8 ]]; then
|
||||
dnf -y module disable postgresql
|
||||
elif [[ "${RHEL}" -eq 7 ]]; then
|
||||
|
@ -225,6 +223,15 @@ install_deps() {
|
|||
elif [[ "${PG_RELEASE}" == "12" ]]; then
|
||||
percona-release enable ppg-12 release
|
||||
fi
|
||||
|
||||
|
||||
PKGLIST="percona-postgresql-${PG_RELEASE} percona-postgresql-common percona-postgresql-server-dev-all"
|
||||
|
||||
# ---- using a community version of postgresql
|
||||
#wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
|
||||
#echo "deb http://apt.postgresql.org/pub/repos/apt/ ${PG_RELEASE}"-pgdg main | sudo tee /etc/apt/sources.list.d/pgdg.list
|
||||
#PKGLIST="postgresql-${PG_RELEASE} postgresql-common postgresql-server-dev-all"
|
||||
|
||||
apt-get update
|
||||
|
||||
if [[ "${OS_NAME}" != "focal" ]]; then
|
||||
|
@ -237,8 +244,9 @@ install_deps() {
|
|||
fi
|
||||
fi
|
||||
|
||||
PKGLIST+=" percona-postgresql-${PG_RELEASE} debconf debhelper clang-7 devscripts dh-exec dh-systemd git wget libkrb5-dev libssl-dev percona-postgresql-common percona-postgresql-server-dev-all"
|
||||
PKGLIST+=" build-essential debconf debhelper devscripts dh-exec dh-systemd git wget libxml-checker-perl libxml-libxml-perl libio-socket-ssl-perl libperl-dev libssl-dev libxml2-dev txt2man zlib1g-dev libpq-dev"
|
||||
PKGLIST+=" debconf debhelper clang-7 devscripts dh-exec dh-systemd git wget libkrb5-dev libssl-dev"
|
||||
PKGLIST+=" build-essential debconf debhelper devscripts dh-exec dh-systemd git wget libxml-checker-perl"
|
||||
PKGLIST+=" libxml-libxml-perl libio-socket-ssl-perl libperl-dev libssl-dev libxml2-dev txt2man zlib1g-dev libpq-dev"
|
||||
|
||||
until DEBIAN_FRONTEND=noninteractive apt-get -y install ${PKGLIST}; do
|
||||
sleep 1
|
||||
|
@ -402,6 +410,7 @@ build_source_deb(){
|
|||
cd ${BUILDDIR}
|
||||
|
||||
dch -D unstable --force-distribution -v "${VERSION}-${DEB_RELEASE}" "Update to new percona-pg-stat-monitor${PG_RELEASE} version ${VERSION}"
|
||||
pg_buildext updatecontrol
|
||||
dpkg-buildpackage -S
|
||||
cd ../
|
||||
mkdir -p $WORKDIR/source_deb
|
||||
|
@ -444,6 +453,7 @@ build_deb(){
|
|||
dpkg-source -x ${DSC}
|
||||
#
|
||||
cd percona-pg-stat-monitor-${VERSION}
|
||||
sed -i "s:\. :${WORKDIR}/percona-pg-stat-monitor-${VERSION} :g" debian/rules
|
||||
dch -m -D "${OS_NAME}" --force-distribution -v "1:${VERSION}-${DEB_RELEASE}.${OS_NAME}" 'Update distribution'
|
||||
unset $(locale|cut -d= -f1)
|
||||
dpkg-buildpackage -rfakeroot -us -uc -b
|
||||
|
|
|
@ -119,12 +119,13 @@ LANGUAGE SQL PARALLEL SAFE;
|
|||
|
||||
CREATE FUNCTION pg_stat_monitor_settings(
|
||||
OUT name text,
|
||||
OUT value INTEGER,
|
||||
OUT default_value INTEGER,
|
||||
OUT value text,
|
||||
OUT default_value text,
|
||||
OUT description text,
|
||||
OUT minimum INTEGER,
|
||||
OUT maximum INTEGER,
|
||||
OUT restart INTEGER
|
||||
OUT options text,
|
||||
OUT restart text
|
||||
)
|
||||
RETURNS SETOF record
|
||||
AS 'MODULE_PATHNAME', 'pg_stat_monitor_settings'
|
||||
|
@ -137,6 +138,7 @@ CREATE VIEW pg_stat_monitor_settings AS SELECT
|
|||
description,
|
||||
minimum,
|
||||
maximum,
|
||||
options,
|
||||
restart
|
||||
FROM pg_stat_monitor_settings();
|
||||
|
||||
|
@ -255,9 +257,42 @@ $$ language plpgsql;
|
|||
-- total_time / greatest(ncalls, 1) as avg_time,
|
||||
-- ncalls,
|
||||
-- ROUND(CAST(total_time / greatest(sum(total_time) OVER(), 0.00000001) * 100 as numeric), 2)::text || '%' as load_comparison
|
||||
--FROM pg_stat_monitor_hook_stats();
|
||||
-- FROM pg_stat_monitor_hook_stats();
|
||||
|
||||
CREATE FUNCTION pg_stat_monitor_errors(
|
||||
OUT severity int,
|
||||
OUT message text,
|
||||
OUT msgtime text,
|
||||
OUT calls int8
|
||||
)
|
||||
RETURNS SETOF record
|
||||
AS 'MODULE_PATHNAME', 'pg_stat_monitor_errors'
|
||||
LANGUAGE C STRICT VOLATILE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION pgsm_log_severity_as_text(severity int) RETURNS TEXT AS
|
||||
$$
|
||||
SELECT
|
||||
CASE
|
||||
WHEN severity = 0 THEN 'INFO'
|
||||
WHEN severity = 1 THEN 'WARNING'
|
||||
WHEN severity = 2 THEN 'ERROR'
|
||||
END
|
||||
$$
|
||||
LANGUAGE SQL PARALLEL SAFE;
|
||||
|
||||
CREATE VIEW pg_stat_monitor_errors AS SELECT
|
||||
pgsm_log_severity_as_text(severity) as severity, message, msgtime, calls
|
||||
FROM pg_stat_monitor_errors();
|
||||
|
||||
CREATE FUNCTION pg_stat_monitor_reset_errors()
|
||||
RETURNS void
|
||||
AS 'MODULE_PATHNAME'
|
||||
LANGUAGE C PARALLEL SAFE;
|
||||
|
||||
GRANT SELECT ON pg_stat_monitor TO PUBLIC;
|
||||
GRANT SELECT ON pg_stat_monitor_settings TO PUBLIC;
|
||||
|
||||
GRANT SELECT ON pg_stat_monitor_errors TO PUBLIC;
|
||||
-- Don't want this to be available to non-superusers.
|
||||
REVOKE ALL ON FUNCTION pg_stat_monitor_reset() FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pg_stat_monitor_reset_errors() FROM PUBLIC;
|
||||
|
|
|
@ -119,12 +119,13 @@ LANGUAGE SQL PARALLEL SAFE;
|
|||
|
||||
CREATE FUNCTION pg_stat_monitor_settings(
|
||||
OUT name text,
|
||||
OUT value INTEGER,
|
||||
OUT default_value INTEGER,
|
||||
OUT value text,
|
||||
OUT default_value text,
|
||||
OUT description text,
|
||||
OUT minimum INTEGER,
|
||||
OUT maximum INTEGER,
|
||||
OUT restart INTEGER
|
||||
OUT options text,
|
||||
OUT restart text
|
||||
)
|
||||
RETURNS SETOF record
|
||||
AS 'MODULE_PATHNAME', 'pg_stat_monitor_settings'
|
||||
|
@ -137,6 +138,7 @@ CREATE VIEW pg_stat_monitor_settings AS SELECT
|
|||
description,
|
||||
minimum,
|
||||
maximum,
|
||||
options,
|
||||
restart
|
||||
FROM pg_stat_monitor_settings();
|
||||
|
||||
|
@ -256,9 +258,42 @@ $$ language plpgsql;
|
|||
-- total_time / greatest(ncalls, 1) as avg_time,
|
||||
-- ncalls,
|
||||
-- ROUND(CAST(total_time / greatest(sum(total_time) OVER(), 0.00000001) * 100 as numeric), 2)::text || '%' as load_comparison
|
||||
--FROM pg_stat_monitor_hook_stats();
|
||||
-- FROM pg_stat_monitor_hook_stats();
|
||||
|
||||
CREATE FUNCTION pg_stat_monitor_errors(
|
||||
OUT severity int,
|
||||
OUT message text,
|
||||
OUT msgtime text,
|
||||
OUT calls int8
|
||||
)
|
||||
RETURNS SETOF record
|
||||
AS 'MODULE_PATHNAME', 'pg_stat_monitor_errors'
|
||||
LANGUAGE C STRICT VOLATILE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION pgsm_log_severity_as_text(severity int) RETURNS TEXT AS
|
||||
$$
|
||||
SELECT
|
||||
CASE
|
||||
WHEN severity = 0 THEN 'INFO'
|
||||
WHEN severity = 1 THEN 'WARNING'
|
||||
WHEN severity = 2 THEN 'ERROR'
|
||||
END
|
||||
$$
|
||||
LANGUAGE SQL PARALLEL SAFE;
|
||||
|
||||
CREATE VIEW pg_stat_monitor_errors AS SELECT
|
||||
pgsm_log_severity_as_text(severity) as severity, message, msgtime, calls
|
||||
FROM pg_stat_monitor_errors();
|
||||
|
||||
CREATE FUNCTION pg_stat_monitor_reset_errors()
|
||||
RETURNS void
|
||||
AS 'MODULE_PATHNAME'
|
||||
LANGUAGE C PARALLEL SAFE;
|
||||
|
||||
GRANT SELECT ON pg_stat_monitor TO PUBLIC;
|
||||
GRANT SELECT ON pg_stat_monitor_settings TO PUBLIC;
|
||||
|
||||
GRANT SELECT ON pg_stat_monitor_errors TO PUBLIC;
|
||||
-- Don't want this to be available to non-superusers.
|
||||
REVOKE ALL ON FUNCTION pg_stat_monitor_reset() FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pg_stat_monitor_reset_errors() FROM PUBLIC;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -87,9 +87,8 @@
|
|||
#define MAX_QUERY_BUF (PGSM_QUERY_SHARED_BUFFER * 1024 * 1024)
|
||||
#define MAX_BUCKETS_MEM (PGSM_MAX * 1024 * 1024)
|
||||
#define BUCKETS_MEM_OVERFLOW() ((hash_get_num_entries(pgss_hash) * sizeof(pgssEntry)) >= MAX_BUCKETS_MEM)
|
||||
#define MAX_QUERY_BUFFER_BUCKET MAX_QUERY_BUF / PGSM_MAX_BUCKETS
|
||||
#define MAX_BUCKET_ENTRIES (MAX_BUCKETS_MEM / sizeof(pgssEntry))
|
||||
#define QUERY_BUFFER_OVERFLOW(x,y) ((x + y + sizeof(uint64) + sizeof(uint64)) > MAX_QUERY_BUFFER_BUCKET)
|
||||
#define QUERY_BUFFER_OVERFLOW(x,y) ((x + y + sizeof(uint64) + sizeof(uint64)) > MAX_QUERY_BUF)
|
||||
#define QUERY_MARGIN 100
|
||||
#define MIN_QUERY_LEN 10
|
||||
#define SQLCODE_LEN 20
|
||||
|
@ -161,7 +160,7 @@ typedef enum AGG_KEY
|
|||
|
||||
#define MAX_QUERY_LEN 1024
|
||||
|
||||
/* shared nenory storage for the query */
|
||||
/* shared memory storage for the query */
|
||||
typedef struct CallTime
|
||||
{
|
||||
double total_time; /* total execution time, in msec */
|
||||
|
@ -171,27 +170,26 @@ typedef struct CallTime
|
|||
double sum_var_time; /* sum of variances in execution time in msec */
|
||||
} CallTime;
|
||||
|
||||
typedef struct pgssQueryHashKey
|
||||
{
|
||||
uint64 bucket_id; /* bucket number */
|
||||
uint64 queryid; /* query identifier */
|
||||
uint64 userid; /* user OID */
|
||||
uint64 dbid; /* database OID */
|
||||
uint64 ip; /* client ip address */
|
||||
uint64 appid; /* hash of application name */
|
||||
} pgssQueryHashKey;
|
||||
|
||||
/*
|
||||
* Entry type for queries hash table (query ID).
|
||||
*
|
||||
* We use a hash table to keep track of query IDs that have their
|
||||
* corresponding query text added to the query buffer (pgsm_query_shared_buffer).
|
||||
*
|
||||
* This allow us to avoid adding duplicated queries to the buffer, therefore
|
||||
* leaving more space for other queries and saving some CPU.
|
||||
*/
|
||||
typedef struct pgssQueryEntry
|
||||
{
|
||||
pgssQueryHashKey key; /* hash key of entry - MUST BE FIRST */
|
||||
uint64 pos; /* bucket number */
|
||||
uint64 state;
|
||||
uint64 queryid; /* query identifier, also the key. */
|
||||
size_t query_pos; /* query location within query buffer */
|
||||
} pgssQueryEntry;
|
||||
|
||||
typedef struct PlanInfo
|
||||
{
|
||||
uint64 planid; /* plan identifier */
|
||||
char plan_text[PLAN_TEXT_LEN]; /* plan text */
|
||||
size_t plan_len; /* strlen(plan_text) */
|
||||
} PlanInfo;
|
||||
|
||||
typedef struct pgssHashKey
|
||||
|
@ -208,10 +206,6 @@ typedef struct pgssHashKey
|
|||
|
||||
typedef struct QueryInfo
|
||||
{
|
||||
uint64 queryid; /* query identifier */
|
||||
Oid userid; /* user OID */
|
||||
Oid dbid; /* database OID */
|
||||
uint host; /* client IP */
|
||||
uint64 parentid; /* parent queryid of current query*/
|
||||
int64 type; /* type of query, options are query, info, warning, error, fatal */
|
||||
char application_name[APPLICATIONNAME_LEN];
|
||||
|
@ -311,8 +305,22 @@ typedef struct pgssSharedState
|
|||
pg_atomic_uint64 current_wbucket;
|
||||
pg_atomic_uint64 prev_bucket_usec;
|
||||
uint64 bucket_entry[MAX_BUCKETS];
|
||||
int64 query_buf_size_bucket;
|
||||
char bucket_start_time[MAX_BUCKETS][60]; /* start time of the bucket */
|
||||
LWLock *errors_lock; /* protects errors hashtable search/modification */
|
||||
/*
|
||||
* These variables are used when pgsm_overflow_target is ON.
|
||||
*
|
||||
* overflow is set to true when the query buffer overflows.
|
||||
*
|
||||
* n_bucket_cycles counts the number of times we changed bucket
|
||||
* since the query buffer overflowed. When it reaches pgsm_max_buckets
|
||||
* we remove the dump file, also reset the counter.
|
||||
*
|
||||
* This allows us to avoid having a large file on disk that would also
|
||||
* slowdown queries to the pg_stat_monitor view.
|
||||
*/
|
||||
bool overflow;
|
||||
size_t n_bucket_cycles;
|
||||
} pgssSharedState;
|
||||
|
||||
#define ResetSharedState(x) \
|
||||
|
@ -382,21 +390,20 @@ int pgsm_get_bucket_size(void);
|
|||
pgssSharedState* pgsm_get_ss(void);
|
||||
HTAB *pgsm_get_plan_hash(void);
|
||||
HTAB *pgsm_get_hash(void);
|
||||
HTAB *pgsm_get_query_hash(void);
|
||||
HTAB *pgsm_get_plan_hash(void);
|
||||
void hash_entry_reset(void);
|
||||
void hash_query_entryies_reset(void);
|
||||
void hash_query_entries();
|
||||
void hash_query_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer[]);
|
||||
void hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer[]);
|
||||
void hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer);
|
||||
pgssEntry* hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding);
|
||||
Size hash_memsize(void);
|
||||
|
||||
int read_query_buffer(int bucket_id, uint64 queryid, char *query_txt, size_t pos);
|
||||
uint64 read_query(unsigned char *buf, uint64 queryid, char * query, size_t pos);
|
||||
pgssQueryEntry* hash_find_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 userid, uint64 ip, uint64 appid);
|
||||
pgssQueryEntry* hash_create_query_entry(uint64 bucket_id, uint64 queryid, uint64 dbid, uint64 userid, uint64 ip, uint64 appid);
|
||||
void pgss_startup(void);
|
||||
void set_qbuf(int i, unsigned char *);
|
||||
void set_qbuf(unsigned char *);
|
||||
|
||||
/* hash_query.c */
|
||||
void pgss_startup(void);
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pgsm_errors.c
|
||||
* Track pg_stat_monitor internal error messages.
|
||||
*
|
||||
* Copyright © 2021, Percona LLC and/or its affiliates
|
||||
*
|
||||
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
||||
*
|
||||
* Portions Copyright (c) 1994, The Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* contrib/pg_stat_monitor/pgsm_errors.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <postgres.h>
|
||||
#include <access/hash.h>
|
||||
#include <storage/shmem.h>
|
||||
#include <utils/hsearch.h>
|
||||
|
||||
#include "pg_stat_monitor.h"
|
||||
#include "pgsm_errors.h"
|
||||
|
||||
|
||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_errors);
|
||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_reset_errors);
|
||||
|
||||
|
||||
/*
|
||||
* Maximum number of error messages tracked.
|
||||
* This should be set to a sensible value in order to track
|
||||
* the different type of errors that pg_stat_monitor may
|
||||
* report, e.g. out of memory.
|
||||
*/
|
||||
#define PSGM_ERRORS_MAX 128
|
||||
|
||||
static HTAB *pgsm_errors_ht = NULL;
|
||||
|
||||
void psgm_errors_init(void)
|
||||
{
|
||||
HASHCTL info;
|
||||
#if PG_VERSION_NUM >= 140000
|
||||
int flags = HASH_ELEM | HASH_STRINGS;
|
||||
#else
|
||||
int flags = HASH_ELEM | HASH_BLOBS;
|
||||
#endif
|
||||
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.keysize = ERROR_MSG_MAX_LEN;
|
||||
info.entrysize = sizeof(ErrorEntry);
|
||||
pgsm_errors_ht = ShmemInitHash("pg_stat_monitor: errors hashtable",
|
||||
PSGM_ERRORS_MAX, /* initial size */
|
||||
PSGM_ERRORS_MAX, /* maximum size */
|
||||
&info,
|
||||
flags);
|
||||
}
|
||||
|
||||
size_t pgsm_errors_size(void)
|
||||
{
|
||||
return hash_estimate_size(PSGM_ERRORS_MAX, sizeof(ErrorEntry));
|
||||
}
|
||||
|
||||
void pgsm_log(PgsmLogSeverity severity, const char *format, ...)
|
||||
{
|
||||
char key[ERROR_MSG_MAX_LEN];
|
||||
ErrorEntry *entry;
|
||||
bool found = false;
|
||||
va_list ap;
|
||||
int n;
|
||||
struct timeval tv;
|
||||
struct tm *lt;
|
||||
pgssSharedState *pgss;
|
||||
|
||||
va_start(ap, format);
|
||||
n = vsnprintf(key, ERROR_MSG_MAX_LEN, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (n < 0)
|
||||
return;
|
||||
|
||||
pgss = pgsm_get_ss();
|
||||
LWLockAcquire(pgss->errors_lock, LW_EXCLUSIVE);
|
||||
|
||||
entry = (ErrorEntry *) hash_search(pgsm_errors_ht, key, HASH_ENTER_NULL, &found);
|
||||
if (!entry)
|
||||
{
|
||||
LWLockRelease(pgss->errors_lock);
|
||||
/*
|
||||
* We're out of memory, can't track this error message.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
entry->severity = severity;
|
||||
entry->calls = 0;
|
||||
}
|
||||
|
||||
/* Update message timestamp. */
|
||||
gettimeofday(&tv, NULL);
|
||||
lt = localtime(&tv.tv_sec);
|
||||
snprintf(entry->time, sizeof(entry->time),
|
||||
"%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);
|
||||
|
||||
entry->calls++;
|
||||
|
||||
LWLockRelease(pgss->errors_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear all entries from the hash table.
|
||||
*/
|
||||
Datum
|
||||
pg_stat_monitor_reset_errors(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HASH_SEQ_STATUS hash_seq;
|
||||
ErrorEntry *entry;
|
||||
pgssSharedState *pgss = pgsm_get_ss();
|
||||
|
||||
/* Safety check... */
|
||||
if (!IsSystemInitialized())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("pg_stat_monitor: must be loaded via shared_preload_libraries")));
|
||||
|
||||
LWLockAcquire(pgss->errors_lock, LW_EXCLUSIVE);
|
||||
|
||||
hash_seq_init(&hash_seq, pgsm_errors_ht);
|
||||
while ((entry = hash_seq_search(&hash_seq)) != NULL)
|
||||
entry = hash_search(pgsm_errors_ht, &entry->message, HASH_REMOVE, NULL);
|
||||
|
||||
LWLockRelease(pgss->errors_lock);
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoked when users query the view pg_stat_monitor_errors.
|
||||
* This function creates tuples with error messages from data present in
|
||||
* the hash table, then return the dataset to the caller.
|
||||
*/
|
||||
Datum
|
||||
pg_stat_monitor_errors(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
|
||||
TupleDesc tupdesc;
|
||||
Tuplestorestate *tupstore;
|
||||
MemoryContext per_query_ctx;
|
||||
MemoryContext oldcontext;
|
||||
HASH_SEQ_STATUS hash_seq;
|
||||
ErrorEntry *error_entry;
|
||||
pgssSharedState *pgss = pgsm_get_ss();
|
||||
|
||||
/* Safety check... */
|
||||
if (!IsSystemInitialized())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("pg_stat_monitor: must be loaded via shared_preload_libraries")));
|
||||
|
||||
/* check to see if caller supports us returning a tuplestore */
|
||||
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("pg_stat_monitor: set-valued function called in context that cannot accept a set")));
|
||||
|
||||
/* Switch into long-lived context to construct returned data structures */
|
||||
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
|
||||
oldcontext = MemoryContextSwitchTo(per_query_ctx);
|
||||
|
||||
/* Build a tuple descriptor for our result type */
|
||||
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
||||
elog(ERROR, "pg_stat_monitor: return type must be a row type");
|
||||
|
||||
if (tupdesc->natts != 4)
|
||||
elog(ERROR, "pg_stat_monitor: incorrect number of output arguments, required 3, found %d", tupdesc->natts);
|
||||
|
||||
tupstore = tuplestore_begin_heap(true, false, work_mem);
|
||||
rsinfo->returnMode = SFRM_Materialize;
|
||||
rsinfo->setResult = tupstore;
|
||||
rsinfo->setDesc = tupdesc;
|
||||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
LWLockAcquire(pgss->errors_lock, LW_SHARED);
|
||||
|
||||
hash_seq_init(&hash_seq, pgsm_errors_ht);
|
||||
while ((error_entry = hash_seq_search(&hash_seq)) != NULL)
|
||||
{
|
||||
Datum values[4];
|
||||
bool nulls[4];
|
||||
int i = 0;
|
||||
memset(values, 0, sizeof(values));
|
||||
memset(nulls, 0, sizeof(nulls));
|
||||
|
||||
values[i++] = Int64GetDatumFast(error_entry->severity);
|
||||
values[i++] = CStringGetTextDatum(error_entry->message);
|
||||
values[i++] = CStringGetTextDatum(error_entry->time);
|
||||
values[i++] = Int64GetDatumFast(error_entry->calls);
|
||||
|
||||
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
|
||||
}
|
||||
|
||||
LWLockRelease(pgss->errors_lock);
|
||||
/* clean up and return the tuplestore */
|
||||
tuplestore_donestoring(tupstore);
|
||||
|
||||
return (Datum)0;
|
||||
}
|
|
@ -12,11 +12,11 @@ SELECT 1 AS num;
|
|||
(1 row)
|
||||
|
||||
SELECT query,application_name FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | application_name
|
||||
--------------------------------------------------------------------------------+-----------------------------
|
||||
SELECT $1 AS num | pg_regress/application_name
|
||||
SELECT pg_stat_monitor_reset(); | pg_regress/application_name
|
||||
SELECT query,application_name FROM pg_stat_monitor ORDER BY query COLLATE "C"; | pg_regress/application_name
|
||||
query | application_name
|
||||
-------------------------------------------------------------------------------+-----------------------------
|
||||
SELECT $1 AS num | pg_regress/application_name
|
||||
SELECT pg_stat_monitor_reset() | pg_regress/application_name
|
||||
SELECT query,application_name FROM pg_stat_monitor ORDER BY query COLLATE "C" | pg_regress/application_name
|
||||
(3 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
Create EXTENSION pg_stat_monitor;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
Set application_name = 'naeem' ;
|
||||
SELECT 1 AS num;
|
||||
num
|
||||
-----
|
||||
1
|
||||
(1 row)
|
||||
|
||||
Set application_name = 'psql' ;
|
||||
SELECT 1 AS num;
|
||||
num
|
||||
-----
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT query,application_name FROM pg_stat_monitor ORDER BY query, application_name COLLATE "C";
|
||||
query | application_name
|
||||
--------------------------------+------------------------------------
|
||||
SELECT $1 AS num | naeem
|
||||
SELECT $1 AS num | psql
|
||||
SELECT pg_stat_monitor_reset() | pg_regress/application_name_unique
|
||||
Set application_name = 'naeem' | naeem
|
||||
Set application_name = 'psql' | psql
|
||||
(5 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
DROP EXTENSION pg_stat_monitor;
|
|
@ -12,11 +12,11 @@ SELECT 1 AS num;
|
|||
(1 row)
|
||||
|
||||
SELECT query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query
|
||||
---------------------------------------------------------------
|
||||
query
|
||||
--------------------------------------------------------------
|
||||
SELECT $1 AS num
|
||||
SELECT pg_stat_monitor_reset();
|
||||
SELECT query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
SELECT pg_stat_monitor_reset()
|
||||
SELECT query FROM pg_stat_monitor ORDER BY query COLLATE "C"
|
||||
(3 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -24,19 +24,19 @@ SELECT b FROM t2 FOR UPDATE;
|
|||
TRUNCATE t1;
|
||||
DROP TABLE t1;
|
||||
SELECT query, cmd_type, cmd_type_text FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | cmd_type | cmd_type_text
|
||||
-----------------------------------------------------------------------------------------+----------+---------------
|
||||
CREATE TABLE t1 (a INTEGER); | 0 |
|
||||
CREATE TABLE t2 (b INTEGER); | 0 |
|
||||
DELETE FROM t1; | 4 | DELETE
|
||||
DROP TABLE t1; | 0 |
|
||||
INSERT INTO t1 VALUES($1) | 3 | INSERT
|
||||
SELECT a FROM t1; | 1 | SELECT
|
||||
SELECT b FROM t2 FOR UPDATE; | 1 | SELECT
|
||||
SELECT pg_stat_monitor_reset(); | 1 | SELECT
|
||||
SELECT query, cmd_type, cmd_type_text FROM pg_stat_monitor ORDER BY query COLLATE "C"; | 1 | SELECT
|
||||
TRUNCATE t1; | 0 |
|
||||
UPDATE t1 SET a = $1 | 2 | UPDATE
|
||||
query | cmd_type | cmd_type_text
|
||||
----------------------------------------------------------------------------------------+----------+---------------
|
||||
CREATE TABLE t1 (a INTEGER) | 0 |
|
||||
CREATE TABLE t2 (b INTEGER) | 0 |
|
||||
DELETE FROM t1 | 4 | DELETE
|
||||
DROP TABLE t1 | 0 |
|
||||
INSERT INTO t1 VALUES($1) | 3 | INSERT
|
||||
SELECT a FROM t1 | 1 | SELECT
|
||||
SELECT b FROM t2 FOR UPDATE | 1 | SELECT
|
||||
SELECT pg_stat_monitor_reset() | 1 | SELECT
|
||||
SELECT query, cmd_type, cmd_type_text FROM pg_stat_monitor ORDER BY query COLLATE "C" | 1 | SELECT
|
||||
TRUNCATE t1 | 0 |
|
||||
UPDATE t1 SET a = $1 | 2 | UPDATE
|
||||
(11 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -36,11 +36,11 @@ SELECT a,b,c,d FROM t1, t2, t3, t4 WHERE t1.a = t2.b AND t3.c = t4.d ORDER BY a;
|
|||
(0 rows)
|
||||
|
||||
SELECT query,calls FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | calls
|
||||
----------------------------------------------------------------------------------+-------
|
||||
SELECT a,b,c,d FROM t1, t2, t3, t4 WHERE t1.a = t2.b AND t3.c = t4.d ORDER BY a; | 4
|
||||
SELECT pg_stat_monitor_reset(); | 1
|
||||
SELECT query,calls FROM pg_stat_monitor ORDER BY query COLLATE "C"; | 1
|
||||
query | calls
|
||||
---------------------------------------------------------------------------------+-------
|
||||
SELECT a,b,c,d FROM t1, t2, t3, t4 WHERE t1.a = t2.b AND t3.c = t4.d ORDER BY a | 4
|
||||
SELECT pg_stat_monitor_reset() | 1
|
||||
SELECT query,calls FROM pg_stat_monitor ORDER BY query COLLATE "C" | 1
|
||||
(3 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -69,8 +69,8 @@ SELECT query,calls FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
|||
query | calls
|
||||
---------------------------------------------------------------------------------------------------+-------
|
||||
SELECT a,b,c,d FROM t1, t2, t3, t4 WHERE t1.a = t2.b AND t3.c = t4.d ORDER BY a | 1000
|
||||
SELECT pg_stat_monitor_reset(); | 1
|
||||
SELECT query,calls FROM pg_stat_monitor ORDER BY query COLLATE "C"; | 1
|
||||
SELECT pg_stat_monitor_reset() | 1
|
||||
SELECT query,calls FROM pg_stat_monitor ORDER BY query COLLATE "C" | 1
|
||||
do $$ +| 1
|
||||
declare +|
|
||||
n integer:= 1; +|
|
||||
|
@ -80,7 +80,7 @@ SELECT query,calls FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
|||
exit when n = 1000; +|
|
||||
n := n + 1; +|
|
||||
end loop; +|
|
||||
end $$; |
|
||||
end $$ |
|
||||
(4 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -28,12 +28,12 @@ SELECT * FROM t3,t4 WHERE t3.c = t4.d;
|
|||
|
||||
\c contrib_regression
|
||||
SELECT datname, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
datname | query
|
||||
--------------------+------------------------------------------------------------------------
|
||||
db1 | SELECT * FROM t1,t2 WHERE t1.a = t2.b;
|
||||
db2 | SELECT * FROM t3,t4 WHERE t3.c = t4.d;
|
||||
contrib_regression | SELECT datname, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
contrib_regression | SELECT pg_stat_monitor_reset();
|
||||
datname | query
|
||||
--------------------+-----------------------------------------------------------------------
|
||||
db1 | SELECT * FROM t1,t2 WHERE t1.a = t2.b
|
||||
db2 | SELECT * FROM t3,t4 WHERE t3.c = t4.d
|
||||
contrib_regression | SELECT datname, query FROM pg_stat_monitor ORDER BY query COLLATE "C"
|
||||
contrib_regression | SELECT pg_stat_monitor_reset()
|
||||
(4 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -21,18 +21,22 @@ RAISE WARNING 'warning message';
|
|||
END $$;
|
||||
WARNING: warning message
|
||||
SELECT query, elevel, sqlcode, message FROM pg_stat_monitor ORDER BY query COLLATE "C",elevel;
|
||||
query | elevel | sqlcode | message
|
||||
------------------------------------------------------------------------------------------------+--------+---------+-----------------------------------
|
||||
ELECET * FROM unknown; | 20 | 42601 | syntax error at or near "ELECET"
|
||||
SELECT * FROM unknown; | 20 | 42P01 | relation "unknown" does not exist
|
||||
SELECT 1/0; | 20 | 22012 | division by zero
|
||||
SELECT pg_stat_monitor_reset(); | 0 | |
|
||||
SELECT query, elevel, sqlcode, message FROM pg_stat_monitor ORDER BY query COLLATE "C",elevel; | 0 | |
|
||||
do $$ +| 19 | 01000 | warning message
|
||||
BEGIN +| | |
|
||||
RAISE WARNING 'warning message'; +| | |
|
||||
END $$; | | |
|
||||
(6 rows)
|
||||
query | elevel | sqlcode | message
|
||||
-----------------------------------------------------------------------------------------------+--------+---------+-----------------------------------
|
||||
ELECET * FROM unknown; | 20 | 42601 | syntax error at or near "ELECET"
|
||||
SELECT * FROM unknown; | 20 | 42P01 | relation "unknown" does not exist
|
||||
SELECT 1/0; | 20 | 22012 | division by zero
|
||||
SELECT pg_stat_monitor_reset() | 0 | |
|
||||
SELECT query, elevel, sqlcode, message FROM pg_stat_monitor ORDER BY query COLLATE "C",elevel | 0 | |
|
||||
do $$ +| 0 | |
|
||||
BEGIN +| | |
|
||||
RAISE WARNING 'warning message'; +| | |
|
||||
END $$ | | |
|
||||
do $$ +| 19 | 01000 | warning message
|
||||
BEGIN +| | |
|
||||
RAISE WARNING 'warning message'; +| | |
|
||||
END $$; | | |
|
||||
(7 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
|
|
|
@ -21,18 +21,22 @@ RAISE WARNING 'warning message';
|
|||
END $$;
|
||||
WARNING: warning message
|
||||
SELECT query, elevel, sqlcode, message FROM pg_stat_monitor ORDER BY query COLLATE "C",elevel;
|
||||
query | elevel | sqlcode | message
|
||||
------------------------------------------------------------------------------------------------+--------+---------+-----------------------------------
|
||||
ELECET * FROM unknown; | 21 | 42601 | syntax error at or near "ELECET"
|
||||
SELECT * FROM unknown; | 21 | 42P01 | relation "unknown" does not exist
|
||||
SELECT 1/0; | 21 | 22012 | division by zero
|
||||
SELECT pg_stat_monitor_reset(); | 0 | |
|
||||
SELECT query, elevel, sqlcode, message FROM pg_stat_monitor ORDER BY query COLLATE "C",elevel; | 0 | |
|
||||
do $$ +| 19 | 01000 | warning message
|
||||
BEGIN +| | |
|
||||
RAISE WARNING 'warning message'; +| | |
|
||||
END $$; | | |
|
||||
(6 rows)
|
||||
query | elevel | sqlcode | message
|
||||
-----------------------------------------------------------------------------------------------+--------+---------+-----------------------------------
|
||||
ELECET * FROM unknown; | 21 | 42601 | syntax error at or near "ELECET"
|
||||
SELECT * FROM unknown; | 21 | 42P01 | relation "unknown" does not exist
|
||||
SELECT 1/0; | 21 | 22012 | division by zero
|
||||
SELECT pg_stat_monitor_reset() | 0 | |
|
||||
SELECT query, elevel, sqlcode, message FROM pg_stat_monitor ORDER BY query COLLATE "C",elevel | 0 | |
|
||||
do $$ +| 0 | |
|
||||
BEGIN +| | |
|
||||
RAISE WARNING 'warning message'; +| | |
|
||||
END $$ | | |
|
||||
do $$ +| 19 | 01000 | warning message
|
||||
BEGIN +| | |
|
||||
RAISE WARNING 'warning message'; +| | |
|
||||
END $$; | | |
|
||||
(7 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
Drop Table if exists Company;
|
||||
NOTICE: table "company" does not exist, skipping
|
||||
CREATE TABLE Company(
|
||||
ID INT PRIMARY KEY NOT NULL,
|
||||
NAME TEXT NOT NULL
|
||||
);
|
||||
CREATE EXTENSION pg_stat_monitor;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO Company(ID, Name) VALUES (1, 'Percona');
|
||||
INSERT INTO Company(ID, Name) VALUES (1, 'Percona');
|
||||
ERROR: duplicate key value violates unique constraint "company_pkey"
|
||||
DETAIL: Key (id)=(1) already exists.
|
||||
Drop Table if exists Company;
|
||||
SELECT query, elevel, sqlcode, message FROM pg_stat_monitor ORDER BY query COLLATE "C",elevel;
|
||||
query | elevel | sqlcode | message
|
||||
-------------------------------------------------------+--------+---------+---------------------------------------------------------------
|
||||
Drop Table if exists Company | 0 | |
|
||||
INSERT INTO Company(ID, Name) VALUES ($1, $2) | 0 | |
|
||||
INSERT INTO Company(ID, Name) VALUES (1, 'Percona'); | 21 | 23505 | duplicate key value violates unique constraint "company_pkey"
|
||||
SELECT pg_stat_monitor_reset() | 0 | |
|
||||
(4 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
DROP EXTENSION pg_stat_monitor;
|
|
@ -0,0 +1,34 @@
|
|||
Drop Table if exists Company;
|
||||
NOTICE: table "company" does not exist, skipping
|
||||
CREATE TABLE Company(
|
||||
ID INT PRIMARY KEY NOT NULL,
|
||||
NAME TEXT NOT NULL
|
||||
);
|
||||
CREATE EXTENSION pg_stat_monitor;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO Company(ID, Name) VALUES (1, 'Percona');
|
||||
INSERT INTO Company(ID, Name) VALUES (1, 'Percona');
|
||||
ERROR: duplicate key value violates unique constraint "company_pkey"
|
||||
DETAIL: Key (id)=(1) already exists.
|
||||
Drop Table if exists Company;
|
||||
SELECT query, elevel, sqlcode, message FROM pg_stat_monitor ORDER BY query COLLATE "C",elevel;
|
||||
query | elevel | sqlcode | message
|
||||
-------------------------------------------------------+--------+---------+---------------------------------------------------------------
|
||||
Drop Table if exists Company | 0 | |
|
||||
INSERT INTO Company(ID, Name) VALUES ($1, $2) | 0 | |
|
||||
INSERT INTO Company(ID, Name) VALUES (1, 'Percona'); | 20 | 23505 | duplicate key value violates unique constraint "company_pkey"
|
||||
SELECT pg_stat_monitor_reset() | 0 | |
|
||||
(4 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
DROP EXTENSION pg_stat_monitor;
|
|
@ -0,0 +1,71 @@
|
|||
CREATE OR REPLACE FUNCTION generate_histogram()
|
||||
RETURNS TABLE (
|
||||
range TEXT, freq INT, bar TEXT
|
||||
) AS $$
|
||||
Declare
|
||||
bucket_id integer;
|
||||
query_id text;
|
||||
BEGIN
|
||||
select bucket into bucket_id from pg_stat_monitor order by calls desc limit 1;
|
||||
select queryid into query_id from pg_stat_monitor order by calls desc limit 1;
|
||||
--RAISE INFO 'bucket_id %', bucket_id;
|
||||
--RAISE INFO 'query_id %', query_id;
|
||||
return query
|
||||
SELECT * FROM histogram(bucket_id, query_id) AS a(range TEXT, freq INT, bar TEXT);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE OR REPLACE FUNCTION run_pg_sleep(INTEGER) RETURNS VOID AS $$
|
||||
DECLARE
|
||||
loops ALIAS FOR $1;
|
||||
BEGIN
|
||||
FOR i IN 1..loops LOOP
|
||||
--RAISE INFO 'Current timestamp: %', timeofday()::TIMESTAMP;
|
||||
RAISE INFO 'Sleep % seconds', i;
|
||||
PERFORM pg_sleep(i);
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' STRICT;
|
||||
CREATE EXTENSION pg_stat_monitor;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
Set pg_stat_monitor.track='all';
|
||||
select run_pg_sleep(5);
|
||||
INFO: Sleep 1 seconds
|
||||
INFO: Sleep 2 seconds
|
||||
INFO: Sleep 3 seconds
|
||||
INFO: Sleep 4 seconds
|
||||
INFO: Sleep 5 seconds
|
||||
run_pg_sleep
|
||||
--------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT substr(query, 0,50) as query, calls, resp_calls FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | calls | resp_calls
|
||||
---------------------------------+-------+-----------------------
|
||||
SELECT pg_sleep(i) | 5 | {0,0,0,0,0,0,3,2,0,0}
|
||||
SELECT pg_stat_monitor_reset() | 1 | {1,0,0,0,0,0,0,0,0,0}
|
||||
Set pg_stat_monitor.track='all' | 1 | {1,0,0,0,0,0,0,0,0,0}
|
||||
select run_pg_sleep($1) | 1 | {0,0,0,0,0,0,0,0,1,0}
|
||||
(4 rows)
|
||||
|
||||
select * from generate_histogram();
|
||||
range | freq | bar
|
||||
--------------------+------+--------------------------------------------------------------------------------------------
|
||||
(0 - 3)} | 0 |
|
||||
(3 - 10)} | 0 |
|
||||
(10 - 31)} | 0 |
|
||||
(31 - 100)} | 0 |
|
||||
(100 - 316)} | 0 |
|
||||
(316 - 1000)} | 0 |
|
||||
(1000 - 3162)} | 3 | ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
|
||||
(3162 - 10000)} | 2 | ■■■■■■■■■■■■■■■■■■■■
|
||||
(10000 - 31622)} | 0 |
|
||||
(31622 - 100000)} | 0 |
|
||||
(10 rows)
|
||||
|
||||
DROP EXTENSION pg_stat_monitor;
|
|
@ -0,0 +1,71 @@
|
|||
CREATE OR REPLACE FUNCTION generate_histogram()
|
||||
RETURNS TABLE (
|
||||
range TEXT, freq INT, bar TEXT
|
||||
) AS $$
|
||||
Declare
|
||||
bucket_id integer;
|
||||
query_id text;
|
||||
BEGIN
|
||||
select bucket into bucket_id from pg_stat_monitor order by calls desc limit 1;
|
||||
select queryid into query_id from pg_stat_monitor order by calls desc limit 1;
|
||||
--RAISE INFO 'bucket_id %', bucket_id;
|
||||
--RAISE INFO 'query_id %', query_id;
|
||||
return query
|
||||
SELECT * FROM histogram(bucket_id, query_id) AS a(range TEXT, freq INT, bar TEXT);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE OR REPLACE FUNCTION run_pg_sleep(INTEGER) RETURNS VOID AS $$
|
||||
DECLARE
|
||||
loops ALIAS FOR $1;
|
||||
BEGIN
|
||||
FOR i IN 1..loops LOOP
|
||||
--RAISE INFO 'Current timestamp: %', timeofday()::TIMESTAMP;
|
||||
RAISE INFO 'Sleep % seconds', i;
|
||||
PERFORM pg_sleep(i);
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' STRICT;
|
||||
CREATE EXTENSION pg_stat_monitor;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
pg_stat_monitor_reset
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
Set pg_stat_monitor.track='all';
|
||||
select run_pg_sleep(5);
|
||||
INFO: Sleep 1 seconds
|
||||
INFO: Sleep 2 seconds
|
||||
INFO: Sleep 3 seconds
|
||||
INFO: Sleep 4 seconds
|
||||
INFO: Sleep 5 seconds
|
||||
run_pg_sleep
|
||||
--------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT substr(query, 0,50) as query, calls, resp_calls FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | calls | resp_calls
|
||||
---------------------------------+-------+-----------------------
|
||||
SELECT pg_sleep(i) | 5 | {0,0,0,0,0,0,3,2,0,0}
|
||||
SELECT pg_stat_monitor_reset() | 1 | {1,0,0,0,0,0,0,0,0,0}
|
||||
Set pg_stat_monitor.track='all' | 1 | {1,0,0,0,0,0,0,0,0,0}
|
||||
select run_pg_sleep($1) | 1 | {0,0,0,0,0,0,0,0,1,0}
|
||||
(4 rows)
|
||||
|
||||
select * from generate_histogram();
|
||||
range | freq | bar
|
||||
--------------------+------+--------------------------------
|
||||
(0 - 3)} | 0 |
|
||||
(3 - 10)} | 0 |
|
||||
(10 - 31)} | 0 |
|
||||
(31 - 100)} | 0 |
|
||||
(100 - 316)} | 0 |
|
||||
(316 - 1000)} | 0 |
|
||||
(1000 - 3162)} | 3 | ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
|
||||
(3162 - 10000)} | 2 | ■■■■■■■■■■■■■■■■■■■■
|
||||
(10000 - 31622)} | 0 |
|
||||
(31622 - 100000)} | 0 |
|
||||
(10 rows)
|
||||
|
||||
DROP EXTENSION pg_stat_monitor;
|
|
@ -37,14 +37,14 @@ SELECT * FROM foo1, foo2, foo3, foo4;
|
|||
(0 rows)
|
||||
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query collate "C";
|
||||
query | relations
|
||||
--------------------------------------------------------------------------+---------------------------------------------------
|
||||
SELECT * FROM foo1, foo2, foo3, foo4; | {public.foo1,public.foo2,public.foo3,public.foo4}
|
||||
SELECT * FROM foo1, foo2, foo3; | {public.foo1,public.foo2,public.foo3}
|
||||
SELECT * FROM foo1, foo2; | {public.foo1,public.foo2}
|
||||
SELECT * FROM foo1; | {public.foo1}
|
||||
SELECT pg_stat_monitor_reset(); |
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query collate "C"; | {public.pg_stat_monitor*,pg_catalog.pg_database}
|
||||
query | relations
|
||||
-------------------------------------------------------------------------+---------------------------------------------------
|
||||
SELECT * FROM foo1 | {public.foo1}
|
||||
SELECT * FROM foo1, foo2 | {public.foo1,public.foo2}
|
||||
SELECT * FROM foo1, foo2, foo3 | {public.foo1,public.foo2,public.foo3}
|
||||
SELECT * FROM foo1, foo2, foo3, foo4 | {public.foo1,public.foo2,public.foo3,public.foo4}
|
||||
SELECT pg_stat_monitor_reset() |
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query collate "C" | {public.pg_stat_monitor*,pg_catalog.pg_database}
|
||||
(6 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -89,14 +89,14 @@ SELECT * FROM sch1.foo1, sch2.foo2, sch3.foo3, sch4.foo4;
|
|||
(0 rows)
|
||||
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query collate "C";
|
||||
query | relations
|
||||
--------------------------------------------------------------------------+--------------------------------------------------
|
||||
SELECT * FROM sch1.foo1, sch2.foo2, sch3.foo3, sch4.foo4; | {sch1.foo1,sch2.foo2,sch3.foo3,sch4.foo4}
|
||||
SELECT * FROM sch1.foo1, sch2.foo2, sch3.foo3; | {sch1.foo1,sch2.foo2,sch3.foo3}
|
||||
SELECT * FROM sch1.foo1, sch2.foo2; | {sch1.foo1,sch2.foo2}
|
||||
SELECT * FROM sch1.foo1; | {sch1.foo1}
|
||||
SELECT pg_stat_monitor_reset(); |
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query collate "C"; | {public.pg_stat_monitor*,pg_catalog.pg_database}
|
||||
query | relations
|
||||
-------------------------------------------------------------------------+--------------------------------------------------
|
||||
SELECT * FROM sch1.foo1 | {sch1.foo1}
|
||||
SELECT * FROM sch1.foo1, sch2.foo2 | {sch1.foo1,sch2.foo2}
|
||||
SELECT * FROM sch1.foo1, sch2.foo2, sch3.foo3 | {sch1.foo1,sch2.foo2,sch3.foo3}
|
||||
SELECT * FROM sch1.foo1, sch2.foo2, sch3.foo3, sch4.foo4 | {sch1.foo1,sch2.foo2,sch3.foo3,sch4.foo4}
|
||||
SELECT pg_stat_monitor_reset() |
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query collate "C" | {public.pg_stat_monitor*,pg_catalog.pg_database}
|
||||
(6 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -122,12 +122,12 @@ SELECT * FROM sch1.foo1, sch2.foo2, foo1, foo2;
|
|||
(0 rows)
|
||||
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query;
|
||||
query | relations
|
||||
--------------------------------------------------------------+--------------------------------------------------
|
||||
SELECT * FROM sch1.foo1, foo1; | {sch1.foo1,public.foo1}
|
||||
SELECT * FROM sch1.foo1, sch2.foo2, foo1, foo2; | {sch1.foo1,sch2.foo2,public.foo1,public.foo2}
|
||||
SELECT pg_stat_monitor_reset(); |
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query; | {public.pg_stat_monitor*,pg_catalog.pg_database}
|
||||
query | relations
|
||||
-------------------------------------------------------------+--------------------------------------------------
|
||||
SELECT * FROM sch1.foo1, foo1 | {sch1.foo1,public.foo1}
|
||||
SELECT * FROM sch1.foo1, sch2.foo2, foo1, foo2 | {sch1.foo1,sch2.foo2,public.foo1,public.foo2}
|
||||
SELECT pg_stat_monitor_reset() |
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query | {public.pg_stat_monitor*,pg_catalog.pg_database}
|
||||
(4 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
@ -168,14 +168,14 @@ SELECT * FROM v1,v2,v3,v4;
|
|||
(0 rows)
|
||||
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query collate "C";
|
||||
query | relations
|
||||
--------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------
|
||||
SELECT * FROM v1,v2,v3,v4; | {public.v1*,public.foo1,public.v2*,public.foo2,public.v3*,public.foo3,public.v4*,public.foo4}
|
||||
SELECT * FROM v1,v2,v3; | {public.v1*,public.foo1,public.v2*,public.foo2,public.v3*,public.foo3}
|
||||
SELECT * FROM v1,v2; | {public.v1*,public.foo1,public.v2*,public.foo2}
|
||||
SELECT * FROM v1; | {public.v1*,public.foo1}
|
||||
SELECT pg_stat_monitor_reset(); |
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query collate "C"; | {public.pg_stat_monitor*,pg_catalog.pg_database}
|
||||
query | relations
|
||||
-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------
|
||||
SELECT * FROM v1 | {public.v1*,public.foo1}
|
||||
SELECT * FROM v1,v2 | {public.v1*,public.foo1,public.v2*,public.foo2}
|
||||
SELECT * FROM v1,v2,v3 | {public.v1*,public.foo1,public.v2*,public.foo2,public.v3*,public.foo3}
|
||||
SELECT * FROM v1,v2,v3,v4 | {public.v1*,public.foo1,public.v2*,public.foo2,public.v3*,public.foo3,public.v4*,public.foo4}
|
||||
SELECT pg_stat_monitor_reset() |
|
||||
SELECT query, relations from pg_stat_monitor ORDER BY query collate "C" | {public.pg_stat_monitor*,pg_catalog.pg_database}
|
||||
(6 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -8541,14 +8541,14 @@ SELECt * FROM t2 WHERE b % 2 = 0;
|
|||
(2500 rows)
|
||||
|
||||
SELECT query, rows_retrieved FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | rows_retrieved
|
||||
-------------------------------------------------------------------------------+----------------
|
||||
SELECT * FROM t1 LIMIT $1 | 10
|
||||
SELECT * FROM t1; | 1000
|
||||
SELECT * FROM t2; | 5000
|
||||
SELECT pg_stat_monitor_reset(); | 1
|
||||
SELECT query, rows_retrieved FROM pg_stat_monitor ORDER BY query COLLATE "C"; | 0
|
||||
SELECt * FROM t2 WHERE b % $1 = $2 | 2500
|
||||
query | rows_retrieved
|
||||
------------------------------------------------------------------------------+----------------
|
||||
SELECT * FROM t1 | 1000
|
||||
SELECT * FROM t1 LIMIT $1 | 10
|
||||
SELECT * FROM t2 | 5000
|
||||
SELECT pg_stat_monitor_reset() | 1
|
||||
SELECT query, rows_retrieved FROM pg_stat_monitor ORDER BY query COLLATE "C" | 0
|
||||
SELECt * FROM t2 WHERE b % $1 = $2 | 2500
|
||||
(6 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -8541,14 +8541,14 @@ SELECt * FROM t2 WHERE b % 2 = 0;
|
|||
(2500 rows)
|
||||
|
||||
SELECT query, rows_retrieved FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | rows_retrieved
|
||||
-------------------------------------------------------------------------------+----------------
|
||||
SELECT * FROM t1 LIMIT $1 | 10
|
||||
SELECT * FROM t1; | 1000
|
||||
SELECT b FROM t2 FOR UPDATE; | 5000
|
||||
SELECT pg_stat_monitor_reset(); | 1
|
||||
SELECT query, rows_retrieved FROM pg_stat_monitor ORDER BY query COLLATE "C"; | 0
|
||||
SELECt * FROM t2 WHERE b % $1 = $2 | 2500
|
||||
query | rows_retrieved
|
||||
------------------------------------------------------------------------------+----------------
|
||||
SELECT * FROM t1 | 1000
|
||||
SELECT * FROM t1 LIMIT $1 | 10
|
||||
SELECT b FROM t2 FOR UPDATE | 5000
|
||||
SELECT pg_stat_monitor_reset() | 1
|
||||
SELECT query, rows_retrieved FROM pg_stat_monitor ORDER BY query COLLATE "C" | 0
|
||||
SELECt * FROM t2 WHERE b % $1 = $2 | 2500
|
||||
(6 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -14,12 +14,12 @@ SELECT 1;
|
|||
SELECT 1/0; -- divide by zero
|
||||
ERROR: division by zero
|
||||
SELECT query, state_code, state FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | state_code | state
|
||||
----------------------------------------------------------------------------------+------------+---------------------
|
||||
SELECT $1 | 3 | FINISHED
|
||||
SELECT 1/0; | 4 | FINISHED WITH ERROR
|
||||
SELECT pg_stat_monitor_reset(); | 3 | FINISHED
|
||||
SELECT query, state_code, state FROM pg_stat_monitor ORDER BY query COLLATE "C"; | 2 | ACTIVE
|
||||
query | state_code | state
|
||||
---------------------------------------------------------------------------------+------------+---------------------
|
||||
SELECT $1 | 3 | FINISHED
|
||||
SELECT 1/0; | 4 | FINISHED WITH ERROR
|
||||
SELECT pg_stat_monitor_reset() | 3 | FINISHED
|
||||
SELECT query, state_code, state FROM pg_stat_monitor ORDER BY query COLLATE "C" | 2 | ACTIVE
|
||||
(4 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -15,8 +15,8 @@ SELECT query, comments FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
|||
query | comments
|
||||
---------------------------------------------------------------------------+----------------------------------------------------------
|
||||
SELECT $1 AS num /* { "application", psql_app, "real_ip", 192.168.1.3) */ | /* { "application", psql_app, "real_ip", 192.168.1.3) */
|
||||
SELECT pg_stat_monitor_reset(); |
|
||||
SELECT query, comments FROM pg_stat_monitor ORDER BY query COLLATE "C"; |
|
||||
SELECT pg_stat_monitor_reset() |
|
||||
SELECT query, comments FROM pg_stat_monitor ORDER BY query COLLATE "C" |
|
||||
(3 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -23,23 +23,23 @@ SELECT add2(1,2);
|
|||
(1 row)
|
||||
|
||||
SELECT query, top_query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | top_query
|
||||
--------------------------------------------------------------------------+--------------------
|
||||
CREATE OR REPLACE FUNCTION add(int, int) RETURNS INTEGER AS +|
|
||||
$$ +|
|
||||
BEGIN +|
|
||||
return (select $1 + $2); +|
|
||||
END; $$ language plpgsql; |
|
||||
CREATE OR REPLACE function add2(int, int) RETURNS int as +|
|
||||
$$ +|
|
||||
BEGIN +|
|
||||
return add($1,$2); +|
|
||||
END; +|
|
||||
$$ language plpgsql; |
|
||||
SELECT (select $1 + $2) | SELECT add2($1,$2)
|
||||
SELECT add2($1,$2) |
|
||||
SELECT pg_stat_monitor_reset(); |
|
||||
SELECT query, top_query FROM pg_stat_monitor ORDER BY query COLLATE "C"; |
|
||||
query | top_query
|
||||
-------------------------------------------------------------------------+--------------------
|
||||
CREATE OR REPLACE FUNCTION add(int, int) RETURNS INTEGER AS +|
|
||||
$$ +|
|
||||
BEGIN +|
|
||||
return (select $1 + $2); +|
|
||||
END; $$ language plpgsql |
|
||||
CREATE OR REPLACE function add2(int, int) RETURNS int as +|
|
||||
$$ +|
|
||||
BEGIN +|
|
||||
return add($1,$2); +|
|
||||
END; +|
|
||||
$$ language plpgsql |
|
||||
SELECT (select $1 + $2) | SELECT add2($1,$2)
|
||||
SELECT add2($1,$2) |
|
||||
SELECT pg_stat_monitor_reset() |
|
||||
SELECT query, top_query FROM pg_stat_monitor ORDER BY query COLLATE "C" |
|
||||
(6 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -23,23 +23,23 @@ SELECT add2(1,2);
|
|||
(1 row)
|
||||
|
||||
SELECT query, top_query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
query | top_query
|
||||
--------------------------------------------------------------------------+--------------------
|
||||
(select $1 + $2) | SELECT add2($1,$2)
|
||||
CREATE OR REPLACE FUNCTION add(int, int) RETURNS INTEGER AS +|
|
||||
$$ +|
|
||||
BEGIN +|
|
||||
return (select $1 + $2); +|
|
||||
END; $$ language plpgsql; |
|
||||
CREATE OR REPLACE function add2(int, int) RETURNS int as +|
|
||||
$$ +|
|
||||
BEGIN +|
|
||||
return add($1,$2); +|
|
||||
END; +|
|
||||
$$ language plpgsql; |
|
||||
SELECT add2($1,$2) |
|
||||
SELECT pg_stat_monitor_reset(); |
|
||||
SELECT query, top_query FROM pg_stat_monitor ORDER BY query COLLATE "C"; |
|
||||
query | top_query
|
||||
-------------------------------------------------------------------------+--------------------
|
||||
(select $1 + $2) | SELECT add2($1,$2)
|
||||
CREATE OR REPLACE FUNCTION add(int, int) RETURNS INTEGER AS +|
|
||||
$$ +|
|
||||
BEGIN +|
|
||||
return (select $1 + $2); +|
|
||||
END; $$ language plpgsql |
|
||||
CREATE OR REPLACE function add2(int, int) RETURNS int as +|
|
||||
$$ +|
|
||||
BEGIN +|
|
||||
return add($1,$2); +|
|
||||
END; +|
|
||||
$$ language plpgsql |
|
||||
SELECT add2($1,$2) |
|
||||
SELECT pg_stat_monitor_reset() |
|
||||
SELECT query, top_query FROM pg_stat_monitor ORDER BY query COLLATE "C" |
|
||||
(6 rows)
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
Create EXTENSION pg_stat_monitor;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
Set application_name = 'naeem' ;
|
||||
SELECT 1 AS num;
|
||||
Set application_name = 'psql' ;
|
||||
SELECT 1 AS num;
|
||||
SELECT query,application_name FROM pg_stat_monitor ORDER BY query, application_name COLLATE "C";
|
||||
SELECT pg_stat_monitor_reset();
|
||||
DROP EXTENSION pg_stat_monitor;
|
|
@ -0,0 +1,17 @@
|
|||
Drop Table if exists Company;
|
||||
|
||||
CREATE TABLE Company(
|
||||
ID INT PRIMARY KEY NOT NULL,
|
||||
NAME TEXT NOT NULL
|
||||
);
|
||||
|
||||
|
||||
CREATE EXTENSION pg_stat_monitor;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
INSERT INTO Company(ID, Name) VALUES (1, 'Percona');
|
||||
INSERT INTO Company(ID, Name) VALUES (1, 'Percona');
|
||||
|
||||
Drop Table if exists Company;
|
||||
SELECT query, elevel, sqlcode, message FROM pg_stat_monitor ORDER BY query COLLATE "C",elevel;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
DROP EXTENSION pg_stat_monitor;
|
|
@ -1,28 +1,39 @@
|
|||
CREATE OR REPLACE FUNCTION generate_histogram()
|
||||
RETURNS TABLE (
|
||||
range TEXT, freq INT, bar TEXT
|
||||
) AS $$
|
||||
Declare
|
||||
bucket_id integer;
|
||||
query_id text;
|
||||
BEGIN
|
||||
select bucket into bucket_id from pg_stat_monitor order by calls desc limit 1;
|
||||
select queryid into query_id from pg_stat_monitor order by calls desc limit 1;
|
||||
--RAISE INFO 'bucket_id %', bucket_id;
|
||||
--RAISE INFO 'query_id %', query_id;
|
||||
return query
|
||||
SELECT * FROM histogram(bucket_id, query_id) AS a(range TEXT, freq INT, bar TEXT);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION run_pg_sleep(INTEGER) RETURNS VOID AS $$
|
||||
DECLARE
|
||||
loops ALIAS FOR $1;
|
||||
BEGIN
|
||||
FOR i IN 1..loops LOOP
|
||||
--RAISE INFO 'Current timestamp: %', timeofday()::TIMESTAMP;
|
||||
RAISE INFO 'Sleep % seconds', i;
|
||||
PERFORM pg_sleep(i);
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' STRICT;
|
||||
|
||||
CREATE EXTENSION pg_stat_monitor;
|
||||
|
||||
CREATE TABLE t1(a int);
|
||||
|
||||
SELECT pg_stat_monitor_reset();
|
||||
Set pg_stat_monitor.track='all';
|
||||
select run_pg_sleep(5);
|
||||
|
||||
INSERT INTO t1 VALUES(generate_series(1,10));
|
||||
ANALYZE t1;
|
||||
SELECT count(*) FROM t1;
|
||||
SELECT substr(query, 0,50) as query, calls, resp_calls FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
|
||||
INSERT INTO t1 VALUES(generate_series(1,10000));
|
||||
ANALYZE t1;
|
||||
SELECT count(*) FROM t1;;
|
||||
select * from generate_histogram();
|
||||
|
||||
INSERT INTO t1 VALUES(generate_series(1,1000000));
|
||||
ANALYZE t1;
|
||||
SELECT count(*) FROM t1;
|
||||
|
||||
INSERT INTO t1 VALUES(generate_series(1,10000000));
|
||||
ANALYZE t1;
|
||||
SELECT count(*) FROM t1;
|
||||
|
||||
SELECT query, calls, min_time, max_time, resp_calls FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||
SELECT * FROM histogram(0, 'F44CD1B4B33A47AF') AS a(range TEXT, freq INT, bar TEXT);
|
||||
|
||||
DROP TABLE t1;
|
||||
SELECT pg_stat_monitor_reset();
|
||||
DROP EXTENSION pg_stat_monitor;
|
||||
|
|
|
@ -13,6 +13,8 @@ URL: https://github.com/Percona-Lab/pg_stat_monitor
|
|||
BuildRequires: percona-postgresql%{pgrel}-devel
|
||||
Requires: postgresql-server
|
||||
Provides: percona-pg-stat-monitor%{pgrel}
|
||||
Conflicts: percona-pg-stat-monitor%{pgrel}
|
||||
Obsoletes: percona-pg-stat-monitor%{pgrel}
|
||||
Epoch: 1
|
||||
Packager: Percona Development Team <https://jira.percona.com>
|
||||
Vendor: Percona, Inc
|
Loading…
Reference in New Issue