[PG-810] PG-17 Support (#463)
* Temporary disable all workflows * Add build workflow with PG17 * Fix incompatibilities * Fix 007_settings_pgsm_query_shared_buffer.pl test * Fix 018_column_names.pl * Fix 025_compare_pgss.pl * Remove tuplestore_donestoring usage at all * Rename I/O timing statistics columns to shared_blk_{read|write}_time * Fix comments with fileds numbers * Fix format * Revert "Temporary disable all workflows" This reverts commitpull/476/head12e75beb63
. * Disable all workflows except check and build for PG 15, 16 and 17 * Fix * Fix comments * Fix migration * Use REL_17_BETA1 in CI * Add timers tests to 028_temp_block.pl * Add local blocks timing statistics columns local_blk_{write|read}_time * Fix t/027_local_blocks.pl test for older PG versions * Fix * Add jit_deform_{count|time} metrics * Fix * Add stats_since and minmax_stats_since fields * Revert "Disable all workflows except check and build for PG 15, 16 and 17" This reverts commit73febf3aee
. * Fix t/028_temp_block.pl for PG14 and below * Fix build for PG12 * Add pgdg workflow for PG17 * Try to fix PG pgdg workflow * Fixes and formatting * Format code * Add level tracking regression test * Fix nesting level tracking * Format code * Add level tracking test expected result for PG13 * Fix for PG12 * Skip level tracking regression test for PG version less than 14 * Fix toplevel calculation for older PG version * Fix level tracking test results * Fix nesting level counting for older PG version * Revert "Fix nesting level counting for older PG version" This reverts commit3e91da8010
. * Fix level tracking for older PG versions once again * Set REL_17_BETA2 tag for PG * Add CI badge for PG17 * Use PG17 for examples in readme
parent
c796995e0c
commit
dacb41f9e4
|
@ -0,0 +1,147 @@
|
||||||
|
name: postgresql-17-build
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
tags:
|
||||||
|
- '[0-9]+.[0-9]+.[0-9]+*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: pg-17-build-test
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Clone postgres repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: 'postgres/postgres'
|
||||||
|
ref: 'REL_17_BETA2' # TODO: Replace with REL_17_STABLE
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt purge postgresql-client-common postgresql-common \
|
||||||
|
postgresql postgresql*
|
||||||
|
sudo apt-get install -y libreadline6-dev systemtap-sdt-dev \
|
||||||
|
zlib1g-dev libssl-dev libpam0g-dev bison flex \
|
||||||
|
libipc-run-perl -y docbook-xsl docbook-xsl libxml2 libxml2-utils \
|
||||||
|
libxml2-dev libxslt-dev xsltproc libkrb5-dev libldap2-dev \
|
||||||
|
libsystemd-dev gettext tcl-dev libperl-dev pkg-config clang-11 \
|
||||||
|
llvm-11 llvm-11-dev libselinux1-dev python3-dev \
|
||||||
|
uuid-dev liblz4-dev
|
||||||
|
sudo rm -rf /var/lib/postgresql /var/log/postgresql /etc/postgresql \
|
||||||
|
/usr/lib/postgresql /usr/include/postgresql /usr/share/postgresql \
|
||||||
|
/etc/postgresql
|
||||||
|
sudo rm -f /usr/bin/pg_config
|
||||||
|
sudo /usr/bin/perl -MCPAN -e 'install IPC::Run'
|
||||||
|
sudo /usr/bin/perl -MCPAN -e 'install Text::Trim'
|
||||||
|
|
||||||
|
- name: Create pgsql dir
|
||||||
|
run: mkdir -p /opt/pgsql
|
||||||
|
|
||||||
|
- name: Build postgres
|
||||||
|
run: |
|
||||||
|
export PATH="/opt/pgsql/bin:$PATH"
|
||||||
|
./configure '--build=x86_64-linux-gnu' '--prefix=/usr' \
|
||||||
|
'--includedir=${prefix}/include' '--mandir=${prefix}/share/man' \
|
||||||
|
'--infodir=${prefix}/share/info' '--sysconfdir=/etc' \
|
||||||
|
'--localstatedir=/var' '--libdir=${prefix}/lib/x86_64-linux-gnu' \
|
||||||
|
'--libexecdir=${prefix}/lib/x86_64-linux-gnu' '--with-icu' \
|
||||||
|
'--with-tcl' '--with-perl' '--with-python' '--with-pam' \
|
||||||
|
'--with-openssl' '--with-libxml' '--with-libxslt' '--with-ldap' \
|
||||||
|
'PYTHON=/usr/bin/python3' '--mandir=/usr/share/postgresql/17/man' \
|
||||||
|
'--docdir=/usr/share/doc/postgresql-doc-17' '--with-pgport=5432' \
|
||||||
|
'--sysconfdir=/etc/postgresql-common' '--datarootdir=/usr/share' \
|
||||||
|
'--datadir=/usr/share/postgresql/17' '--with-uuid=e2fs' \
|
||||||
|
'--bindir=/usr/lib/postgresql/17/bin' '--enable-tap-tests' \
|
||||||
|
'--libdir=/usr/lib/x86_64-linux-gnu' '--enable-debug' \
|
||||||
|
'--libexecdir=/usr/lib/postgresql' '--with-gnu-ld' \
|
||||||
|
'--includedir=/usr/include/postgresql' '--enable-dtrace' \
|
||||||
|
'--enable-nls' '--enable-thread-safety' '--disable-rpath' \
|
||||||
|
'--with-system-tzdata=/usr/share/zoneinfo' '--with-llvm' \
|
||||||
|
'LLVM_CONFIG=/usr/bin/llvm-config-11' 'CLANG=/usr/bin/clang-11' \
|
||||||
|
'--with-systemd' '--with-selinux' 'MKDIR_P=/bin/mkdir -p' \
|
||||||
|
'PROVE=/usr/bin/prove' 'TAR=/bin/tar' 'XSLTPROC=xsltproc --nonet' \
|
||||||
|
'LDFLAGS=-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now' \
|
||||||
|
'build_alias=x86_64-linux-gnu' '--with-gssapi' \
|
||||||
|
'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2' \
|
||||||
|
'CFLAGS=-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer' \
|
||||||
|
'CXXFLAGS=-g -O2 -fstack-protector-strong -Wformat -Werror=format-security'
|
||||||
|
make world
|
||||||
|
sudo make install-world
|
||||||
|
|
||||||
|
- name: Start postgresql cluster
|
||||||
|
run: |
|
||||||
|
export PATH="/usr/lib/postgresql/17/bin:$PATH"
|
||||||
|
sudo cp /usr/lib/postgresql/17/bin/pg_config /usr/bin
|
||||||
|
initdb -D /opt/pgsql/data
|
||||||
|
pg_ctl -D /opt/pgsql/data -l logfile start
|
||||||
|
|
||||||
|
- name: Clone pg_stat_monitor repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
path: 'src/pg_stat_monitor'
|
||||||
|
|
||||||
|
- name: Build pg_stat_monitor
|
||||||
|
run: |
|
||||||
|
make USE_PGXS=1
|
||||||
|
sudo make USE_PGXS=1 install
|
||||||
|
working-directory: src/pg_stat_monitor
|
||||||
|
|
||||||
|
- name: Configure and Restart Server
|
||||||
|
run: |
|
||||||
|
export PATH="/usr/lib/postgresql/17/bin:$PATH"
|
||||||
|
pg_ctl -D /opt/pgsql/data -l logfile stop
|
||||||
|
echo "shared_preload_libraries = 'pg_stat_monitor'" >> \
|
||||||
|
/opt/pgsql/data/postgresql.conf
|
||||||
|
echo "compute_query_id = regress" >> /opt/pgsql/data/postgresql.conf
|
||||||
|
pg_ctl -D /opt/pgsql/data -l logfile start
|
||||||
|
working-directory: src/pg_stat_monitor
|
||||||
|
|
||||||
|
- name: Start pg_stat_monitor_tests
|
||||||
|
run: |
|
||||||
|
make installcheck
|
||||||
|
working-directory: src/pg_stat_monitor/
|
||||||
|
|
||||||
|
- name: Change dir permissions on fail
|
||||||
|
if: ${{ failure() }}
|
||||||
|
run: |
|
||||||
|
sudo chmod -R ugo+rwx t
|
||||||
|
sudo chmod -R ugo+rwx tmp_check
|
||||||
|
exit 2 # regenerate error so that we can upload files in next step
|
||||||
|
working-directory: src/pg_stat_monitor
|
||||||
|
|
||||||
|
- name: Upload logs on fail
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: Regressions diff and postgresql log
|
||||||
|
path: |
|
||||||
|
src/pg_stat_monitor/regression.diffs
|
||||||
|
src/pg_stat_monitor/regression.out
|
||||||
|
src/pg_stat_monitor/logfile
|
||||||
|
src/pg_stat_monitor/t/results/
|
||||||
|
src/pg_stat_monitor/tmp_check/log/
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/archives/*
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/backup/*
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/pgdata/*
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/archives/
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/backup/
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/pgdata/
|
||||||
|
if-no-files-found: warn
|
||||||
|
retention-days: 3
|
||||||
|
|
||||||
|
- name: Start Server installcheck-world tests
|
||||||
|
run: make installcheck-world
|
||||||
|
|
||||||
|
- name: Report on installcheck-world test suites fail
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: ${{ failure() }}
|
||||||
|
with:
|
||||||
|
name: Regressions output files of failed testsuite, and pg log
|
||||||
|
path: |
|
||||||
|
**/regression.diffs
|
||||||
|
**/regression.out
|
||||||
|
src/pg_stat_monitor/logfile
|
||||||
|
retention-days: 3
|
|
@ -0,0 +1,93 @@
|
||||||
|
name: postgresql-17-pgdg-package
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
tags:
|
||||||
|
- '[0-9]+.[0-9]+.[0-9]+*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: pg-17-pgdg-package-test
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Clone pg_stat_monitor repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
path: 'src/pg_stat_monitor'
|
||||||
|
|
||||||
|
- name: Delete old postgresql files
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt purge postgresql-client-common postgresql-common \
|
||||||
|
postgresql postgresql*
|
||||||
|
sudo apt-get install -y libreadline6-dev systemtap-sdt-dev wget \
|
||||||
|
zlib1g-dev libssl-dev libpam0g-dev bison flex libipc-run-perl
|
||||||
|
sudo rm -rf /var/lib/postgresql /var/log/postgresql /etc/postgresql \
|
||||||
|
/usr/lib/postgresql /usr/include/postgresql /usr/share/postgresql \
|
||||||
|
/etc/postgresql
|
||||||
|
sudo rm -f /usr/bin/pg_config
|
||||||
|
sudo /usr/bin/perl -MCPAN -e 'install IPC::Run'
|
||||||
|
sudo /usr/bin/perl -MCPAN -e 'install Text::Trim'
|
||||||
|
|
||||||
|
- name: Install PG Distribution Postgresql 17
|
||||||
|
run: |
|
||||||
|
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt \
|
||||||
|
$(lsb_release -cs)-pgdg main 17" > /etc/apt/sources.list.d/pgdg.list'
|
||||||
|
sudo wget --quiet -O - \
|
||||||
|
https://www.postgresql.org/media/keys/ACCC4CF8.asc |
|
||||||
|
sudo apt-key add -
|
||||||
|
sudo apt update
|
||||||
|
sudo apt -y install postgresql-17 postgresql-server-dev-17
|
||||||
|
|
||||||
|
- name: Change src owner to postgres
|
||||||
|
run: |
|
||||||
|
sudo chmod o+rx ~
|
||||||
|
sudo chown -R postgres:postgres src
|
||||||
|
|
||||||
|
- name: Build pg_stat_monitor
|
||||||
|
run: |
|
||||||
|
sudo -u postgres bash -c 'make USE_PGXS=1'
|
||||||
|
sudo make USE_PGXS=1 install
|
||||||
|
working-directory: src/pg_stat_monitor
|
||||||
|
|
||||||
|
- name: Start pg_stat_monitor_tests
|
||||||
|
run: |
|
||||||
|
sudo service postgresql stop
|
||||||
|
echo "shared_preload_libraries = 'pg_stat_monitor'" |
|
||||||
|
sudo tee -a /etc/postgresql/17/main/postgresql.conf
|
||||||
|
sudo service postgresql start
|
||||||
|
sudo psql -V
|
||||||
|
export PG_TEST_PORT_DIR=${GITHUB_WORKSPACE}/src/pg_stat_monitor
|
||||||
|
echo $PG_TEST_PORT_DIR
|
||||||
|
sudo -E -u postgres bash -c 'make installcheck USE_PGXS=1'
|
||||||
|
working-directory: src/pg_stat_monitor
|
||||||
|
|
||||||
|
- name: Change dir permissions on fail
|
||||||
|
if: ${{ failure() }}
|
||||||
|
run: |
|
||||||
|
sudo chmod -R ugo+rwx t
|
||||||
|
sudo chmod -R ugo+rwx tmp_check
|
||||||
|
exit 2 # regenerate error so that we can upload files in next step
|
||||||
|
working-directory: src/pg_stat_monitor
|
||||||
|
|
||||||
|
- name: Upload logs on fail
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: Regressions diff and postgresql log
|
||||||
|
path: |
|
||||||
|
src/pg_stat_monitor/regression.diffs
|
||||||
|
src/pg_stat_monitor/regression.out
|
||||||
|
src/pg_stat_monitor/logfile
|
||||||
|
src/pg_stat_monitor/t/results/
|
||||||
|
src/pg_stat_monitor/tmp_check/log/
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/archives/*
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/backup/*
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/pgdata/*
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/archives/
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/backup/
|
||||||
|
!src/pg_stat_monitor/tmp_check/**/pgdata/
|
||||||
|
if-no-files-found: warn
|
||||||
|
retention-days: 3
|
4
Makefile
4
Makefile
|
@ -4,7 +4,7 @@ MODULE_big = pg_stat_monitor
|
||||||
OBJS = hash_query.o guc.o pg_stat_monitor.o $(WIN32RES)
|
OBJS = hash_query.o guc.o pg_stat_monitor.o $(WIN32RES)
|
||||||
|
|
||||||
EXTENSION = pg_stat_monitor
|
EXTENSION = pg_stat_monitor
|
||||||
DATA = pg_stat_monitor--2.0.sql pg_stat_monitor--1.0--2.0.sql
|
DATA = pg_stat_monitor--2.0.sql pg_stat_monitor--1.0--2.0.sql pg_stat_monitor--2.0--2.1.sql
|
||||||
|
|
||||||
PGFILEDESC = "pg_stat_monitor - execution statistics of SQL statements"
|
PGFILEDESC = "pg_stat_monitor - execution statistics of SQL statements"
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ LDFLAGS_SL += $(filter -lm, $(LIBS))
|
||||||
|
|
||||||
TAP_TESTS = 1
|
TAP_TESTS = 1
|
||||||
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf --inputdir=regression
|
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_monitor/pg_stat_monitor.conf --inputdir=regression
|
||||||
REGRESS = basic version guc pgsm_query_id functions counters relations database error_insert application_name application_name_unique top_query cmd_type error rows tags user
|
REGRESS = basic version guc pgsm_query_id functions counters relations database error_insert application_name application_name_unique top_query cmd_type error rows tags user level_tracking
|
||||||
|
|
||||||
# Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
|
# Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
|
||||||
# which typical installcheck users do not have (e.g. buildfarm clients).
|
# which typical installcheck users do not have (e.g. buildfarm clients).
|
||||||
|
|
21
README.md
21
README.md
|
@ -3,6 +3,7 @@
|
||||||
[](https://github.com/percona/pg_stat_monitor/actions/workflows/postgresql-14-pgdg-package.yml)
|
[](https://github.com/percona/pg_stat_monitor/actions/workflows/postgresql-14-pgdg-package.yml)
|
||||||
[](https://github.com/percona/pg_stat_monitor/actions/workflows/postgresql-15-pgdg-package.yml)
|
[](https://github.com/percona/pg_stat_monitor/actions/workflows/postgresql-15-pgdg-package.yml)
|
||||||
[](https://github.com/percona/pg_stat_monitor/actions/workflows/postgresql-16-pgdg-package.yml)
|
[](https://github.com/percona/pg_stat_monitor/actions/workflows/postgresql-16-pgdg-package.yml)
|
||||||
|
[](https://github.com/percona/pg_stat_monitor/actions/workflows/postgresql-17-pgdg-package.yml)
|
||||||
|
|
||||||
[](https://badge.fury.io/pg/pg_stat_monitor)
|
[](https://badge.fury.io/pg/pg_stat_monitor)
|
||||||
[](https://codecov.io/gh/percona/pg_stat_monitor)
|
[](https://codecov.io/gh/percona/pg_stat_monitor)
|
||||||
|
@ -51,7 +52,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).
|
`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 [12](https://www.percona.com/downloads/postgresql-distribution-12/LATEST/), [13](https://www.percona.com/downloads/postgresql-distribution-13/LATEST/), [14](https://www.percona.com/downloads/postgresql-distribution-14/LATEST/), [15](https://www.percona.com/downloads/postgresql-distribution-15/LATEST/) and [16](https://www.percona.com/downloads/postgresql-distribution-16/LATEST/).
|
The `RPM` (for RHEL and CentOS) and the `DEB` (for Debian and Ubuntu) packages are available from Percona repositories for PostgreSQL versions [12](https://www.percona.com/downloads/postgresql-distribution-12/LATEST/), [13](https://www.percona.com/downloads/postgresql-distribution-13/LATEST/), [14](https://www.percona.com/downloads/postgresql-distribution-14/LATEST/), [15](https://www.percona.com/downloads/postgresql-distribution-15/LATEST/), [16](https://www.percona.com/downloads/postgresql-distribution-16/LATEST/) and [17](https://www.percona.com/downloads/postgresql-distribution-17/LATEST/).
|
||||||
|
|
||||||
The RPM packages are also available in the official PostgreSQL (PGDG) yum repositories.
|
The RPM packages are also available in the official PostgreSQL (PGDG) yum repositories.
|
||||||
|
|
||||||
|
@ -61,8 +62,8 @@ The `pg_stat_monitor` should work on the latest version of both [Percona Distrib
|
||||||
|
|
||||||
| **Distribution** | **Version** | **Provider** |
|
| **Distribution** | **Version** | **Provider** |
|
||||||
| ---------------- | --------------- | ------------ |
|
| ---------------- | --------------- | ------------ |
|
||||||
|[Percona Distribution for PostgreSQL](https://www.percona.com/software/postgresql-distribution)| [12](https://www.percona.com/downloads/postgresql-distribution-12/LATEST/), [13](https://www.percona.com/downloads/postgresql-distribution-13/LATEST/), [14](https://www.percona.com/downloads/postgresql-distribution-14/LATEST/), [15](https://www.percona.com/downloads/postgresql-distribution-15/LATEST/) and [16](https://www.percona.com/downloads/postgresql-distribution-16/LATEST/)| Percona|
|
|[Percona Distribution for PostgreSQL](https://www.percona.com/software/postgresql-distribution)| [12](https://www.percona.com/downloads/postgresql-distribution-12/LATEST/), [13](https://www.percona.com/downloads/postgresql-distribution-13/LATEST/), [14](https://www.percona.com/downloads/postgresql-distribution-14/LATEST/), [15](https://www.percona.com/downloads/postgresql-distribution-15/LATEST/), [16](https://www.percona.com/downloads/postgresql-distribution-16/LATEST/) and [17](https://www.percona.com/downloads/postgresql-distribution-17/LATEST/)| Percona|
|
||||||
| PostgreSQL | 12, 13, 14, 15 and 16 | PostgreSQL Global Development Group (PGDG) |
|
| PostgreSQL | 12, 13, 14, 15, 16 and 17 | PostgreSQL Global Development Group (PGDG) |
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
@ -121,16 +122,16 @@ To install `pg_stat_monitor` from Percona repositories, you need to use the `per
|
||||||
percona-release setup ppg-XX
|
percona-release setup ppg-XX
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace XX with the desired PostgreSQL version. For example, to install `pg_stat_monitor ` for PostgreSQL 16, specify `ppg-16`.
|
Replace XX with the desired PostgreSQL version. For example, to install `pg_stat_monitor ` for PostgreSQL 17, specify `ppg-17`.
|
||||||
|
|
||||||
3. Install `pg_stat_monitor` package
|
3. Install `pg_stat_monitor` package
|
||||||
* For Debian and Ubuntu:
|
* For Debian and Ubuntu:
|
||||||
``` sh
|
``` sh
|
||||||
apt-get install percona-pg-stat-monitor16
|
apt-get install percona-pg-stat-monitor17
|
||||||
```
|
```
|
||||||
* For RHEL and CentOS:
|
* For RHEL and CentOS:
|
||||||
``` sh
|
``` sh
|
||||||
yum install percona-pg-stat-monitor16
|
yum install percona-pg-stat-monitor17
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Installing from PostgreSQL `yum` repositories
|
#### Installing from PostgreSQL `yum` repositories
|
||||||
|
@ -143,7 +144,7 @@ Install `pg_stat_monitor`:
|
||||||
dnf install -y pg_stat_monitor_<VERSION>
|
dnf install -y pg_stat_monitor_<VERSION>
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace the `VERSION` variable with the PostgreSQL version you are using (e.g. specify `pg_stat_monitor_16` for PostgreSQL 16)
|
Replace the `VERSION` variable with the PostgreSQL version you are using (e.g. specify `pg_stat_monitor_17` for PostgreSQL 17)
|
||||||
|
|
||||||
|
|
||||||
#### Installing from PGXN
|
#### Installing from PGXN
|
||||||
|
@ -204,7 +205,7 @@ sudo systemctl restart postgresql.service
|
||||||
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo systemctl restart postgresql-16
|
sudo systemctl restart postgresql-17
|
||||||
```
|
```
|
||||||
|
|
||||||
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:
|
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:
|
||||||
|
@ -280,7 +281,7 @@ To uninstall `pg_stat_monitor`, do the following:
|
||||||
|
|
||||||
**Important**: If the `shared_preload_libraries` parameter includes other modules, specify them all for the `ALTER SYSTEM SET` command to keep using them.
|
**Important**: If the `shared_preload_libraries` parameter includes other modules, specify them all for the `ALTER SYSTEM SET` command to keep using them.
|
||||||
|
|
||||||
3. Restart the `postgresql` instance to apply the changes. The following command restarts PostgreSQL 16. Replace the version value with the one you are using.
|
3. Restart the `postgresql` instance to apply the changes. The following command restarts PostgreSQL 17. Replace the version value with the one you are using.
|
||||||
|
|
||||||
* On Debian and Ubuntu:
|
* On Debian and Ubuntu:
|
||||||
|
|
||||||
|
@ -292,7 +293,7 @@ To uninstall `pg_stat_monitor`, do the following:
|
||||||
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo systemctl restart postgresql-16
|
sudo systemctl restart postgresql-17
|
||||||
```
|
```
|
||||||
|
|
||||||
### How we work
|
### How we work
|
||||||
|
|
|
@ -303,6 +303,8 @@ hash_entry_alloc(pgsmSharedState * pgsm, pgsmHashKey * key, int encoding)
|
||||||
memset(&entry->counters, 0, sizeof(Counters));
|
memset(&entry->counters, 0, sizeof(Counters));
|
||||||
entry->query_text.query_pos = InvalidDsaPointer;
|
entry->query_text.query_pos = InvalidDsaPointer;
|
||||||
entry->counters.info.parent_query = InvalidDsaPointer;
|
entry->counters.info.parent_query = InvalidDsaPointer;
|
||||||
|
entry->stats_since = GetCurrentTimestamp();
|
||||||
|
entry->minmax_stats_since = entry->stats_since;
|
||||||
|
|
||||||
/* set the appropriate initial usage count */
|
/* set the appropriate initial usage count */
|
||||||
/* re-initialize the mutex each time ... we assume no one using it */
|
/* re-initialize the mutex each time ... we assume no one using it */
|
||||||
|
|
|
@ -0,0 +1,497 @@
|
||||||
|
/* contrib/pg_stat_monitor/pg_stat_monitor--2.0--2.1.sql */
|
||||||
|
|
||||||
|
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||||
|
\echo Use "ALTER EXTENSION pg_stat_monitor" to load this file. \quit
|
||||||
|
|
||||||
|
DROP FUNCTION pg_stat_monitor_internal CASCADE;
|
||||||
|
DROP FUNCTION pgsm_create_view CASCADE;
|
||||||
|
DROP FUNCTION pgsm_create_11_view();
|
||||||
|
DROP FUNCTION pgsm_create_13_view();
|
||||||
|
DROP FUNCTION pgsm_create_14_view();
|
||||||
|
DROP FUNCTION pgsm_create_15_view();
|
||||||
|
|
||||||
|
CREATE FUNCTION pg_stat_monitor_internal(
|
||||||
|
IN showtext boolean,
|
||||||
|
OUT bucket int8, -- 0
|
||||||
|
OUT userid oid,
|
||||||
|
OUT username text,
|
||||||
|
OUT dbid oid,
|
||||||
|
OUT datname text,
|
||||||
|
OUT client_ip int8,
|
||||||
|
|
||||||
|
OUT queryid int8, -- 6
|
||||||
|
OUT planid int8,
|
||||||
|
OUT query text,
|
||||||
|
OUT query_plan text,
|
||||||
|
OUT pgsm_query_id int8,
|
||||||
|
OUT top_queryid int8,
|
||||||
|
OUT top_query text,
|
||||||
|
OUT application_name text,
|
||||||
|
|
||||||
|
OUT relations text, -- 14
|
||||||
|
OUT cmd_type int,
|
||||||
|
OUT elevel int,
|
||||||
|
OUT sqlcode TEXT,
|
||||||
|
OUT message text,
|
||||||
|
OUT bucket_start_time timestamptz,
|
||||||
|
|
||||||
|
OUT calls int8, -- 20
|
||||||
|
|
||||||
|
OUT total_exec_time float8, -- 21
|
||||||
|
OUT min_exec_time float8,
|
||||||
|
OUT max_exec_time float8,
|
||||||
|
OUT mean_exec_time float8,
|
||||||
|
OUT stddev_exec_time float8,
|
||||||
|
|
||||||
|
OUT rows int8, -- 26
|
||||||
|
|
||||||
|
OUT plans int8, -- 27
|
||||||
|
|
||||||
|
OUT total_plan_time float8, -- 28
|
||||||
|
OUT min_plan_time float8,
|
||||||
|
OUT max_plan_time float8,
|
||||||
|
OUT mean_plan_time float8,
|
||||||
|
OUT stddev_plan_time float8,
|
||||||
|
|
||||||
|
OUT shared_blks_hit int8, -- 33
|
||||||
|
OUT shared_blks_read int8,
|
||||||
|
OUT shared_blks_dirtied int8,
|
||||||
|
OUT shared_blks_written int8,
|
||||||
|
OUT local_blks_hit int8,
|
||||||
|
OUT local_blks_read int8,
|
||||||
|
OUT local_blks_dirtied int8,
|
||||||
|
OUT local_blks_written int8,
|
||||||
|
OUT temp_blks_read int8,
|
||||||
|
OUT temp_blks_written int8,
|
||||||
|
OUT shared_blk_read_time float8,
|
||||||
|
OUT shared_blk_write_time float8,
|
||||||
|
OUT local_blk_read_time float8,
|
||||||
|
OUT local_blk_write_time float8,
|
||||||
|
OUT temp_blk_read_time float8,
|
||||||
|
OUT temp_blk_write_time float8,
|
||||||
|
|
||||||
|
OUT resp_calls text, -- 49
|
||||||
|
OUT cpu_user_time float8,
|
||||||
|
OUT cpu_sys_time float8,
|
||||||
|
OUT wal_records int8,
|
||||||
|
OUT wal_fpi int8,
|
||||||
|
OUT wal_bytes numeric,
|
||||||
|
OUT comments TEXT,
|
||||||
|
|
||||||
|
OUT jit_functions int8, -- 56
|
||||||
|
OUT jit_generation_time float8,
|
||||||
|
OUT jit_inlining_count int8,
|
||||||
|
OUT jit_inlining_time float8,
|
||||||
|
OUT jit_optimization_count int8,
|
||||||
|
OUT jit_optimization_time float8,
|
||||||
|
OUT jit_emission_count int8,
|
||||||
|
OUT jit_emission_time float8,
|
||||||
|
OUT jit_deform_count int8,
|
||||||
|
OUT jit_deform_time float8,
|
||||||
|
|
||||||
|
OUT stats_since timestamp with time zone, -- 66
|
||||||
|
OUT minmax_stats_since timestamp with time zone,
|
||||||
|
|
||||||
|
OUT toplevel BOOLEAN, -- 68
|
||||||
|
OUT bucket_done BOOLEAN
|
||||||
|
)
|
||||||
|
RETURNS SETOF record
|
||||||
|
AS 'MODULE_PATHNAME', 'pg_stat_monitor_2_1'
|
||||||
|
LANGUAGE C STRICT VOLATILE PARALLEL SAFE;
|
||||||
|
|
||||||
|
-- Register a view on the function for ease of use.
|
||||||
|
CREATE FUNCTION pgsm_create_11_view() RETURNS INT AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
CREATE VIEW pg_stat_monitor AS SELECT
|
||||||
|
bucket,
|
||||||
|
bucket_start_time AS bucket_start_time,
|
||||||
|
userid,
|
||||||
|
username,
|
||||||
|
dbid,
|
||||||
|
datname,
|
||||||
|
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||||
|
pgsm_query_id,
|
||||||
|
queryid,
|
||||||
|
top_queryid,
|
||||||
|
query,
|
||||||
|
comments,
|
||||||
|
planid,
|
||||||
|
query_plan,
|
||||||
|
top_query,
|
||||||
|
application_name,
|
||||||
|
string_to_array(relations, ',') AS relations,
|
||||||
|
cmd_type,
|
||||||
|
get_cmd_type(cmd_type) AS cmd_type_text,
|
||||||
|
elevel,
|
||||||
|
sqlcode,
|
||||||
|
message,
|
||||||
|
calls,
|
||||||
|
total_exec_time AS total_time,
|
||||||
|
min_exec_time AS min_time,
|
||||||
|
max_exec_time AS max_time,
|
||||||
|
mean_exec_time AS mean_time,
|
||||||
|
stddev_exec_time AS stddev_time,
|
||||||
|
rows,
|
||||||
|
shared_blks_hit,
|
||||||
|
shared_blks_read,
|
||||||
|
shared_blks_dirtied,
|
||||||
|
shared_blks_written,
|
||||||
|
local_blks_hit,
|
||||||
|
local_blks_read,
|
||||||
|
local_blks_dirtied,
|
||||||
|
local_blks_written,
|
||||||
|
temp_blks_read,
|
||||||
|
temp_blks_written,
|
||||||
|
shared_blk_read_time AS blk_read_time,
|
||||||
|
shared_blk_write_time AS blk_write_time,
|
||||||
|
(string_to_array(resp_calls, ',')) resp_calls,
|
||||||
|
cpu_user_time,
|
||||||
|
cpu_sys_time,
|
||||||
|
bucket_done
|
||||||
|
FROM pg_stat_monitor_internal(TRUE)
|
||||||
|
ORDER BY bucket_start_time;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION pgsm_create_13_view() RETURNS INT AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
CREATE VIEW pg_stat_monitor AS SELECT
|
||||||
|
bucket,
|
||||||
|
bucket_start_time AS bucket_start_time,
|
||||||
|
userid,
|
||||||
|
username,
|
||||||
|
dbid,
|
||||||
|
datname,
|
||||||
|
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||||
|
pgsm_query_id,
|
||||||
|
queryid,
|
||||||
|
toplevel,
|
||||||
|
top_queryid,
|
||||||
|
query,
|
||||||
|
comments,
|
||||||
|
planid,
|
||||||
|
query_plan,
|
||||||
|
top_query,
|
||||||
|
application_name,
|
||||||
|
string_to_array(relations, ',') AS relations,
|
||||||
|
cmd_type,
|
||||||
|
get_cmd_type(cmd_type) AS cmd_type_text,
|
||||||
|
elevel,
|
||||||
|
sqlcode,
|
||||||
|
message,
|
||||||
|
calls,
|
||||||
|
total_exec_time,
|
||||||
|
min_exec_time,
|
||||||
|
max_exec_time,
|
||||||
|
mean_exec_time,
|
||||||
|
stddev_exec_time,
|
||||||
|
rows,
|
||||||
|
shared_blks_hit,
|
||||||
|
shared_blks_read,
|
||||||
|
shared_blks_dirtied,
|
||||||
|
shared_blks_written,
|
||||||
|
local_blks_hit,
|
||||||
|
local_blks_read,
|
||||||
|
local_blks_dirtied,
|
||||||
|
local_blks_written,
|
||||||
|
temp_blks_read,
|
||||||
|
temp_blks_written,
|
||||||
|
shared_blk_read_time AS blk_read_time,
|
||||||
|
shared_blk_write_time AS blk_write_time,
|
||||||
|
(string_to_array(resp_calls, ',')) resp_calls,
|
||||||
|
cpu_user_time,
|
||||||
|
cpu_sys_time,
|
||||||
|
wal_records,
|
||||||
|
wal_fpi,
|
||||||
|
wal_bytes,
|
||||||
|
bucket_done,
|
||||||
|
-- PostgreSQL-13 Specific Coulumns
|
||||||
|
plans,
|
||||||
|
total_plan_time,
|
||||||
|
min_plan_time,
|
||||||
|
max_plan_time,
|
||||||
|
mean_plan_time,
|
||||||
|
stddev_plan_time
|
||||||
|
FROM pg_stat_monitor_internal(TRUE)
|
||||||
|
ORDER BY bucket_start_time;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE FUNCTION pgsm_create_14_view() RETURNS INT AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
CREATE VIEW pg_stat_monitor AS SELECT
|
||||||
|
bucket,
|
||||||
|
bucket_start_time AS bucket_start_time,
|
||||||
|
userid,
|
||||||
|
username,
|
||||||
|
dbid,
|
||||||
|
datname,
|
||||||
|
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||||
|
pgsm_query_id,
|
||||||
|
queryid,
|
||||||
|
toplevel,
|
||||||
|
top_queryid,
|
||||||
|
query,
|
||||||
|
comments,
|
||||||
|
planid,
|
||||||
|
query_plan,
|
||||||
|
top_query,
|
||||||
|
application_name,
|
||||||
|
string_to_array(relations, ',') AS relations,
|
||||||
|
cmd_type,
|
||||||
|
get_cmd_type(cmd_type) AS cmd_type_text,
|
||||||
|
elevel,
|
||||||
|
sqlcode,
|
||||||
|
message,
|
||||||
|
calls,
|
||||||
|
total_exec_time,
|
||||||
|
min_exec_time,
|
||||||
|
max_exec_time,
|
||||||
|
mean_exec_time,
|
||||||
|
stddev_exec_time,
|
||||||
|
rows,
|
||||||
|
shared_blks_hit,
|
||||||
|
shared_blks_read,
|
||||||
|
shared_blks_dirtied,
|
||||||
|
shared_blks_written,
|
||||||
|
local_blks_hit,
|
||||||
|
local_blks_read,
|
||||||
|
local_blks_dirtied,
|
||||||
|
local_blks_written,
|
||||||
|
temp_blks_read,
|
||||||
|
temp_blks_written,
|
||||||
|
shared_blk_read_time AS blk_read_time,
|
||||||
|
shared_blk_write_time AS blk_write_time,
|
||||||
|
(string_to_array(resp_calls, ',')) resp_calls,
|
||||||
|
cpu_user_time,
|
||||||
|
cpu_sys_time,
|
||||||
|
wal_records,
|
||||||
|
wal_fpi,
|
||||||
|
wal_bytes,
|
||||||
|
bucket_done,
|
||||||
|
|
||||||
|
plans,
|
||||||
|
total_plan_time,
|
||||||
|
min_plan_time,
|
||||||
|
max_plan_time,
|
||||||
|
mean_plan_time,
|
||||||
|
stddev_plan_time
|
||||||
|
FROM pg_stat_monitor_internal(TRUE)
|
||||||
|
ORDER BY bucket_start_time;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE FUNCTION pgsm_create_15_view() RETURNS INT AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
CREATE VIEW pg_stat_monitor AS SELECT
|
||||||
|
bucket,
|
||||||
|
bucket_start_time AS bucket_start_time,
|
||||||
|
userid,
|
||||||
|
username,
|
||||||
|
dbid,
|
||||||
|
datname,
|
||||||
|
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||||
|
pgsm_query_id,
|
||||||
|
queryid,
|
||||||
|
toplevel,
|
||||||
|
top_queryid,
|
||||||
|
query,
|
||||||
|
comments,
|
||||||
|
planid,
|
||||||
|
query_plan,
|
||||||
|
top_query,
|
||||||
|
application_name,
|
||||||
|
string_to_array(relations, ',') AS relations,
|
||||||
|
cmd_type,
|
||||||
|
get_cmd_type(cmd_type) AS cmd_type_text,
|
||||||
|
elevel,
|
||||||
|
sqlcode,
|
||||||
|
message,
|
||||||
|
calls,
|
||||||
|
total_exec_time,
|
||||||
|
min_exec_time,
|
||||||
|
max_exec_time,
|
||||||
|
mean_exec_time,
|
||||||
|
stddev_exec_time,
|
||||||
|
rows,
|
||||||
|
shared_blks_hit,
|
||||||
|
shared_blks_read,
|
||||||
|
shared_blks_dirtied,
|
||||||
|
shared_blks_written,
|
||||||
|
local_blks_hit,
|
||||||
|
local_blks_read,
|
||||||
|
local_blks_dirtied,
|
||||||
|
local_blks_written,
|
||||||
|
temp_blks_read,
|
||||||
|
temp_blks_written,
|
||||||
|
shared_blk_read_time AS blk_read_time,
|
||||||
|
shared_blk_write_time AS blk_write_time,
|
||||||
|
temp_blk_read_time,
|
||||||
|
temp_blk_write_time,
|
||||||
|
|
||||||
|
(string_to_array(resp_calls, ',')) resp_calls,
|
||||||
|
cpu_user_time,
|
||||||
|
cpu_sys_time,
|
||||||
|
wal_records,
|
||||||
|
wal_fpi,
|
||||||
|
wal_bytes,
|
||||||
|
bucket_done,
|
||||||
|
|
||||||
|
plans,
|
||||||
|
total_plan_time,
|
||||||
|
min_plan_time,
|
||||||
|
max_plan_time,
|
||||||
|
mean_plan_time,
|
||||||
|
stddev_plan_time,
|
||||||
|
|
||||||
|
jit_functions,
|
||||||
|
jit_generation_time,
|
||||||
|
jit_inlining_count,
|
||||||
|
jit_inlining_time,
|
||||||
|
jit_optimization_count,
|
||||||
|
jit_optimization_time,
|
||||||
|
jit_emission_count,
|
||||||
|
jit_emission_time
|
||||||
|
|
||||||
|
FROM pg_stat_monitor_internal(TRUE)
|
||||||
|
ORDER BY bucket_start_time;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE FUNCTION pgsm_create_17_view() RETURNS INT AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
CREATE VIEW pg_stat_monitor AS SELECT
|
||||||
|
bucket,
|
||||||
|
bucket_start_time,
|
||||||
|
userid,
|
||||||
|
username,
|
||||||
|
dbid,
|
||||||
|
datname,
|
||||||
|
'0.0.0.0'::inet + client_ip AS client_ip,
|
||||||
|
pgsm_query_id,
|
||||||
|
queryid,
|
||||||
|
toplevel,
|
||||||
|
top_queryid,
|
||||||
|
query,
|
||||||
|
comments,
|
||||||
|
planid,
|
||||||
|
query_plan,
|
||||||
|
top_query,
|
||||||
|
application_name,
|
||||||
|
string_to_array(relations, ',') AS relations,
|
||||||
|
cmd_type,
|
||||||
|
get_cmd_type(cmd_type) AS cmd_type_text,
|
||||||
|
elevel,
|
||||||
|
sqlcode,
|
||||||
|
message,
|
||||||
|
calls,
|
||||||
|
total_exec_time,
|
||||||
|
min_exec_time,
|
||||||
|
max_exec_time,
|
||||||
|
mean_exec_time,
|
||||||
|
stddev_exec_time,
|
||||||
|
rows,
|
||||||
|
shared_blks_hit,
|
||||||
|
shared_blks_read,
|
||||||
|
shared_blks_dirtied,
|
||||||
|
shared_blks_written,
|
||||||
|
local_blks_hit,
|
||||||
|
local_blks_read,
|
||||||
|
local_blks_dirtied,
|
||||||
|
local_blks_written,
|
||||||
|
temp_blks_read,
|
||||||
|
temp_blks_written,
|
||||||
|
shared_blk_read_time,
|
||||||
|
shared_blk_write_time,
|
||||||
|
local_blk_read_time,
|
||||||
|
local_blk_write_time,
|
||||||
|
temp_blk_read_time,
|
||||||
|
temp_blk_write_time,
|
||||||
|
|
||||||
|
(string_to_array(resp_calls, ',')) resp_calls,
|
||||||
|
cpu_user_time,
|
||||||
|
cpu_sys_time,
|
||||||
|
wal_records,
|
||||||
|
wal_fpi,
|
||||||
|
wal_bytes,
|
||||||
|
bucket_done,
|
||||||
|
|
||||||
|
plans,
|
||||||
|
total_plan_time,
|
||||||
|
min_plan_time,
|
||||||
|
max_plan_time,
|
||||||
|
mean_plan_time,
|
||||||
|
stddev_plan_time,
|
||||||
|
|
||||||
|
jit_functions,
|
||||||
|
jit_generation_time,
|
||||||
|
jit_inlining_count,
|
||||||
|
jit_inlining_time,
|
||||||
|
jit_optimization_count,
|
||||||
|
jit_optimization_time,
|
||||||
|
jit_emission_count,
|
||||||
|
jit_emission_time,
|
||||||
|
jit_deform_count,
|
||||||
|
jit_deform_time,
|
||||||
|
|
||||||
|
stats_since,
|
||||||
|
minmax_stats_since
|
||||||
|
|
||||||
|
FROM pg_stat_monitor_internal(TRUE)
|
||||||
|
ORDER BY bucket_start_time;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE FUNCTION pgsm_create_view() RETURNS INT AS
|
||||||
|
$$
|
||||||
|
DECLARE ver integer;
|
||||||
|
BEGIN
|
||||||
|
SELECT current_setting('server_version_num') INTO ver;
|
||||||
|
IF (ver >= 170000) THEN
|
||||||
|
return pgsm_create_17_view();
|
||||||
|
END IF;
|
||||||
|
IF (ver >= 150000) THEN
|
||||||
|
return pgsm_create_15_view();
|
||||||
|
END IF;
|
||||||
|
IF (ver >= 140000) THEN
|
||||||
|
return pgsm_create_14_view();
|
||||||
|
END IF;
|
||||||
|
IF (ver >= 130000) THEN
|
||||||
|
return pgsm_create_13_view();
|
||||||
|
END IF;
|
||||||
|
IF (ver >= 110000) THEN
|
||||||
|
return pgsm_create_11_view();
|
||||||
|
END IF;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
SELECT pgsm_create_view();
|
||||||
|
REVOKE ALL ON FUNCTION pgsm_create_view FROM PUBLIC;
|
||||||
|
REVOKE ALL ON FUNCTION pgsm_create_11_view FROM PUBLIC;
|
||||||
|
REVOKE ALL ON FUNCTION pgsm_create_13_view FROM PUBLIC;
|
||||||
|
REVOKE ALL ON FUNCTION pgsm_create_14_view FROM PUBLIC;
|
||||||
|
REVOKE ALL ON FUNCTION pgsm_create_15_view FROM PUBLIC;
|
||||||
|
REVOKE ALL ON FUNCTION pgsm_create_17_view FROM PUBLIC;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION range TO PUBLIC;
|
||||||
|
GRANT EXECUTE ON FUNCTION decode_error_level TO PUBLIC;
|
||||||
|
GRANT EXECUTE ON FUNCTION get_histogram_timings TO PUBLIC;
|
||||||
|
GRANT EXECUTE ON FUNCTION get_cmd_type TO PUBLIC;
|
||||||
|
GRANT EXECUTE ON FUNCTION pg_stat_monitor_internal TO PUBLIC;
|
||||||
|
|
||||||
|
GRANT SELECT ON pg_stat_monitor TO PUBLIC;
|
||||||
|
|
||||||
|
-- Reset is only available to super user
|
||||||
|
REVOKE ALL ON FUNCTION pg_stat_monitor_reset FROM PUBLIC;
|
|
@ -31,16 +31,18 @@
|
||||||
typedef enum pgsmVersion
|
typedef enum pgsmVersion
|
||||||
{
|
{
|
||||||
PGSM_V1_0 = 0,
|
PGSM_V1_0 = 0,
|
||||||
PGSM_V2_0
|
PGSM_V2_0,
|
||||||
|
PGSM_V2_1
|
||||||
} pgsmVersion;
|
} pgsmVersion;
|
||||||
|
|
||||||
PG_MODULE_MAGIC;
|
PG_MODULE_MAGIC;
|
||||||
|
|
||||||
#define BUILD_VERSION "2.0.4"
|
#define BUILD_VERSION "2.1.0"
|
||||||
|
|
||||||
/* Number of output arguments (columns) for various API versions */
|
/* Number of output arguments (columns) for various API versions */
|
||||||
#define PG_STAT_MONITOR_COLS_V1_0 52
|
#define PG_STAT_MONITOR_COLS_V1_0 52
|
||||||
#define PG_STAT_MONITOR_COLS_V2_0 64
|
#define PG_STAT_MONITOR_COLS_V2_0 64
|
||||||
|
#define PG_STAT_MONITOR_COLS_V2_1 70
|
||||||
#define PG_STAT_MONITOR_COLS PG_STAT_MONITOR_COLS_V2_0 /* maximum of above */
|
#define PG_STAT_MONITOR_COLS PG_STAT_MONITOR_COLS_V2_0 /* maximum of above */
|
||||||
|
|
||||||
#define PGSM_TEXT_FILE PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat_monitor_query"
|
#define PGSM_TEXT_FILE PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat_monitor_query"
|
||||||
|
@ -71,11 +73,12 @@ do \
|
||||||
/*---- Initicalization Function Declarations ----*/
|
/*---- Initicalization Function Declarations ----*/
|
||||||
void _PG_init(void);
|
void _PG_init(void);
|
||||||
|
|
||||||
/* Current nesting depth of ExecutorRun+ProcessUtility calls */
|
/* Current nesting depth of planner/ExecutorRun/ProcessUtility calls */
|
||||||
static int exec_nested_level = 0;
|
static int nesting_level = 0;
|
||||||
volatile bool __pgsm_do_not_capture_error = false;
|
volatile bool __pgsm_do_not_capture_error = false;
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= 130000
|
#if PG_VERSION_NUM >= 130000 && PG_VERSION_NUM < 170000
|
||||||
|
/* Before planner nesting level was conunted separately */
|
||||||
static int plan_nested_level = 0;
|
static int plan_nested_level = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -145,6 +148,7 @@ PG_FUNCTION_INFO_V1(pg_stat_monitor_version);
|
||||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_reset);
|
PG_FUNCTION_INFO_V1(pg_stat_monitor_reset);
|
||||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_1_0);
|
PG_FUNCTION_INFO_V1(pg_stat_monitor_1_0);
|
||||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_2_0);
|
PG_FUNCTION_INFO_V1(pg_stat_monitor_2_0);
|
||||||
|
PG_FUNCTION_INFO_V1(pg_stat_monitor_2_1);
|
||||||
PG_FUNCTION_INFO_V1(pg_stat_monitor);
|
PG_FUNCTION_INFO_V1(pg_stat_monitor);
|
||||||
PG_FUNCTION_INFO_V1(get_histogram_timings);
|
PG_FUNCTION_INFO_V1(get_histogram_timings);
|
||||||
PG_FUNCTION_INFO_V1(pg_stat_monitor_hook_stats);
|
PG_FUNCTION_INFO_V1(pg_stat_monitor_hook_stats);
|
||||||
|
@ -197,11 +201,6 @@ DECLARE_HOOK(void pgsm_ProcessUtility, PlannedStmt *pstmt, const char *queryStri
|
||||||
static uint64 pgsm_hash_string(const char *str, int len);
|
static uint64 pgsm_hash_string(const char *str, int len);
|
||||||
char *unpack_sql_state(int sql_state);
|
char *unpack_sql_state(int sql_state);
|
||||||
|
|
||||||
#define PGSM_HANDLED_UTILITY(n) (!IsA(n, ExecuteStmt) && \
|
|
||||||
!IsA(n, PrepareStmt) && \
|
|
||||||
!IsA(n, DeallocateStmt))
|
|
||||||
|
|
||||||
|
|
||||||
static pgsmEntry * pgsm_create_hash_entry(uint64 bucket_id, uint64 queryid, PlanInfo * plan_info);
|
static pgsmEntry * pgsm_create_hash_entry(uint64 bucket_id, uint64 queryid, PlanInfo * plan_info);
|
||||||
static void pgsm_add_to_list(pgsmEntry * entry, char *query_text, int query_len);
|
static void pgsm_add_to_list(pgsmEntry * entry, char *query_text, int query_len);
|
||||||
static pgsmEntry * pgsm_get_entry_for_query(uint64 queryid, PlanInfo * plan_info, const char *query_text, int query_len, bool create);
|
static pgsmEntry * pgsm_get_entry_for_query(uint64 queryid, PlanInfo * plan_info, const char *query_text, int query_len, bool create);
|
||||||
|
@ -425,17 +424,18 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pgsm_enabled(exec_nested_level))
|
if (!pgsm_enabled(nesting_level))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear queryId for prepared statements related utility, as those will
|
* If it's EXECUTE, clear the queryId so that stats will accumulate for
|
||||||
* inherit from the underlying statement's one (except DEALLOCATE which is
|
* the underlying PREPARE. But don't do this if we're not tracking
|
||||||
* entirely untracked).
|
* utility statements, to avoid messing up another extension that might be
|
||||||
|
* tracking them.
|
||||||
*/
|
*/
|
||||||
if (query->utilityStmt)
|
if (query->utilityStmt)
|
||||||
{
|
{
|
||||||
if (pgsm_track_utility && !PGSM_HANDLED_UTILITY(query->utilityStmt))
|
if (pgsm_track_utility && IsA(query->utilityStmt, ExecuteStmt))
|
||||||
query->queryId = UINT64CONST(0);
|
query->queryId = UINT64CONST(0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -568,7 +568,7 @@ pgsm_ExecutorStart(QueryDesc *queryDesc, int eflags)
|
||||||
* counting of optimizable statements that are directly contained in
|
* counting of optimizable statements that are directly contained in
|
||||||
* utility statements.
|
* utility statements.
|
||||||
*/
|
*/
|
||||||
if (pgsm_enabled(exec_nested_level) &&
|
if (pgsm_enabled(nesting_level) &&
|
||||||
queryDesc->plannedstmt->queryId != UINT64CONST(0))
|
queryDesc->plannedstmt->queryId != UINT64CONST(0))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -599,37 +599,37 @@ static void
|
||||||
pgsm_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count,
|
pgsm_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count,
|
||||||
bool execute_once)
|
bool execute_once)
|
||||||
{
|
{
|
||||||
if (exec_nested_level >= 0 && exec_nested_level < max_stack_depth)
|
if (nesting_level >= 0 && nesting_level < max_stack_depth)
|
||||||
{
|
{
|
||||||
nested_queryids[exec_nested_level] = queryDesc->plannedstmt->queryId;
|
nested_queryids[nesting_level] = queryDesc->plannedstmt->queryId;
|
||||||
nested_query_txts[exec_nested_level] = strdup(queryDesc->sourceText);
|
nested_query_txts[nesting_level] = strdup(queryDesc->sourceText);
|
||||||
}
|
}
|
||||||
|
|
||||||
exec_nested_level++;
|
nesting_level++;
|
||||||
PG_TRY();
|
PG_TRY();
|
||||||
{
|
{
|
||||||
if (prev_ExecutorRun)
|
if (prev_ExecutorRun)
|
||||||
prev_ExecutorRun(queryDesc, direction, count, execute_once);
|
prev_ExecutorRun(queryDesc, direction, count, execute_once);
|
||||||
else
|
else
|
||||||
standard_ExecutorRun(queryDesc, direction, count, execute_once);
|
standard_ExecutorRun(queryDesc, direction, count, execute_once);
|
||||||
exec_nested_level--;
|
nesting_level--;
|
||||||
if (exec_nested_level >= 0 && exec_nested_level < max_stack_depth)
|
if (nesting_level >= 0 && nesting_level < max_stack_depth)
|
||||||
{
|
{
|
||||||
nested_queryids[exec_nested_level] = UINT64CONST(0);
|
nested_queryids[nesting_level] = UINT64CONST(0);
|
||||||
if (nested_query_txts[exec_nested_level])
|
if (nested_query_txts[nesting_level])
|
||||||
free(nested_query_txts[exec_nested_level]);
|
free(nested_query_txts[nesting_level]);
|
||||||
nested_query_txts[exec_nested_level] = NULL;
|
nested_query_txts[nesting_level] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PG_CATCH();
|
PG_CATCH();
|
||||||
{
|
{
|
||||||
exec_nested_level--;
|
nesting_level--;
|
||||||
if (exec_nested_level >= 0 && exec_nested_level < max_stack_depth)
|
if (nesting_level >= 0 && nesting_level < max_stack_depth)
|
||||||
{
|
{
|
||||||
nested_queryids[exec_nested_level] = UINT64CONST(0);
|
nested_queryids[nesting_level] = UINT64CONST(0);
|
||||||
if (nested_query_txts[exec_nested_level])
|
if (nested_query_txts[nesting_level])
|
||||||
free(nested_query_txts[exec_nested_level]);
|
free(nested_query_txts[nesting_level]);
|
||||||
nested_query_txts[exec_nested_level] = NULL;
|
nested_query_txts[nesting_level] = NULL;
|
||||||
}
|
}
|
||||||
PG_RE_THROW();
|
PG_RE_THROW();
|
||||||
}
|
}
|
||||||
|
@ -642,7 +642,7 @@ pgsm_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count,
|
||||||
static void
|
static void
|
||||||
pgsm_ExecutorFinish(QueryDesc *queryDesc)
|
pgsm_ExecutorFinish(QueryDesc *queryDesc)
|
||||||
{
|
{
|
||||||
exec_nested_level++;
|
nesting_level++;
|
||||||
|
|
||||||
PG_TRY();
|
PG_TRY();
|
||||||
{
|
{
|
||||||
|
@ -650,11 +650,11 @@ pgsm_ExecutorFinish(QueryDesc *queryDesc)
|
||||||
prev_ExecutorFinish(queryDesc);
|
prev_ExecutorFinish(queryDesc);
|
||||||
else
|
else
|
||||||
standard_ExecutorFinish(queryDesc);
|
standard_ExecutorFinish(queryDesc);
|
||||||
exec_nested_level--;
|
nesting_level--;
|
||||||
}
|
}
|
||||||
PG_CATCH();
|
PG_CATCH();
|
||||||
{
|
{
|
||||||
exec_nested_level--;
|
nesting_level--;
|
||||||
PG_RE_THROW();
|
PG_RE_THROW();
|
||||||
}
|
}
|
||||||
PG_END_TRY();
|
PG_END_TRY();
|
||||||
|
@ -722,7 +722,7 @@ pgsm_ExecutorEnd(QueryDesc *queryDesc)
|
||||||
MemoryContextSwitchTo(oldctx);
|
MemoryContextSwitchTo(oldctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queryId != UINT64CONST(0) && queryDesc->totaltime && pgsm_enabled(exec_nested_level))
|
if (queryId != UINT64CONST(0) && queryDesc->totaltime && pgsm_enabled(nesting_level))
|
||||||
{
|
{
|
||||||
entry = pgsm_get_entry_for_query(queryId, plan_ptr, (char *) queryDesc->sourceText, strlen(queryDesc->sourceText), true);
|
entry = pgsm_get_entry_for_query(queryId, plan_ptr, (char *) queryDesc->sourceText, strlen(queryDesc->sourceText), true);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
|
@ -868,8 +868,14 @@ pgsm_planner_hook(Query *parse, const char *query_string, int cursorOptions, Par
|
||||||
* top level planner call.
|
* top level planner call.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (pgsm_enabled(plan_nested_level + exec_nested_level) &&
|
bool enabled;
|
||||||
pgsm_track_planning && query_string && parse->queryId != UINT64CONST(0))
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
enabled = pgsm_enabled(nesting_level);
|
||||||
|
#else
|
||||||
|
enabled = pgsm_enabled(plan_nested_level + nesting_level);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (enabled && pgsm_track_planning && query_string && parse->queryId != UINT64CONST(0))
|
||||||
{
|
{
|
||||||
pgsmEntry *entry = NULL;
|
pgsmEntry *entry = NULL;
|
||||||
instr_time start;
|
instr_time start;
|
||||||
|
@ -892,7 +898,11 @@ pgsm_planner_hook(Query *parse, const char *query_string, int cursorOptions, Par
|
||||||
if (MemoryContextIsValid(MessageContext))
|
if (MemoryContextIsValid(MessageContext))
|
||||||
entry = pgsm_get_entry_for_query(parse->queryId, NULL, query_string, strlen(query_string), true);
|
entry = pgsm_get_entry_for_query(parse->queryId, NULL, query_string, strlen(query_string), true);
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
nesting_level++;
|
||||||
|
#else
|
||||||
plan_nested_level++;
|
plan_nested_level++;
|
||||||
|
#endif
|
||||||
PG_TRY();
|
PG_TRY();
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -909,7 +919,11 @@ pgsm_planner_hook(Query *parse, const char *query_string, int cursorOptions, Par
|
||||||
}
|
}
|
||||||
PG_FINALLY();
|
PG_FINALLY();
|
||||||
{
|
{
|
||||||
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
nesting_level--;
|
||||||
|
#else
|
||||||
plan_nested_level--;
|
plan_nested_level--;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
PG_END_TRY();
|
PG_END_TRY();
|
||||||
|
|
||||||
|
@ -945,19 +959,38 @@ pgsm_planner_hook(Query *parse, const char *query_string, int cursorOptions, Par
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
* Even though we're not tracking plan time for this statement, we
|
||||||
|
* must still increment the nesting level, to ensure that functions
|
||||||
|
* evaluated during planning are not seen as top-level calls.
|
||||||
|
*
|
||||||
* If there is a previous installed hook, then assume it's going to
|
* If there is a previous installed hook, then assume it's going to
|
||||||
* call standard_planner() function, otherwise we call the function
|
* call standard_planner() function, otherwise we call the function
|
||||||
* here. This is to avoid calling standard_planner() function twice,
|
* here. This is to avoid calling standard_planner() function twice,
|
||||||
* since it modifies the first argument (Query *), the second call
|
* since it modifies the first argument (Query *), the second call
|
||||||
* would trigger an assertion failure.
|
* would trigger an assertion failure.
|
||||||
*/
|
*/
|
||||||
plan_nested_level++;
|
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
nesting_level++;
|
||||||
|
#else
|
||||||
|
plan_nested_level++;
|
||||||
|
#endif
|
||||||
|
PG_TRY();
|
||||||
|
{
|
||||||
if (planner_hook_next)
|
if (planner_hook_next)
|
||||||
result = planner_hook_next(parse, query_string, cursorOptions, boundParams);
|
result = planner_hook_next(parse, query_string, cursorOptions, boundParams);
|
||||||
else
|
else
|
||||||
result = standard_planner(parse, query_string, cursorOptions, boundParams);
|
result = standard_planner(parse, query_string, cursorOptions, boundParams);
|
||||||
|
}
|
||||||
|
PG_FINALLY();
|
||||||
|
{
|
||||||
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
nesting_level--;
|
||||||
|
#else
|
||||||
plan_nested_level--;
|
plan_nested_level--;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
PG_END_TRY();
|
||||||
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -995,6 +1028,7 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||||
{
|
{
|
||||||
Node *parsetree = pstmt->utilityStmt;
|
Node *parsetree = pstmt->utilityStmt;
|
||||||
uint64 queryId = 0;
|
uint64 queryId = 0;
|
||||||
|
bool enabled = pgsm_track_utility && pgsm_enabled(nesting_level);
|
||||||
|
|
||||||
#if PG_VERSION_NUM < 140000
|
#if PG_VERSION_NUM < 140000
|
||||||
int len = strlen(queryString);
|
int len = strlen(queryString);
|
||||||
|
@ -1012,7 +1046,7 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||||
* since we are already measuring the statement's costs at the utility
|
* since we are already measuring the statement's costs at the utility
|
||||||
* level.
|
* level.
|
||||||
*/
|
*/
|
||||||
if (pgsm_track_utility && pgsm_enabled(exec_nested_level))
|
if (enabled)
|
||||||
pstmt->queryId = UINT64CONST(0);
|
pstmt->queryId = UINT64CONST(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1025,13 +1059,16 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||||
* hash table entry for the PREPARE (with hash calculated from the query
|
* hash table entry for the PREPARE (with hash calculated from the query
|
||||||
* string), and then a different one with the same query string (but hash
|
* string), and then a different one with the same query string (but hash
|
||||||
* calculated from the query tree) would be used to accumulate costs of
|
* calculated from the query tree) would be used to accumulate costs of
|
||||||
* ensuing EXECUTEs. This would be confusing, and inconsistent with other
|
* ensuing EXECUTEs. This would be confusing. Since PREPARE doesn't
|
||||||
* cases where planning time is not included at all.
|
* actually run the planner (only parse+rewrite), its costs are generally
|
||||||
|
* pretty negligible and it seems okay to just ignore it.
|
||||||
*
|
*
|
||||||
* Likewise, we don't track execution of DEALLOCATE.
|
* Likewise, we don't track execution of DEALLOCATE.
|
||||||
*/
|
*/
|
||||||
if (pgsm_track_utility && pgsm_enabled(exec_nested_level) &&
|
if (enabled &&
|
||||||
PGSM_HANDLED_UTILITY(parsetree))
|
!IsA(parsetree, ExecuteStmt) &&
|
||||||
|
!IsA(parsetree, PrepareStmt) &&
|
||||||
|
!IsA(parsetree, DeallocateStmt))
|
||||||
{
|
{
|
||||||
pgsmEntry *entry;
|
pgsmEntry *entry;
|
||||||
char *query_text;
|
char *query_text;
|
||||||
|
@ -1052,7 +1089,7 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||||
elog(DEBUG1, "[pg_stat_monitor] pgsm_ProcessUtility: Failed to execute getrusage.");
|
elog(DEBUG1, "[pg_stat_monitor] pgsm_ProcessUtility: Failed to execute getrusage.");
|
||||||
|
|
||||||
INSTR_TIME_SET_CURRENT(start);
|
INSTR_TIME_SET_CURRENT(start);
|
||||||
exec_nested_level++;
|
nesting_level++;
|
||||||
|
|
||||||
PG_TRY();
|
PG_TRY();
|
||||||
{
|
{
|
||||||
|
@ -1092,11 +1129,11 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||||
dest,
|
dest,
|
||||||
completionTag);
|
completionTag);
|
||||||
#endif
|
#endif
|
||||||
exec_nested_level--;
|
nesting_level--;
|
||||||
}
|
}
|
||||||
PG_CATCH();
|
PG_CATCH();
|
||||||
{
|
{
|
||||||
exec_nested_level--;
|
nesting_level--;
|
||||||
PG_RE_THROW();
|
PG_RE_THROW();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1182,6 +1219,33 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Even though we're not tracking execution time for this statement,
|
||||||
|
* we must still increment the nesting level, to ensure that functions
|
||||||
|
* evaluated within it are not seen as top-level calls. But don't do
|
||||||
|
* so for EXECUTE; that way, when control reaches pgss_planner or
|
||||||
|
* pgss_ExecutorStart, we will treat the costs as top-level if
|
||||||
|
* appropriate. Likewise, don't bump for PREPARE, so that parse
|
||||||
|
* analysis will treat the statement as top-level if appropriate.
|
||||||
|
*
|
||||||
|
* Likewise, we don't track execution of DEALLOCATE.
|
||||||
|
*
|
||||||
|
* To be absolutely certain we don't mess up the nesting level,
|
||||||
|
* evaluate the bump_level condition just once.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
bool bump_level =
|
||||||
|
!IsA(parsetree, ExecuteStmt) &&
|
||||||
|
!IsA(parsetree, PrepareStmt) &&
|
||||||
|
!IsA(parsetree, DeallocateStmt);
|
||||||
|
|
||||||
|
if (bump_level)
|
||||||
|
nesting_level++;
|
||||||
|
|
||||||
|
PG_TRY();
|
||||||
|
{
|
||||||
|
#endif
|
||||||
#if PG_VERSION_NUM >= 140000
|
#if PG_VERSION_NUM >= 140000
|
||||||
if (prev_ProcessUtility)
|
if (prev_ProcessUtility)
|
||||||
prev_ProcessUtility(pstmt, queryString,
|
prev_ProcessUtility(pstmt, queryString,
|
||||||
|
@ -1217,6 +1281,18 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||||
context, params, queryEnv,
|
context, params, queryEnv,
|
||||||
dest,
|
dest,
|
||||||
completionTag);
|
completionTag);
|
||||||
|
#endif
|
||||||
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
if (bump_level)
|
||||||
|
nesting_level--;
|
||||||
|
}
|
||||||
|
PG_CATCH();
|
||||||
|
{
|
||||||
|
if (bump_level)
|
||||||
|
nesting_level--;
|
||||||
|
PG_RE_THROW();
|
||||||
|
}
|
||||||
|
PG_END_TRY();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1358,9 +1434,13 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||||
int sqlcode_len = error_info ? strlen(error_info->sqlcode) : 0;
|
int sqlcode_len = error_info ? strlen(error_info->sqlcode) : 0;
|
||||||
int plan_text_len = plan_info ? plan_info->plan_len : 0;
|
int plan_text_len = plan_info ? plan_info->plan_len : 0;
|
||||||
|
|
||||||
/* Start collecting data for next bucket and reset all counters */
|
/* Start collecting data for next bucket and reset all counters and timestamps */
|
||||||
if (reset)
|
if (reset)
|
||||||
|
{
|
||||||
memset(&entry->counters, 0, sizeof(Counters));
|
memset(&entry->counters, 0, sizeof(Counters));
|
||||||
|
entry->stats_since = GetCurrentTimestamp();
|
||||||
|
entry->minmax_stats_since = entry->stats_since;
|
||||||
|
}
|
||||||
|
|
||||||
/* volatile block */
|
/* volatile block */
|
||||||
{
|
{
|
||||||
|
@ -1457,14 +1537,14 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||||
e->counters.info.num_relations = num_relations;
|
e->counters.info.num_relations = num_relations;
|
||||||
_snprintf2(e->counters.info.relations, relations, num_relations, REL_LEN);
|
_snprintf2(e->counters.info.relations, relations, num_relations, REL_LEN);
|
||||||
|
|
||||||
if (exec_nested_level > 0 && e->counters.info.parentid == 0 && pgsm_track == PGSM_TRACK_ALL)
|
if (nesting_level > 0 && e->counters.info.parentid == 0 && pgsm_track == PGSM_TRACK_ALL)
|
||||||
{
|
{
|
||||||
if (exec_nested_level >= 0 && exec_nested_level < max_stack_depth)
|
if (nesting_level >= 0 && nesting_level < max_stack_depth)
|
||||||
{
|
{
|
||||||
int parent_query_len = nested_query_txts[exec_nested_level - 1] ?
|
int parent_query_len = nested_query_txts[nesting_level - 1] ?
|
||||||
strlen(nested_query_txts[exec_nested_level - 1]) : 0;
|
strlen(nested_query_txts[nesting_level - 1]) : 0;
|
||||||
|
|
||||||
e->counters.info.parentid = nested_queryids[exec_nested_level - 1];
|
e->counters.info.parentid = nested_queryids[nesting_level - 1];
|
||||||
e->counters.info.parent_query = InvalidDsaPointer;
|
e->counters.info.parent_query = InvalidDsaPointer;
|
||||||
/* If we have a parent query, store it in the raw dsa area */
|
/* If we have a parent query, store it in the raw dsa area */
|
||||||
if (parent_query_len > 0)
|
if (parent_query_len > 0)
|
||||||
|
@ -1482,7 +1562,7 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||||
if (DsaPointerIsValid(qry))
|
if (DsaPointerIsValid(qry))
|
||||||
{
|
{
|
||||||
qry_buff = dsa_get_address(query_dsa_area, qry);
|
qry_buff = dsa_get_address(query_dsa_area, qry);
|
||||||
memcpy(qry_buff, nested_query_txts[exec_nested_level - 1], parent_query_len);
|
memcpy(qry_buff, nested_query_txts[nesting_level - 1], parent_query_len);
|
||||||
qry_buff[parent_query_len] = 0;
|
qry_buff[parent_query_len] = 0;
|
||||||
/* store the dsa pointer for parent query text */
|
/* store the dsa pointer for parent query text */
|
||||||
e->counters.info.parent_query = qry;
|
e->counters.info.parent_query = qry;
|
||||||
|
@ -1518,15 +1598,32 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||||
e->counters.blocks.local_blks_written += bufusage->local_blks_written;
|
e->counters.blocks.local_blks_written += bufusage->local_blks_written;
|
||||||
e->counters.blocks.temp_blks_read += bufusage->temp_blks_read;
|
e->counters.blocks.temp_blks_read += bufusage->temp_blks_read;
|
||||||
e->counters.blocks.temp_blks_written += bufusage->temp_blks_written;
|
e->counters.blocks.temp_blks_written += bufusage->temp_blks_written;
|
||||||
e->counters.blocks.blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->blk_read_time);
|
|
||||||
e->counters.blocks.blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->blk_write_time);
|
#if PG_VERSION_NUM < 170000
|
||||||
|
e->counters.blocks.shared_blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->blk_read_time);
|
||||||
|
e->counters.blocks.shared_blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->blk_write_time);
|
||||||
|
#else
|
||||||
|
e->counters.blocks.shared_blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->shared_blk_read_time);
|
||||||
|
e->counters.blocks.shared_blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->shared_blk_write_time);
|
||||||
|
e->counters.blocks.local_blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->local_blk_read_time);
|
||||||
|
e->counters.blocks.local_blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->local_blk_write_time);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= 150000
|
#if PG_VERSION_NUM >= 150000
|
||||||
e->counters.blocks.temp_blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->temp_blk_read_time);
|
e->counters.blocks.temp_blk_read_time += INSTR_TIME_GET_MILLISEC(bufusage->temp_blk_read_time);
|
||||||
e->counters.blocks.temp_blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->temp_blk_write_time);
|
e->counters.blocks.temp_blk_write_time += INSTR_TIME_GET_MILLISEC(bufusage->temp_blk_write_time);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memcpy((void *) &e->counters.blocks.instr_blk_read_time, &bufusage->blk_read_time, sizeof(instr_time));
|
#if PG_VERSION_NUM < 170000
|
||||||
memcpy((void *) &e->counters.blocks.instr_blk_write_time, &bufusage->blk_write_time, sizeof(instr_time));
|
memcpy((void *) &e->counters.blocks.instr_shared_blk_read_time, &bufusage->blk_read_time, sizeof(instr_time));
|
||||||
|
memcpy((void *) &e->counters.blocks.instr_shared_blk_write_time, &bufusage->blk_write_time, sizeof(instr_time));
|
||||||
|
#else
|
||||||
|
memcpy((void *) &e->counters.blocks.instr_shared_blk_read_time, &bufusage->shared_blk_read_time, sizeof(instr_time));
|
||||||
|
memcpy((void *) &e->counters.blocks.instr_shared_blk_write_time, &bufusage->shared_blk_write_time, sizeof(instr_time));
|
||||||
|
memcpy((void *) &e->counters.blocks.instr_local_blk_write_time, &bufusage->local_blk_write_time, sizeof(instr_time));
|
||||||
|
memcpy((void *) &e->counters.blocks.instr_local_blk_write_time, &bufusage->local_blk_write_time, sizeof(instr_time));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= 150000
|
#if PG_VERSION_NUM >= 150000
|
||||||
memcpy((void *) &e->counters.blocks.instr_temp_blk_read_time, &bufusage->temp_blk_read_time, sizeof(bufusage->temp_blk_read_time));
|
memcpy((void *) &e->counters.blocks.instr_temp_blk_read_time, &bufusage->temp_blk_read_time, sizeof(bufusage->temp_blk_read_time));
|
||||||
|
@ -1564,6 +1661,12 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||||
e->counters.jitinfo.jit_emission_count++;
|
e->counters.jitinfo.jit_emission_count++;
|
||||||
e->counters.jitinfo.jit_emission_time += INSTR_TIME_GET_MILLISEC(jitusage->emission_counter);
|
e->counters.jitinfo.jit_emission_time += INSTR_TIME_GET_MILLISEC(jitusage->emission_counter);
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
if (INSTR_TIME_GET_MILLISEC(jitusage->deform_counter))
|
||||||
|
e->counters.jitinfo.jit_deform_count++;
|
||||||
|
e->counters.jitinfo.jit_deform_time += INSTR_TIME_GET_MILLISEC(jitusage->deform_counter);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Only do this for local storage scenarios */
|
/* Only do this for local storage scenarios */
|
||||||
if (kind != PGSM_STORE)
|
if (kind != PGSM_STORE)
|
||||||
{
|
{
|
||||||
|
@ -1571,6 +1674,10 @@ pgsm_update_entry(pgsmEntry * entry,
|
||||||
memcpy((void *) &e->counters.jitinfo.instr_inlining_counter, &jitusage->inlining_counter, sizeof(instr_time));
|
memcpy((void *) &e->counters.jitinfo.instr_inlining_counter, &jitusage->inlining_counter, sizeof(instr_time));
|
||||||
memcpy((void *) &e->counters.jitinfo.instr_optimization_counter, &jitusage->optimization_counter, sizeof(instr_time));
|
memcpy((void *) &e->counters.jitinfo.instr_optimization_counter, &jitusage->optimization_counter, sizeof(instr_time));
|
||||||
memcpy((void *) &e->counters.jitinfo.instr_emission_counter, &jitusage->emission_counter, sizeof(instr_time));
|
memcpy((void *) &e->counters.jitinfo.instr_emission_counter, &jitusage->emission_counter, sizeof(instr_time));
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
memcpy((void *) &e->counters.jitinfo.instr_deform_counter, &jitusage->deform_counter, sizeof(instr_time));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1716,7 +1823,11 @@ pgsm_create_hash_entry(uint64 bucket_id, uint64 queryid, PlanInfo * plan_info)
|
||||||
#if PG_VERSION_NUM < 140000
|
#if PG_VERSION_NUM < 140000
|
||||||
entry->key.toplevel = 1;
|
entry->key.toplevel = 1;
|
||||||
#else
|
#else
|
||||||
entry->key.toplevel = ((exec_nested_level + plan_nested_level) == 0);
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
entry->key.toplevel = ((nesting_level) == 0);
|
||||||
|
#else
|
||||||
|
entry->key.toplevel = ((nesting_level + plan_nested_level) == 0);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (IsTransactionState())
|
if (IsTransactionState())
|
||||||
|
@ -1802,8 +1913,15 @@ pgsm_store(pgsmEntry * entry)
|
||||||
bufusage.temp_blks_read = entry->counters.blocks.temp_blks_read;
|
bufusage.temp_blks_read = entry->counters.blocks.temp_blks_read;
|
||||||
bufusage.temp_blks_written = entry->counters.blocks.temp_blks_written;
|
bufusage.temp_blks_written = entry->counters.blocks.temp_blks_written;
|
||||||
|
|
||||||
memcpy(&bufusage.blk_read_time, &entry->counters.blocks.instr_blk_read_time, sizeof(instr_time));
|
#if PG_VERSION_NUM < 170000
|
||||||
memcpy(&bufusage.blk_write_time, &entry->counters.blocks.instr_blk_write_time, sizeof(instr_time));
|
memcpy(&bufusage.blk_read_time, &entry->counters.blocks.instr_shared_blk_read_time, sizeof(instr_time));
|
||||||
|
memcpy(&bufusage.blk_write_time, &entry->counters.blocks.instr_shared_blk_write_time, sizeof(instr_time));
|
||||||
|
#else
|
||||||
|
memcpy(&bufusage.shared_blk_read_time, &entry->counters.blocks.instr_shared_blk_read_time, sizeof(instr_time));
|
||||||
|
memcpy(&bufusage.shared_blk_write_time, &entry->counters.blocks.instr_shared_blk_write_time, sizeof(instr_time));
|
||||||
|
memcpy(&bufusage.local_blk_read_time, &entry->counters.blocks.instr_local_blk_read_time, sizeof(instr_time));
|
||||||
|
memcpy(&bufusage.local_blk_write_time, &entry->counters.blocks.instr_local_blk_write_time, sizeof(instr_time));
|
||||||
|
#endif
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= 150000
|
#if PG_VERSION_NUM >= 150000
|
||||||
memcpy(&bufusage.temp_blk_read_time, &entry->counters.blocks.instr_temp_blk_read_time, sizeof(instr_time));
|
memcpy(&bufusage.temp_blk_read_time, &entry->counters.blocks.instr_temp_blk_read_time, sizeof(instr_time));
|
||||||
|
@ -1822,6 +1940,10 @@ pgsm_store(pgsmEntry * entry)
|
||||||
memcpy(&jitusage.optimization_counter, &entry->counters.jitinfo.instr_optimization_counter, sizeof(instr_time));
|
memcpy(&jitusage.optimization_counter, &entry->counters.jitinfo.instr_optimization_counter, sizeof(instr_time));
|
||||||
memcpy(&jitusage.emission_counter, &entry->counters.jitinfo.instr_emission_counter, sizeof(instr_time));
|
memcpy(&jitusage.emission_counter, &entry->counters.jitinfo.instr_emission_counter, sizeof(instr_time));
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= 170000
|
||||||
|
memcpy(&jitusage.deform_counter, &entry->counters.jitinfo.instr_deform_counter, sizeof(instr_time));
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Acquire a share lock to start with. We'd have to acquire exclusive if
|
* Acquire a share lock to start with. We'd have to acquire exclusive if
|
||||||
* we need ot create the entry.
|
* we need ot create the entry.
|
||||||
|
@ -1979,6 +2101,13 @@ pg_stat_monitor_2_0(PG_FUNCTION_ARGS)
|
||||||
return (Datum) 0;
|
return (Datum) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
pg_stat_monitor_2_1(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
pg_stat_monitor_internal(fcinfo, PGSM_V2_1, true);
|
||||||
|
return (Datum) 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Legacy entry point for pg_stat_monitor() API versions 1.0
|
* Legacy entry point for pg_stat_monitor() API versions 1.0
|
||||||
*/
|
*/
|
||||||
|
@ -1999,7 +2128,7 @@ IsBucketValid(uint64 bucketid)
|
||||||
|
|
||||||
TimestampDifference(pgsm->bucket_start_time[bucketid], current_tz, &secs, µsecs);
|
TimestampDifference(pgsm->bucket_start_time[bucketid], current_tz, &secs, µsecs);
|
||||||
|
|
||||||
if (secs > ((int64)pgsm_bucket_time * pgsm_max_buckets))
|
if (secs > ((int64) pgsm_bucket_time * pgsm_max_buckets))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2018,7 +2147,25 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
PGSM_HASH_SEQ_STATUS hstat;
|
PGSM_HASH_SEQ_STATUS hstat;
|
||||||
pgsmEntry *entry;
|
pgsmEntry *entry;
|
||||||
pgsmSharedState *pgsm;
|
pgsmSharedState *pgsm;
|
||||||
int expected_columns = (api_version >= PGSM_V2_0) ? PG_STAT_MONITOR_COLS_V2_0 : PG_STAT_MONITOR_COLS_V1_0;
|
|
||||||
|
int expected_columns;
|
||||||
|
|
||||||
|
switch (api_version)
|
||||||
|
{
|
||||||
|
case PGSM_V1_0:
|
||||||
|
expected_columns = PG_STAT_MONITOR_COLS_V1_0;
|
||||||
|
break;
|
||||||
|
case PGSM_V2_0:
|
||||||
|
expected_columns = PG_STAT_MONITOR_COLS_V2_0;
|
||||||
|
break;
|
||||||
|
case PGSM_V2_1:
|
||||||
|
expected_columns = PG_STAT_MONITOR_COLS_V2_1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("[pg_stat_monitor] pg_stat_monitor_internal: Unknown API version")));
|
||||||
|
}
|
||||||
|
|
||||||
/* Disallow old api usage */
|
/* Disallow old api usage */
|
||||||
if (api_version < PGSM_V2_0)
|
if (api_version < PGSM_V2_0)
|
||||||
|
@ -2148,17 +2295,17 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
/* userid at column number 1 */
|
/* userid at column number 1 */
|
||||||
values[i++] = ObjectIdGetDatum(userid);
|
values[i++] = ObjectIdGetDatum(userid);
|
||||||
|
|
||||||
/* userid at column number 1 */
|
/* username at column number 2 */
|
||||||
values[i++] = CStringGetTextDatum(entry->username);
|
values[i++] = CStringGetTextDatum(entry->username);
|
||||||
|
|
||||||
/* dbid at column number 2 */
|
/* dbid at column number 3 */
|
||||||
values[i++] = ObjectIdGetDatum(dbid);
|
values[i++] = ObjectIdGetDatum(dbid);
|
||||||
|
|
||||||
/* userid at column number 1 */
|
/* datname at column number 4 */
|
||||||
values[i++] = CStringGetTextDatum(entry->datname);
|
values[i++] = CStringGetTextDatum(entry->datname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ip address at column number 3, Superusers or members of
|
* ip address at column number 5, Superusers or members of
|
||||||
* pg_read_all_stats members are allowed
|
* pg_read_all_stats members are allowed
|
||||||
*/
|
*/
|
||||||
if (is_allowed_role || userid == GetUserId())
|
if (is_allowed_role || userid == GetUserId())
|
||||||
|
@ -2166,10 +2313,10 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
else
|
else
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
|
|
||||||
/* queryid at column number 4 */
|
/* queryid at column number 6 */
|
||||||
values[i++] = UInt64GetDatum(queryid);
|
values[i++] = UInt64GetDatum(queryid);
|
||||||
|
|
||||||
/* planid at column number 5 */
|
/* planid at column number 7 */
|
||||||
if (planid)
|
if (planid)
|
||||||
{
|
{
|
||||||
values[i++] = UInt64GetDatum(planid);
|
values[i++] = UInt64GetDatum(planid);
|
||||||
|
@ -2184,12 +2331,12 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
{
|
{
|
||||||
char *enc;
|
char *enc;
|
||||||
|
|
||||||
/* query at column number 6 */
|
/* query at column number 8 */
|
||||||
enc = pg_any_to_server(query_txt, strlen(query_txt), GetDatabaseEncoding());
|
enc = pg_any_to_server(query_txt, strlen(query_txt), GetDatabaseEncoding());
|
||||||
values[i++] = CStringGetTextDatum(enc);
|
values[i++] = CStringGetTextDatum(enc);
|
||||||
if (enc != query_txt)
|
if (enc != query_txt)
|
||||||
pfree(enc);
|
pfree(enc);
|
||||||
/* plan at column number 7 */
|
/* plan at column number 9 */
|
||||||
if (planid && tmp.planinfo.plan_text[0])
|
if (planid && tmp.planinfo.plan_text[0])
|
||||||
values[i++] = CStringGetTextDatum(tmp.planinfo.plan_text);
|
values[i++] = CStringGetTextDatum(tmp.planinfo.plan_text);
|
||||||
else
|
else
|
||||||
|
@ -2197,25 +2344,26 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* query at column number 6 */
|
/* query at column number 8 */
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
/* plan at column number 7 */
|
/* plan at column number 9 */
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* query text at column number 6 */
|
/* query text and plan at column number 8 and 9 */
|
||||||
values[i++] = CStringGetTextDatum("<insufficient privilege>");
|
values[i++] = CStringGetTextDatum("<insufficient privilege>");
|
||||||
values[i++] = CStringGetTextDatum("<insufficient privilege>");
|
values[i++] = CStringGetTextDatum("<insufficient privilege>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pgsm_query_id at column number 10 */
|
||||||
if (pgsm_query_id)
|
if (pgsm_query_id)
|
||||||
values[i++] = UInt64GetDatum(pgsm_query_id);
|
values[i++] = UInt64GetDatum(pgsm_query_id);
|
||||||
else
|
else
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
|
|
||||||
/* parentid at column number 9 */
|
/* parentid at column number 11 */
|
||||||
if (tmp.info.parentid != UINT64CONST(0))
|
if (tmp.info.parentid != UINT64CONST(0))
|
||||||
{
|
{
|
||||||
values[i++] = UInt64GetDatum(tmp.info.parentid);
|
values[i++] = UInt64GetDatum(tmp.info.parentid);
|
||||||
|
@ -2227,13 +2375,13 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* application_name at column number 10 */
|
/* application_name at column number 15 */
|
||||||
if (strlen(tmp.info.application_name) > 0)
|
if (strlen(tmp.info.application_name) > 0)
|
||||||
values[i++] = CStringGetTextDatum(tmp.info.application_name);
|
values[i++] = CStringGetTextDatum(tmp.info.application_name);
|
||||||
else
|
else
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
|
|
||||||
/* relations at column number 10 */
|
/* relations at column number 14 */
|
||||||
if (tmp.info.num_relations > 0)
|
if (tmp.info.num_relations > 0)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
@ -2262,28 +2410,28 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
else
|
else
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
|
|
||||||
/* cmd_type at column number 11 */
|
/* cmd_type at column number 15 */
|
||||||
if (tmp.info.cmd_type == CMD_NOTHING)
|
if (tmp.info.cmd_type == CMD_NOTHING)
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
else
|
else
|
||||||
values[i++] = Int64GetDatumFast((int64) tmp.info.cmd_type);
|
values[i++] = Int64GetDatumFast((int64) tmp.info.cmd_type);
|
||||||
|
|
||||||
/* elevel at column number 12 */
|
/* elevel at column number 16 */
|
||||||
values[i++] = Int64GetDatumFast(tmp.error.elevel);
|
values[i++] = Int64GetDatumFast(tmp.error.elevel);
|
||||||
|
|
||||||
/* sqlcode at column number 13 */
|
/* sqlcode at column number 17 */
|
||||||
if (strlen(tmp.error.sqlcode) == 0)
|
if (strlen(tmp.error.sqlcode) == 0)
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
else
|
else
|
||||||
values[i++] = CStringGetTextDatum(tmp.error.sqlcode);
|
values[i++] = CStringGetTextDatum(tmp.error.sqlcode);
|
||||||
|
|
||||||
/* message at column number 14 */
|
/* message at column number 18 */
|
||||||
if (strlen(tmp.error.message) == 0)
|
if (strlen(tmp.error.message) == 0)
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
else
|
else
|
||||||
values[i++] = CStringGetTextDatum(tmp.error.message);
|
values[i++] = CStringGetTextDatum(tmp.error.message);
|
||||||
|
|
||||||
/* bucket_start_time at column number 15 */
|
/* bucket_start_time at column number 19 */
|
||||||
values[i++] = TimestampTzGetDatum(pgsm->bucket_start_time[entry->key.bucket_id]);
|
values[i++] = TimestampTzGetDatum(pgsm->bucket_start_time[entry->key.bucket_id]);
|
||||||
|
|
||||||
if (tmp.calls.calls == 0)
|
if (tmp.calls.calls == 0)
|
||||||
|
@ -2293,29 +2441,29 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
tmp.resp_calls[0]++;
|
tmp.resp_calls[0]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calls at column number 16 */
|
/* calls at column number 20 */
|
||||||
values[i++] = Int64GetDatumFast(tmp.calls.calls);
|
values[i++] = Int64GetDatumFast(tmp.calls.calls);
|
||||||
|
|
||||||
/* total_time at column number 17 */
|
/* total_time at column number 21 */
|
||||||
values[i++] = Float8GetDatumFast(tmp.time.total_time);
|
values[i++] = Float8GetDatumFast(tmp.time.total_time);
|
||||||
|
|
||||||
/* min_time at column number 18 */
|
/* min_time at column number 22 */
|
||||||
values[i++] = Float8GetDatumFast(tmp.time.min_time);
|
values[i++] = Float8GetDatumFast(tmp.time.min_time);
|
||||||
|
|
||||||
/* max_time at column number 19 */
|
/* max_time at column number 23 */
|
||||||
values[i++] = Float8GetDatumFast(tmp.time.max_time);
|
values[i++] = Float8GetDatumFast(tmp.time.max_time);
|
||||||
|
|
||||||
/* mean_time at column number 20 */
|
/* mean_time at column number 24 */
|
||||||
values[i++] = Float8GetDatumFast(tmp.time.mean_time);
|
values[i++] = Float8GetDatumFast(tmp.time.mean_time);
|
||||||
if (tmp.calls.calls > 1)
|
if (tmp.calls.calls > 1)
|
||||||
stddev = sqrt(tmp.time.sum_var_time / tmp.calls.calls);
|
stddev = sqrt(tmp.time.sum_var_time / tmp.calls.calls);
|
||||||
else
|
else
|
||||||
stddev = 0.0;
|
stddev = 0.0;
|
||||||
|
|
||||||
/* calls at column number 21 */
|
/* stddev_exec_time at column number 25 */
|
||||||
values[i++] = Float8GetDatumFast(stddev);
|
values[i++] = Float8GetDatumFast(stddev);
|
||||||
|
|
||||||
/* calls at column number 22 */
|
/* rows at column number 26 */
|
||||||
values[i++] = Int64GetDatumFast(tmp.calls.rows);
|
values[i++] = Int64GetDatumFast(tmp.calls.rows);
|
||||||
|
|
||||||
if (tmp.calls.calls == 0)
|
if (tmp.calls.calls == 0)
|
||||||
|
@ -2325,29 +2473,29 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
tmp.resp_calls[0]++;
|
tmp.resp_calls[0]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calls at column number 23 */
|
/* plans at column number 27 */
|
||||||
values[i++] = Int64GetDatumFast(tmp.plancalls.calls);
|
values[i++] = Int64GetDatumFast(tmp.plancalls.calls);
|
||||||
|
|
||||||
/* total_time at column number 24 */
|
/* total_plan_time at column number 28 */
|
||||||
values[i++] = Float8GetDatumFast(tmp.plantime.total_time);
|
values[i++] = Float8GetDatumFast(tmp.plantime.total_time);
|
||||||
|
|
||||||
/* min_time at column number 25 */
|
/* min_plan_time at column number 29 */
|
||||||
values[i++] = Float8GetDatumFast(tmp.plantime.min_time);
|
values[i++] = Float8GetDatumFast(tmp.plantime.min_time);
|
||||||
|
|
||||||
/* max_time at column number 26 */
|
/* max_plan_time at column number 30 */
|
||||||
values[i++] = Float8GetDatumFast(tmp.plantime.max_time);
|
values[i++] = Float8GetDatumFast(tmp.plantime.max_time);
|
||||||
|
|
||||||
/* mean_time at column number 27 */
|
/* mean_plan_time at column number 31 */
|
||||||
values[i++] = Float8GetDatumFast(tmp.plantime.mean_time);
|
values[i++] = Float8GetDatumFast(tmp.plantime.mean_time);
|
||||||
if (tmp.plancalls.calls > 1)
|
if (tmp.plancalls.calls > 1)
|
||||||
stddev = sqrt(tmp.plantime.sum_var_time / tmp.plancalls.calls);
|
stddev = sqrt(tmp.plantime.sum_var_time / tmp.plancalls.calls);
|
||||||
else
|
else
|
||||||
stddev = 0.0;
|
stddev = 0.0;
|
||||||
|
|
||||||
/* calls at column number 28 */
|
/* stddev_plan_time at column number 32 */
|
||||||
values[i++] = Float8GetDatumFast(stddev);
|
values[i++] = Float8GetDatumFast(stddev);
|
||||||
|
|
||||||
/* blocks are from column number 29 - 40 */
|
/* blocks are from column number 33 - 48 */
|
||||||
values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_hit);
|
values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_hit);
|
||||||
values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_read);
|
values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_read);
|
||||||
values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_dirtied);
|
values[i++] = Int64GetDatumFast(tmp.blocks.shared_blks_dirtied);
|
||||||
|
@ -2358,27 +2506,29 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
values[i++] = Int64GetDatumFast(tmp.blocks.local_blks_written);
|
values[i++] = Int64GetDatumFast(tmp.blocks.local_blks_written);
|
||||||
values[i++] = Int64GetDatumFast(tmp.blocks.temp_blks_read);
|
values[i++] = Int64GetDatumFast(tmp.blocks.temp_blks_read);
|
||||||
values[i++] = Int64GetDatumFast(tmp.blocks.temp_blks_written);
|
values[i++] = Int64GetDatumFast(tmp.blocks.temp_blks_written);
|
||||||
values[i++] = Float8GetDatumFast(tmp.blocks.blk_read_time);
|
values[i++] = Float8GetDatumFast(tmp.blocks.shared_blk_read_time);
|
||||||
values[i++] = Float8GetDatumFast(tmp.blocks.blk_write_time);
|
values[i++] = Float8GetDatumFast(tmp.blocks.shared_blk_write_time);
|
||||||
|
values[i++] = Float8GetDatumFast(tmp.blocks.local_blk_read_time);
|
||||||
|
values[i++] = Float8GetDatumFast(tmp.blocks.local_blk_write_time);
|
||||||
values[i++] = Float8GetDatumFast(tmp.blocks.temp_blk_read_time);
|
values[i++] = Float8GetDatumFast(tmp.blocks.temp_blk_read_time);
|
||||||
values[i++] = Float8GetDatumFast(tmp.blocks.temp_blk_write_time);
|
values[i++] = Float8GetDatumFast(tmp.blocks.temp_blk_write_time);
|
||||||
|
|
||||||
/* resp_calls at column number 41 */
|
/* resp_calls at column number 49 */
|
||||||
values[i++] = IntArrayGetTextDatum(tmp.resp_calls, hist_bucket_count_total);
|
values[i++] = IntArrayGetTextDatum(tmp.resp_calls, hist_bucket_count_total);
|
||||||
|
|
||||||
/* utime at column number 42 */
|
/* cpu_user_time at column number 50 */
|
||||||
values[i++] = Float8GetDatumFast(tmp.sysinfo.utime);
|
values[i++] = Float8GetDatumFast(tmp.sysinfo.utime);
|
||||||
|
|
||||||
/* stime at column number 43 */
|
/* cpu_sys_time at column number 51 */
|
||||||
values[i++] = Float8GetDatumFast(tmp.sysinfo.stime);
|
values[i++] = Float8GetDatumFast(tmp.sysinfo.stime);
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
Datum wal_bytes;
|
Datum wal_bytes;
|
||||||
|
|
||||||
/* wal_records at column number 44 */
|
/* wal_records at column number 52 */
|
||||||
values[i++] = Int64GetDatumFast(tmp.walusage.wal_records);
|
values[i++] = Int64GetDatumFast(tmp.walusage.wal_records);
|
||||||
|
|
||||||
/* wal_fpi at column number 45 */
|
/* wal_fpi at column number 53 */
|
||||||
values[i++] = Int64GetDatumFast(tmp.walusage.wal_fpi);
|
values[i++] = Int64GetDatumFast(tmp.walusage.wal_fpi);
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, UINT64_FORMAT, tmp.walusage.wal_bytes);
|
snprintf(buf, sizeof buf, UINT64_FORMAT, tmp.walusage.wal_bytes);
|
||||||
|
@ -2388,15 +2538,16 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
CStringGetDatum(buf),
|
CStringGetDatum(buf),
|
||||||
ObjectIdGetDatum(0),
|
ObjectIdGetDatum(0),
|
||||||
Int32GetDatum(-1));
|
Int32GetDatum(-1));
|
||||||
/* wal_bytes at column number 46 */
|
/* wal_bytes at column number 54 */
|
||||||
values[i++] = wal_bytes;
|
values[i++] = wal_bytes;
|
||||||
|
|
||||||
/* application_name at column number 47 */
|
/* application_name at column number 55 */
|
||||||
if (strlen(tmp.info.comments) > 0)
|
if (strlen(tmp.info.comments) > 0)
|
||||||
values[i++] = CStringGetTextDatum(tmp.info.comments);
|
values[i++] = CStringGetTextDatum(tmp.info.comments);
|
||||||
else
|
else
|
||||||
nulls[i++] = true;
|
nulls[i++] = true;
|
||||||
|
|
||||||
|
/* blocks are from column number 56 - 63 */
|
||||||
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_functions);
|
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_functions);
|
||||||
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_generation_time);
|
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_generation_time);
|
||||||
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_inlining_count);
|
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_inlining_count);
|
||||||
|
@ -2405,8 +2556,18 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_optimization_time);
|
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_optimization_time);
|
||||||
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_emission_count);
|
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_emission_count);
|
||||||
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_emission_time);
|
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_emission_time);
|
||||||
|
values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_deform_count);
|
||||||
|
values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_deform_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* at column number 64 */
|
||||||
|
values[i++] = TimestampTzGetDatum(entry->stats_since);
|
||||||
|
values[i++] = TimestampTzGetDatum(entry->minmax_stats_since);
|
||||||
|
|
||||||
|
/* toplevel at column number 66 */
|
||||||
values[i++] = BoolGetDatum(toplevel);
|
values[i++] = BoolGetDatum(toplevel);
|
||||||
|
|
||||||
|
/* bucket_done at column number 67 */
|
||||||
values[i++] = BoolGetDatum(pg_atomic_read_u64(&pgsm->current_wbucket) != bucketid);
|
values[i++] = BoolGetDatum(pg_atomic_read_u64(&pgsm->current_wbucket) != bucketid);
|
||||||
|
|
||||||
/* clean up and return the tuplestore */
|
/* clean up and return the tuplestore */
|
||||||
|
@ -2420,9 +2581,6 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
|
||||||
/* clean up and return the tuplestore */
|
/* clean up and return the tuplestore */
|
||||||
pgsm_hash_seq_term(&hstat);
|
pgsm_hash_seq_term(&hstat);
|
||||||
LWLockRelease(pgsm->lock);
|
LWLockRelease(pgsm->lock);
|
||||||
|
|
||||||
|
|
||||||
tuplestore_donestoring(tupstore);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64
|
static uint64
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# pg_stat_monitor extension
|
# pg_stat_monitor extension
|
||||||
comment = 'The pg_stat_monitor is a PostgreSQL Query Performance Monitoring tool, based on PostgreSQL contrib module pg_stat_statements. pg_stat_monitor provides aggregated statistics, client information, plan details including plan, and histogram information.'
|
comment = 'The pg_stat_monitor is a PostgreSQL Query Performance Monitoring tool, based on PostgreSQL contrib module pg_stat_statements. pg_stat_monitor provides aggregated statistics, client information, plan details including plan, and histogram information.'
|
||||||
default_version = '2.0'
|
default_version = '2.1'
|
||||||
module_pathname = '$libdir/pg_stat_monitor'
|
module_pathname = '$libdir/pg_stat_monitor'
|
||||||
relocatable = true
|
relocatable = true
|
||||||
|
|
|
@ -284,19 +284,21 @@ typedef struct Blocks
|
||||||
int64 local_blks_written; /* # of local disk blocks written */
|
int64 local_blks_written; /* # of local disk blocks written */
|
||||||
int64 temp_blks_read; /* # of temp blocks read */
|
int64 temp_blks_read; /* # of temp blocks read */
|
||||||
int64 temp_blks_written; /* # of temp blocks written */
|
int64 temp_blks_written; /* # of temp blocks written */
|
||||||
double blk_read_time; /* time spent reading, in msec */
|
double shared_blk_read_time; /* time spent reading shared blocks, in msec */
|
||||||
double blk_write_time; /* time spent writing, in msec */
|
double shared_blk_write_time; /* time spent writing shared blocks, in msec */
|
||||||
|
double local_blk_read_time; /* time spent reading local blocks, in msec */
|
||||||
|
double local_blk_write_time; /* time spent writing local blocks, in msec */
|
||||||
double temp_blk_read_time; /* time spent reading temp blocks, in msec */
|
double temp_blk_read_time; /* time spent reading temp blocks, in msec */
|
||||||
double temp_blk_write_time; /* time spent writing temp blocks, in
|
double temp_blk_write_time; /* time spent writing temp blocks, in msec */
|
||||||
* msec */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variables for local entry. The values to be passed to pgsm_update_entry
|
* Variables for local entry. The values to be passed to pgsm_update_entry
|
||||||
* from pgsm_store.
|
* from pgsm_store.
|
||||||
*/
|
*/
|
||||||
instr_time instr_blk_read_time; /* time spent reading blocks */
|
instr_time instr_shared_blk_read_time; /* time spent reading shared blocks */
|
||||||
instr_time instr_blk_write_time; /* time spent writing blocks */
|
instr_time instr_shared_blk_write_time; /* time spent writing shared blocks */
|
||||||
|
instr_time instr_local_blk_read_time; /* time spent reading local blocks */
|
||||||
|
instr_time instr_local_blk_write_time; /* time spent writing local blocks */
|
||||||
instr_time instr_temp_blk_read_time; /* time spent reading temp blocks */
|
instr_time instr_temp_blk_read_time; /* time spent reading temp blocks */
|
||||||
instr_time instr_temp_blk_write_time; /* time spent writing temp blocks */
|
instr_time instr_temp_blk_write_time; /* time spent writing temp blocks */
|
||||||
} Blocks;
|
} Blocks;
|
||||||
|
@ -307,6 +309,9 @@ typedef struct JitInfo
|
||||||
double jit_generation_time; /* total time to generate jit code */
|
double jit_generation_time; /* total time to generate jit code */
|
||||||
int64 jit_inlining_count; /* number of times inlining time has been
|
int64 jit_inlining_count; /* number of times inlining time has been
|
||||||
* > 0 */
|
* > 0 */
|
||||||
|
double jit_deform_time; /* total time to deform tuples in jit code */
|
||||||
|
int64 jit_deform_count; /* number of times deform time has been >
|
||||||
|
* 0 */
|
||||||
double jit_inlining_time; /* total time to inline jit code */
|
double jit_inlining_time; /* total time to inline jit code */
|
||||||
int64 jit_optimization_count; /* number of times optimization time
|
int64 jit_optimization_count; /* number of times optimization time
|
||||||
* has been > 0 */
|
* has been > 0 */
|
||||||
|
@ -321,6 +326,7 @@ typedef struct JitInfo
|
||||||
*/
|
*/
|
||||||
instr_time instr_generation_counter; /* generation counter */
|
instr_time instr_generation_counter; /* generation counter */
|
||||||
instr_time instr_inlining_counter; /* inlining counter */
|
instr_time instr_inlining_counter; /* inlining counter */
|
||||||
|
instr_time instr_deform_counter; /* deform counter */
|
||||||
instr_time instr_optimization_counter; /* optimization counter */
|
instr_time instr_optimization_counter; /* optimization counter */
|
||||||
instr_time instr_emission_counter; /* emission counter */
|
instr_time instr_emission_counter; /* emission counter */
|
||||||
} JitInfo;
|
} JitInfo;
|
||||||
|
@ -370,6 +376,8 @@ typedef struct pgsmEntry
|
||||||
char username[NAMEDATALEN]; /* user name */
|
char username[NAMEDATALEN]; /* user name */
|
||||||
Counters counters; /* the statistics for this query */
|
Counters counters; /* the statistics for this query */
|
||||||
int encoding; /* query text encoding */
|
int encoding; /* query text encoding */
|
||||||
|
TimestampTz stats_since; /* timestamp of entry allocation */
|
||||||
|
TimestampTz minmax_stats_since; /* timestamp of last min/max values reset */
|
||||||
slock_t mutex; /* protects the counters only */
|
slock_t mutex; /* protects the counters only */
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,9 +24,10 @@ SELECT routine_schema, routine_name, routine_type, data_type FROM information_sc
|
||||||
public | pgsm_create_13_view | FUNCTION | integer
|
public | pgsm_create_13_view | FUNCTION | integer
|
||||||
public | pgsm_create_14_view | FUNCTION | integer
|
public | pgsm_create_14_view | FUNCTION | integer
|
||||||
public | pgsm_create_15_view | FUNCTION | integer
|
public | pgsm_create_15_view | FUNCTION | integer
|
||||||
|
public | pgsm_create_17_view | FUNCTION | integer
|
||||||
public | pgsm_create_view | FUNCTION | integer
|
public | pgsm_create_view | FUNCTION | integer
|
||||||
public | range | FUNCTION | ARRAY
|
public | range | FUNCTION | ARRAY
|
||||||
(13 rows)
|
(14 rows)
|
||||||
|
|
||||||
SET ROLE u1;
|
SET ROLE u1;
|
||||||
SELECT routine_schema, routine_name, routine_type, data_type FROM information_schema.routines WHERE routine_schema = 'public' ORDER BY routine_name COLLATE "C";
|
SELECT routine_schema, routine_name, routine_type, data_type FROM information_schema.routines WHERE routine_schema = 'public' ORDER BY routine_name COLLATE "C";
|
||||||
|
|
|
@ -24,9 +24,10 @@ SELECT routine_schema, routine_name, routine_type, data_type FROM information_sc
|
||||||
public | pgsm_create_13_view | FUNCTION | integer
|
public | pgsm_create_13_view | FUNCTION | integer
|
||||||
public | pgsm_create_14_view | FUNCTION | integer
|
public | pgsm_create_14_view | FUNCTION | integer
|
||||||
public | pgsm_create_15_view | FUNCTION | integer
|
public | pgsm_create_15_view | FUNCTION | integer
|
||||||
|
public | pgsm_create_17_view | FUNCTION | integer
|
||||||
public | pgsm_create_view | FUNCTION | integer
|
public | pgsm_create_view | FUNCTION | integer
|
||||||
public | range | FUNCTION | ARRAY
|
public | range | FUNCTION | ARRAY
|
||||||
(13 rows)
|
(14 rows)
|
||||||
|
|
||||||
SET ROLE u1;
|
SET ROLE u1;
|
||||||
SELECT routine_schema, routine_name, routine_type, data_type FROM information_schema.routines WHERE routine_schema = 'public' ORDER BY routine_name COLLATE "C";
|
SELECT routine_schema, routine_name, routine_type, data_type FROM information_schema.routines WHERE routine_schema = 'public' ORDER BY routine_name COLLATE "C";
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
--
|
||||||
|
-- Statement level tracking
|
||||||
|
--
|
||||||
|
SELECT setting::integer < 140000 AS skip_test FROM pg_settings where name = 'server_version_num' \gset
|
||||||
|
\if :skip_test
|
||||||
|
\quit
|
|
@ -0,0 +1,326 @@
|
||||||
|
--
|
||||||
|
-- Statement level tracking
|
||||||
|
--
|
||||||
|
SELECT setting::integer < 140000 AS skip_test FROM pg_settings where name = 'server_version_num' \gset
|
||||||
|
\if :skip_test
|
||||||
|
\quit
|
||||||
|
\endif
|
||||||
|
CREATE EXTENSION pg_stat_monitor;
|
||||||
|
SET pg_stat_monitor.pgsm_track_utility = TRUE;
|
||||||
|
SET pg_stat_monitor.pgsm_normalized_query = TRUE;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- DO block - top-level tracking.
|
||||||
|
CREATE TABLE stats_track_tab (x int);
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'top';
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
WHERE query LIKE '%DELETE%' ORDER BY query COLLATE "C", toplevel;
|
||||||
|
toplevel | calls | query
|
||||||
|
----------+-------+--------------------------------
|
||||||
|
t | 1 | DELETE FROM stats_track_tab
|
||||||
|
t | 1 | DO $$ +
|
||||||
|
| | BEGIN +
|
||||||
|
| | DELETE FROM stats_track_tab;+
|
||||||
|
| | END; +
|
||||||
|
| | $$ LANGUAGE plpgsql
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- DO block - all-level tracking.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'all';
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END; $$;
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
BEGIN
|
||||||
|
-- this is a SELECT
|
||||||
|
PERFORM 'hello world'::TEXT;
|
||||||
|
END; $$;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
ORDER BY query COLLATE "C", toplevel;
|
||||||
|
toplevel | calls | query
|
||||||
|
----------+-------+----------------------------------------
|
||||||
|
f | 1 | DELETE FROM stats_track_tab
|
||||||
|
t | 1 | DELETE FROM stats_track_tab
|
||||||
|
t | 1 | DO $$ +
|
||||||
|
| | BEGIN +
|
||||||
|
| | DELETE FROM stats_track_tab; +
|
||||||
|
| | END; $$
|
||||||
|
t | 1 | DO LANGUAGE plpgsql $$ +
|
||||||
|
| | BEGIN +
|
||||||
|
| | -- this is a SELECT +
|
||||||
|
| | PERFORM 'hello world'::TEXT; +
|
||||||
|
| | END; $$
|
||||||
|
f | 1 | SELECT $1::TEXT
|
||||||
|
t | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
t | 1 | SET pg_stat_monitor.pgsm_track = 'all'
|
||||||
|
(7 rows)
|
||||||
|
|
||||||
|
-- DO block - top-level tracking without utility.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'top';
|
||||||
|
SET pg_stat_monitor.pgsm_track_utility = FALSE;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END; $$;
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
BEGIN
|
||||||
|
-- this is a SELECT
|
||||||
|
PERFORM 'hello world'::TEXT;
|
||||||
|
END; $$;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
ORDER BY query COLLATE "C", toplevel;
|
||||||
|
toplevel | calls | query
|
||||||
|
----------+-------+--------------------------------
|
||||||
|
t | 2 | DELETE FROM stats_track_tab
|
||||||
|
t | 1 | SELECT $1::TEXT
|
||||||
|
t | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- DO block - all-level tracking without utility.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'all';
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END; $$;
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
BEGIN
|
||||||
|
-- this is a SELECT
|
||||||
|
PERFORM 'hello world'::TEXT;
|
||||||
|
END; $$;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
ORDER BY query COLLATE "C", toplevel;
|
||||||
|
toplevel | calls | query
|
||||||
|
----------+-------+--------------------------------
|
||||||
|
t | 2 | DELETE FROM stats_track_tab
|
||||||
|
t | 1 | SELECT $1::TEXT
|
||||||
|
t | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- PL/pgSQL function - top-level tracking.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'top';
|
||||||
|
SET pg_stat_monitor.pgsm_track_utility = FALSE;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$
|
||||||
|
DECLARE
|
||||||
|
r INTEGER;
|
||||||
|
BEGIN
|
||||||
|
SELECT (i + 1 + 1.0)::INTEGER INTO r;
|
||||||
|
RETURN r;
|
||||||
|
END; $$ LANGUAGE plpgsql;
|
||||||
|
SELECT PLUS_TWO(3);
|
||||||
|
plus_two
|
||||||
|
----------
|
||||||
|
5
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_TWO(7);
|
||||||
|
plus_two
|
||||||
|
----------
|
||||||
|
9
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- SQL function --- use LIMIT to keep it from being inlined
|
||||||
|
CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL;
|
||||||
|
SELECT PLUS_ONE(8);
|
||||||
|
plus_one
|
||||||
|
----------
|
||||||
|
9
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_ONE(10);
|
||||||
|
plus_one
|
||||||
|
----------
|
||||||
|
11
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
calls | rows | query
|
||||||
|
-------+------+--------------------------------
|
||||||
|
2 | 2 | SELECT PLUS_ONE($1)
|
||||||
|
2 | 2 | SELECT PLUS_TWO($1)
|
||||||
|
1 | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- immutable SQL function --- can be executed at plan time
|
||||||
|
CREATE FUNCTION PLUS_THREE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT i + 3 LIMIT 1 $$ IMMUTABLE LANGUAGE SQL;
|
||||||
|
SELECT PLUS_THREE(8);
|
||||||
|
plus_three
|
||||||
|
------------
|
||||||
|
11
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_THREE(10);
|
||||||
|
plus_three
|
||||||
|
------------
|
||||||
|
13
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT toplevel, calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
toplevel | calls | rows | query
|
||||||
|
----------+-------+------+---------------------------------------------------------------------------
|
||||||
|
t | 2 | 2 | SELECT PLUS_ONE($1)
|
||||||
|
t | 2 | 2 | SELECT PLUS_THREE($1)
|
||||||
|
t | 2 | 2 | SELECT PLUS_TWO($1)
|
||||||
|
t | 1 | 3 | SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C"
|
||||||
|
f | 2 | 2 | SELECT i + $2 LIMIT $3
|
||||||
|
t | 1 | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(6 rows)
|
||||||
|
|
||||||
|
-- PL/pgSQL function - all-level tracking.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'all';
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- we drop and recreate the functions to avoid any caching funnies
|
||||||
|
DROP FUNCTION PLUS_ONE(INTEGER);
|
||||||
|
DROP FUNCTION PLUS_TWO(INTEGER);
|
||||||
|
DROP FUNCTION PLUS_THREE(INTEGER);
|
||||||
|
-- PL/pgSQL function
|
||||||
|
CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$
|
||||||
|
DECLARE
|
||||||
|
r INTEGER;
|
||||||
|
BEGIN
|
||||||
|
SELECT (i + 1 + 1.0)::INTEGER INTO r;
|
||||||
|
RETURN r;
|
||||||
|
END; $$ LANGUAGE plpgsql;
|
||||||
|
SELECT PLUS_TWO(-1);
|
||||||
|
plus_two
|
||||||
|
----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_TWO(2);
|
||||||
|
plus_two
|
||||||
|
----------
|
||||||
|
4
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- SQL function --- use LIMIT to keep it from being inlined
|
||||||
|
CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL;
|
||||||
|
SELECT PLUS_ONE(3);
|
||||||
|
plus_one
|
||||||
|
----------
|
||||||
|
4
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_ONE(1);
|
||||||
|
plus_one
|
||||||
|
----------
|
||||||
|
2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
calls | rows | query
|
||||||
|
-------+------+-----------------------------------
|
||||||
|
2 | 2 | SELECT (i + $2 + $3)::INTEGER
|
||||||
|
2 | 2 | SELECT (i + $2)::INTEGER LIMIT $3
|
||||||
|
2 | 2 | SELECT PLUS_ONE($1)
|
||||||
|
2 | 2 | SELECT PLUS_TWO($1)
|
||||||
|
1 | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
-- immutable SQL function --- can be executed at plan time
|
||||||
|
CREATE FUNCTION PLUS_THREE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT i + 3 LIMIT 1 $$ IMMUTABLE LANGUAGE SQL;
|
||||||
|
SELECT PLUS_THREE(8);
|
||||||
|
plus_three
|
||||||
|
------------
|
||||||
|
11
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_THREE(10);
|
||||||
|
plus_three
|
||||||
|
------------
|
||||||
|
13
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT toplevel, calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
toplevel | calls | rows | query
|
||||||
|
----------+-------+------+---------------------------------------------------------------------------
|
||||||
|
f | 2 | 2 | SELECT (i + $2 + $3)::INTEGER
|
||||||
|
f | 2 | 2 | SELECT (i + $2)::INTEGER LIMIT $3
|
||||||
|
t | 2 | 2 | SELECT PLUS_ONE($1)
|
||||||
|
t | 2 | 2 | SELECT PLUS_THREE($1)
|
||||||
|
t | 2 | 2 | SELECT PLUS_TWO($1)
|
||||||
|
t | 1 | 5 | SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C"
|
||||||
|
f | 2 | 2 | SELECT i + $2 LIMIT $3
|
||||||
|
t | 1 | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(8 rows)
|
||||||
|
|
||||||
|
--
|
||||||
|
-- pg_stat_monitor.pgsm_track = none
|
||||||
|
--
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'none';
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 1 AS "one";
|
||||||
|
one
|
||||||
|
-----
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 1 + 1 AS "two";
|
||||||
|
two
|
||||||
|
-----
|
||||||
|
2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
calls | rows | query
|
||||||
|
-------+------+-------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DROP EXTENSION pg_stat_monitor;
|
|
@ -0,0 +1,325 @@
|
||||||
|
--
|
||||||
|
-- Statement level tracking
|
||||||
|
--
|
||||||
|
SELECT setting::integer < 140000 AS skip_test FROM pg_settings where name = 'server_version_num' \gset
|
||||||
|
\if :skip_test
|
||||||
|
\quit
|
||||||
|
\endif
|
||||||
|
CREATE EXTENSION pg_stat_monitor;
|
||||||
|
SET pg_stat_monitor.pgsm_track_utility = TRUE;
|
||||||
|
SET pg_stat_monitor.pgsm_normalized_query = TRUE;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- DO block - top-level tracking.
|
||||||
|
CREATE TABLE stats_track_tab (x int);
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'top';
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
WHERE query LIKE '%DELETE%' ORDER BY query COLLATE "C", toplevel;
|
||||||
|
toplevel | calls | query
|
||||||
|
----------+-------+--------------------------------
|
||||||
|
t | 1 | DELETE FROM stats_track_tab
|
||||||
|
t | 1 | DO $$ +
|
||||||
|
| | BEGIN +
|
||||||
|
| | DELETE FROM stats_track_tab;+
|
||||||
|
| | END; +
|
||||||
|
| | $$ LANGUAGE plpgsql
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- DO block - all-level tracking.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'all';
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END; $$;
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
BEGIN
|
||||||
|
-- this is a SELECT
|
||||||
|
PERFORM 'hello world'::TEXT;
|
||||||
|
END; $$;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
ORDER BY query COLLATE "C", toplevel;
|
||||||
|
toplevel | calls | query
|
||||||
|
----------+-------+----------------------------------------
|
||||||
|
f | 1 | DELETE FROM stats_track_tab
|
||||||
|
t | 1 | DELETE FROM stats_track_tab
|
||||||
|
t | 1 | DO $$ +
|
||||||
|
| | BEGIN +
|
||||||
|
| | DELETE FROM stats_track_tab; +
|
||||||
|
| | END; $$
|
||||||
|
t | 1 | DO LANGUAGE plpgsql $$ +
|
||||||
|
| | BEGIN +
|
||||||
|
| | -- this is a SELECT +
|
||||||
|
| | PERFORM 'hello world'::TEXT; +
|
||||||
|
| | END; $$
|
||||||
|
f | 1 | SELECT $1::TEXT
|
||||||
|
t | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
t | 1 | SET pg_stat_monitor.pgsm_track = 'all'
|
||||||
|
(7 rows)
|
||||||
|
|
||||||
|
-- DO block - top-level tracking without utility.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'top';
|
||||||
|
SET pg_stat_monitor.pgsm_track_utility = FALSE;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END; $$;
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
BEGIN
|
||||||
|
-- this is a SELECT
|
||||||
|
PERFORM 'hello world'::TEXT;
|
||||||
|
END; $$;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
ORDER BY query COLLATE "C", toplevel;
|
||||||
|
toplevel | calls | query
|
||||||
|
----------+-------+--------------------------------
|
||||||
|
t | 1 | DELETE FROM stats_track_tab
|
||||||
|
t | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- DO block - all-level tracking without utility.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'all';
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END; $$;
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
BEGIN
|
||||||
|
-- this is a SELECT
|
||||||
|
PERFORM 'hello world'::TEXT;
|
||||||
|
END; $$;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
ORDER BY query COLLATE "C", toplevel;
|
||||||
|
toplevel | calls | query
|
||||||
|
----------+-------+--------------------------------
|
||||||
|
f | 1 | DELETE FROM stats_track_tab
|
||||||
|
t | 1 | DELETE FROM stats_track_tab
|
||||||
|
f | 1 | SELECT $1::TEXT
|
||||||
|
t | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
-- PL/pgSQL function - top-level tracking.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'top';
|
||||||
|
SET pg_stat_monitor.pgsm_track_utility = FALSE;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$
|
||||||
|
DECLARE
|
||||||
|
r INTEGER;
|
||||||
|
BEGIN
|
||||||
|
SELECT (i + 1 + 1.0)::INTEGER INTO r;
|
||||||
|
RETURN r;
|
||||||
|
END; $$ LANGUAGE plpgsql;
|
||||||
|
SELECT PLUS_TWO(3);
|
||||||
|
plus_two
|
||||||
|
----------
|
||||||
|
5
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_TWO(7);
|
||||||
|
plus_two
|
||||||
|
----------
|
||||||
|
9
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- SQL function --- use LIMIT to keep it from being inlined
|
||||||
|
CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL;
|
||||||
|
SELECT PLUS_ONE(8);
|
||||||
|
plus_one
|
||||||
|
----------
|
||||||
|
9
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_ONE(10);
|
||||||
|
plus_one
|
||||||
|
----------
|
||||||
|
11
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
calls | rows | query
|
||||||
|
-------+------+--------------------------------
|
||||||
|
2 | 2 | SELECT PLUS_ONE($1)
|
||||||
|
2 | 2 | SELECT PLUS_TWO($1)
|
||||||
|
1 | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- immutable SQL function --- can be executed at plan time
|
||||||
|
CREATE FUNCTION PLUS_THREE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT i + 3 LIMIT 1 $$ IMMUTABLE LANGUAGE SQL;
|
||||||
|
SELECT PLUS_THREE(8);
|
||||||
|
plus_three
|
||||||
|
------------
|
||||||
|
11
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_THREE(10);
|
||||||
|
plus_three
|
||||||
|
------------
|
||||||
|
13
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT toplevel, calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
toplevel | calls | rows | query
|
||||||
|
----------+-------+------+---------------------------------------------------------------------------
|
||||||
|
t | 2 | 2 | SELECT PLUS_ONE($1)
|
||||||
|
t | 2 | 2 | SELECT PLUS_THREE($1)
|
||||||
|
t | 2 | 2 | SELECT PLUS_TWO($1)
|
||||||
|
t | 1 | 3 | SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C"
|
||||||
|
t | 1 | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
-- PL/pgSQL function - all-level tracking.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'all';
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- we drop and recreate the functions to avoid any caching funnies
|
||||||
|
DROP FUNCTION PLUS_ONE(INTEGER);
|
||||||
|
DROP FUNCTION PLUS_TWO(INTEGER);
|
||||||
|
DROP FUNCTION PLUS_THREE(INTEGER);
|
||||||
|
-- PL/pgSQL function
|
||||||
|
CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$
|
||||||
|
DECLARE
|
||||||
|
r INTEGER;
|
||||||
|
BEGIN
|
||||||
|
SELECT (i + 1 + 1.0)::INTEGER INTO r;
|
||||||
|
RETURN r;
|
||||||
|
END; $$ LANGUAGE plpgsql;
|
||||||
|
SELECT PLUS_TWO(-1);
|
||||||
|
plus_two
|
||||||
|
----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_TWO(2);
|
||||||
|
plus_two
|
||||||
|
----------
|
||||||
|
4
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- SQL function --- use LIMIT to keep it from being inlined
|
||||||
|
CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL;
|
||||||
|
SELECT PLUS_ONE(3);
|
||||||
|
plus_one
|
||||||
|
----------
|
||||||
|
4
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_ONE(1);
|
||||||
|
plus_one
|
||||||
|
----------
|
||||||
|
2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
calls | rows | query
|
||||||
|
-------+------+-----------------------------------
|
||||||
|
2 | 2 | SELECT (i + $2 + $3)::INTEGER
|
||||||
|
2 | 2 | SELECT (i + $2)::INTEGER LIMIT $3
|
||||||
|
2 | 2 | SELECT PLUS_ONE($1)
|
||||||
|
2 | 2 | SELECT PLUS_TWO($1)
|
||||||
|
1 | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
-- immutable SQL function --- can be executed at plan time
|
||||||
|
CREATE FUNCTION PLUS_THREE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT i + 3 LIMIT 1 $$ IMMUTABLE LANGUAGE SQL;
|
||||||
|
SELECT PLUS_THREE(8);
|
||||||
|
plus_three
|
||||||
|
------------
|
||||||
|
11
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT PLUS_THREE(10);
|
||||||
|
plus_three
|
||||||
|
------------
|
||||||
|
13
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT toplevel, calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
toplevel | calls | rows | query
|
||||||
|
----------+-------+------+---------------------------------------------------------------------------
|
||||||
|
f | 2 | 2 | SELECT (i + $2 + $3)::INTEGER
|
||||||
|
f | 2 | 2 | SELECT (i + $2)::INTEGER LIMIT $3
|
||||||
|
t | 2 | 2 | SELECT PLUS_ONE($1)
|
||||||
|
t | 2 | 2 | SELECT PLUS_THREE($1)
|
||||||
|
t | 2 | 2 | SELECT PLUS_TWO($1)
|
||||||
|
t | 1 | 5 | SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C"
|
||||||
|
f | 2 | 2 | SELECT i + $2 LIMIT $3
|
||||||
|
t | 1 | 1 | SELECT pg_stat_monitor_reset()
|
||||||
|
(8 rows)
|
||||||
|
|
||||||
|
--
|
||||||
|
-- pg_stat_monitor.pgsm_track = none
|
||||||
|
--
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'none';
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 1 AS "one";
|
||||||
|
one
|
||||||
|
-----
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 1 + 1 AS "two";
|
||||||
|
two
|
||||||
|
-----
|
||||||
|
2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
calls | rows | query
|
||||||
|
-------+------+-------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DROP EXTENSION pg_stat_monitor;
|
|
@ -0,0 +1,115 @@
|
||||||
|
CREATE EXTENSION pg_stat_monitor;
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
CREATE DATABASE db2;
|
||||||
|
\c db1
|
||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
CREATE TABLE t2 (b int);
|
||||||
|
CREATE FUNCTION add(integer, integer) RETURNS integer
|
||||||
|
AS 'select $1 + $2;'
|
||||||
|
LANGUAGE SQL
|
||||||
|
IMMUTABLE
|
||||||
|
RETURNS NULL ON NULL INPUT;
|
||||||
|
\c db2
|
||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
CREATE TABLE t3 (c int);
|
||||||
|
CREATE FUNCTION add(integer, integer) RETURNS integer
|
||||||
|
AS 'select $1 + $2;'
|
||||||
|
LANGUAGE SQL
|
||||||
|
IMMUTABLE
|
||||||
|
RETURNS NULL ON NULL INPUT;
|
||||||
|
\c contrib_regression
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c db1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
---
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT *, ADD(1, 2) FROM t1;
|
||||||
|
a | add
|
||||||
|
---+-----
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT * FROM t2;
|
||||||
|
b
|
||||||
|
---
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
-- Check that spaces and comments do not generate a different pgsm_query_id
|
||||||
|
SELECT * FROM t2 --WHATEVER;
|
||||||
|
;
|
||||||
|
b
|
||||||
|
---
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT * FROM t2 /* ...
|
||||||
|
...
|
||||||
|
More comments to check for spaces.
|
||||||
|
*/
|
||||||
|
;
|
||||||
|
b
|
||||||
|
---
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
\c db2
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
---
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT *, ADD(1, 2) FROM t1;
|
||||||
|
a | add
|
||||||
|
---+-----
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
set pg_stat_monitor.pgsm_enable_pgsm_query_id = off;
|
||||||
|
SELECT * FROM t3;
|
||||||
|
c
|
||||||
|
---
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
set pg_stat_monitor.pgsm_enable_pgsm_query_id = on;
|
||||||
|
SELECT * FROM t3 where c = 20;
|
||||||
|
c
|
||||||
|
---
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
\c contrib_regression
|
||||||
|
SELECT datname, pgsm_query_id, query, calls FROM pg_stat_monitor ORDER BY pgsm_query_id, query, datname;
|
||||||
|
datname | pgsm_query_id | query | calls
|
||||||
|
--------------------+---------------------+-----------------------------------------------------+-------
|
||||||
|
contrib_regression | 689150021118383254 | SELECT pg_stat_monitor_reset() | 1
|
||||||
|
db1 | 1897482803466821995 | SELECT * FROM t2 | 3
|
||||||
|
db1 | 1988437669671417938 | SELECT * FROM t1 | 1
|
||||||
|
db2 | 1988437669671417938 | SELECT * FROM t1 | 1
|
||||||
|
db2 | 6220142855706866455 | set pg_stat_monitor.pgsm_enable_pgsm_query_id = on | 1
|
||||||
|
db2 | 6633979598391393345 | SELECT * FROM t3 where c = 20 | 1
|
||||||
|
db1 | 8140395000078788481 | SELECT *, ADD(1, 2) FROM t1 | 1
|
||||||
|
db2 | 8140395000078788481 | SELECT *, ADD(1, 2) FROM t1 | 1
|
||||||
|
db2 | | SELECT * FROM t3 | 1
|
||||||
|
db2 | | set pg_stat_monitor.pgsm_enable_pgsm_query_id = off | 1
|
||||||
|
(10 rows)
|
||||||
|
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c db1
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP FUNCTION ADD;
|
||||||
|
\c db2
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t3;
|
||||||
|
DROP FUNCTION ADD;
|
||||||
|
\c contrib_regression
|
||||||
|
DROP DATABASE db1;
|
||||||
|
DROP DATABASE db2;
|
||||||
|
DROP EXTENSION pg_stat_monitor;
|
|
@ -2,7 +2,7 @@ CREATE EXTENSION pg_stat_monitor;
|
||||||
SELECT pg_stat_monitor_version();
|
SELECT pg_stat_monitor_version();
|
||||||
pg_stat_monitor_version
|
pg_stat_monitor_version
|
||||||
-------------------------
|
-------------------------
|
||||||
2.0.4
|
2.1.0
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
DROP EXTENSION pg_stat_monitor;
|
DROP EXTENSION pg_stat_monitor;
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
--
|
||||||
|
-- Statement level tracking
|
||||||
|
--
|
||||||
|
|
||||||
|
SELECT setting::integer < 140000 AS skip_test FROM pg_settings where name = 'server_version_num' \gset
|
||||||
|
\if :skip_test
|
||||||
|
\quit
|
||||||
|
\endif
|
||||||
|
|
||||||
|
CREATE EXTENSION pg_stat_monitor;
|
||||||
|
SET pg_stat_monitor.pgsm_track_utility = TRUE;
|
||||||
|
SET pg_stat_monitor.pgsm_normalized_query = TRUE;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
|
||||||
|
-- DO block - top-level tracking.
|
||||||
|
CREATE TABLE stats_track_tab (x int);
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'top';
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
WHERE query LIKE '%DELETE%' ORDER BY query COLLATE "C", toplevel;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
|
||||||
|
-- DO block - all-level tracking.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'all';
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END; $$;
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
BEGIN
|
||||||
|
-- this is a SELECT
|
||||||
|
PERFORM 'hello world'::TEXT;
|
||||||
|
END; $$;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
ORDER BY query COLLATE "C", toplevel;
|
||||||
|
|
||||||
|
-- DO block - top-level tracking without utility.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'top';
|
||||||
|
SET pg_stat_monitor.pgsm_track_utility = FALSE;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END; $$;
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
BEGIN
|
||||||
|
-- this is a SELECT
|
||||||
|
PERFORM 'hello world'::TEXT;
|
||||||
|
END; $$;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
ORDER BY query COLLATE "C", toplevel;
|
||||||
|
|
||||||
|
-- DO block - all-level tracking without utility.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'all';
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM stats_track_tab;
|
||||||
|
END; $$;
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
BEGIN
|
||||||
|
-- this is a SELECT
|
||||||
|
PERFORM 'hello world'::TEXT;
|
||||||
|
END; $$;
|
||||||
|
SELECT toplevel, calls, query FROM pg_stat_monitor
|
||||||
|
ORDER BY query COLLATE "C", toplevel;
|
||||||
|
|
||||||
|
-- PL/pgSQL function - top-level tracking.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'top';
|
||||||
|
SET pg_stat_monitor.pgsm_track_utility = FALSE;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$
|
||||||
|
DECLARE
|
||||||
|
r INTEGER;
|
||||||
|
BEGIN
|
||||||
|
SELECT (i + 1 + 1.0)::INTEGER INTO r;
|
||||||
|
RETURN r;
|
||||||
|
END; $$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
SELECT PLUS_TWO(3);
|
||||||
|
SELECT PLUS_TWO(7);
|
||||||
|
|
||||||
|
-- SQL function --- use LIMIT to keep it from being inlined
|
||||||
|
CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL;
|
||||||
|
|
||||||
|
SELECT PLUS_ONE(8);
|
||||||
|
SELECT PLUS_ONE(10);
|
||||||
|
|
||||||
|
SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
|
||||||
|
-- immutable SQL function --- can be executed at plan time
|
||||||
|
CREATE FUNCTION PLUS_THREE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT i + 3 LIMIT 1 $$ IMMUTABLE LANGUAGE SQL;
|
||||||
|
|
||||||
|
SELECT PLUS_THREE(8);
|
||||||
|
SELECT PLUS_THREE(10);
|
||||||
|
|
||||||
|
SELECT toplevel, calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
|
||||||
|
-- PL/pgSQL function - all-level tracking.
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'all';
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
|
||||||
|
-- we drop and recreate the functions to avoid any caching funnies
|
||||||
|
DROP FUNCTION PLUS_ONE(INTEGER);
|
||||||
|
DROP FUNCTION PLUS_TWO(INTEGER);
|
||||||
|
DROP FUNCTION PLUS_THREE(INTEGER);
|
||||||
|
|
||||||
|
-- PL/pgSQL function
|
||||||
|
CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$
|
||||||
|
DECLARE
|
||||||
|
r INTEGER;
|
||||||
|
BEGIN
|
||||||
|
SELECT (i + 1 + 1.0)::INTEGER INTO r;
|
||||||
|
RETURN r;
|
||||||
|
END; $$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
SELECT PLUS_TWO(-1);
|
||||||
|
SELECT PLUS_TWO(2);
|
||||||
|
|
||||||
|
-- SQL function --- use LIMIT to keep it from being inlined
|
||||||
|
CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL;
|
||||||
|
|
||||||
|
SELECT PLUS_ONE(3);
|
||||||
|
SELECT PLUS_ONE(1);
|
||||||
|
|
||||||
|
SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
|
||||||
|
-- immutable SQL function --- can be executed at plan time
|
||||||
|
CREATE FUNCTION PLUS_THREE(i INTEGER) RETURNS INTEGER AS
|
||||||
|
$$ SELECT i + 3 LIMIT 1 $$ IMMUTABLE LANGUAGE SQL;
|
||||||
|
|
||||||
|
SELECT PLUS_THREE(8);
|
||||||
|
SELECT PLUS_THREE(10);
|
||||||
|
|
||||||
|
SELECT toplevel, calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
|
||||||
|
--
|
||||||
|
-- pg_stat_monitor.pgsm_track = none
|
||||||
|
--
|
||||||
|
SET pg_stat_monitor.pgsm_track = 'none';
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
|
||||||
|
SELECT 1 AS "one";
|
||||||
|
SELECT 1 + 1 AS "two";
|
||||||
|
|
||||||
|
SELECT calls, rows, query FROM pg_stat_monitor ORDER BY query COLLATE "C";
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
|
||||||
|
DROP EXTENSION pg_stat_monitor;
|
|
@ -22,7 +22,22 @@ print $conf "shared_preload_libraries = 'pg_stat_monitor'\n";
|
||||||
close $conf;
|
close $conf;
|
||||||
|
|
||||||
# Dictionary for expected PGSM columns names on different PG server versions
|
# Dictionary for expected PGSM columns names on different PG server versions
|
||||||
my %pg_versions_pgsm_columns = ( 16 => "application_name,blk_read_time," .
|
my %pg_versions_pgsm_columns = ( 17 => "application_name,".
|
||||||
|
"bucket,bucket_done,bucket_start_time,calls," .
|
||||||
|
"client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time," .
|
||||||
|
"datname,dbid,elevel,jit_deform_count,jit_deform_time," .
|
||||||
|
"jit_emission_count,jit_emission_time,jit_functions,jit_generation_time," .
|
||||||
|
"jit_inlining_count,jit_inlining_time,jit_optimization_count,jit_optimization_time," .
|
||||||
|
"local_blk_read_time,local_blk_write_time,local_blks_dirtied,local_blks_hit,".
|
||||||
|
"local_blks_read,local_blks_written,max_exec_time,max_plan_time,mean_exec_time," .
|
||||||
|
"mean_plan_time,message,min_exec_time,min_plan_time,minmax_stats_since," .
|
||||||
|
"pgsm_query_id,planid,plans,query,query_plan,queryid,relations,resp_calls,rows," .
|
||||||
|
"shared_blk_read_time,shared_blk_write_time,shared_blks_dirtied," .
|
||||||
|
"shared_blks_hit,shared_blks_read,shared_blks_written,sqlcode,stats_since," .
|
||||||
|
"stddev_exec_time,stddev_plan_time,temp_blk_read_time,temp_blk_write_time," .
|
||||||
|
"temp_blks_read,temp_blks_written,top_query,top_queryid,toplevel," .
|
||||||
|
"total_exec_time,total_plan_time,userid,username,wal_bytes,wal_fpi,wal_records",
|
||||||
|
16 => "application_name,blk_read_time," .
|
||||||
"blk_write_time,bucket,bucket_done,bucket_start_time,calls," .
|
"blk_write_time,bucket,bucket_done,bucket_start_time,calls," .
|
||||||
"client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time," .
|
"client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time," .
|
||||||
"datname,dbid,elevel,jit_emission_count,jit_emission_time,jit_functions," .
|
"datname,dbid,elevel,jit_emission_count,jit_emission_time,jit_functions," .
|
||||||
|
|
|
@ -35,6 +35,15 @@ $node->append_conf('postgresql.conf', "pg_stat_monitor.pgsm_normalized_query = y
|
||||||
my $rt_value = $node->start;
|
my $rt_value = $node->start;
|
||||||
ok($rt_value == 1, "Start Server");
|
ok($rt_value == 1, "Start Server");
|
||||||
|
|
||||||
|
my $col_shared_blk_read_time = "shared_blk_read_time";
|
||||||
|
my $col_shared_blk_write_time = "shared_blk_write_time";
|
||||||
|
|
||||||
|
if ($PGSM::PG_MAJOR_VERSION <= 16)
|
||||||
|
{
|
||||||
|
$col_shared_blk_read_time = "blk_read_time";
|
||||||
|
$col_shared_blk_write_time = "blk_write_time";
|
||||||
|
}
|
||||||
|
|
||||||
# CREATE EXTENSION and change out file permissions
|
# CREATE EXTENSION and change out file permissions
|
||||||
my ($cmdret, $stdout, $stderr) = $node->psql('postgres', 'CREATE EXTENSION pg_stat_statements;', extra_params => ['-a']);
|
my ($cmdret, $stdout, $stderr) = $node->psql('postgres', 'CREATE EXTENSION pg_stat_statements;', extra_params => ['-a']);
|
||||||
ok($cmdret == 0, "CREATE PGSS EXTENSION");
|
ok($cmdret == 0, "CREATE PGSS EXTENSION");
|
||||||
|
@ -78,10 +87,10 @@ ok($cmdret == 0, "Run pgbench");
|
||||||
ok($cmdret == 0, "Run pg_sleep for 2 seconds ");
|
ok($cmdret == 0, "Run pg_sleep for 2 seconds ");
|
||||||
PGSM::append_to_file($stdout);
|
PGSM::append_to_file($stdout);
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT substr(query,0,30),calls, rows, ROUND(total_exec_time::numeric,4) AS total_exec_time, ROUND(min_exec_time::numeric,4) AS min_exec_time, ROUND(max_exec_time::numeric,4) AS max_exec_time, ROUND(mean_exec_time::numeric,4) AS mean_exec_time, ROUND(stddev_exec_time::numeric,4) AS stddev_exec_time, ROUND(blk_read_time::numeric,4) AS blk_read_time, ROUND(blk_write_time::numeric,4) AS blk_write_time FROM pg_stat_statements WHERE query LIKE \'%bench%\' ORDER BY query,calls DESC;', extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT substr(query,0,30),calls, rows, ROUND(total_exec_time::numeric,4) AS total_exec_time, ROUND(min_exec_time::numeric,4) AS min_exec_time, ROUND(max_exec_time::numeric,4) AS max_exec_time, ROUND(mean_exec_time::numeric,4) AS mean_exec_time, ROUND(stddev_exec_time::numeric,4) AS stddev_exec_time, ROUND(${col_shared_blk_read_time}::numeric,4) AS ${col_shared_blk_read_time}, ROUND(${col_shared_blk_write_time}::numeric,4) AS ${col_shared_blk_write_time} FROM pg_stat_statements WHERE query LIKE '%bench%' ORDER BY query,calls DESC;", extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
||||||
PGSM::append_to_debug_file($stdout);
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT bucket, bucket_start_time, queryid, substr(query,0,30) AS query, calls, rows, total_exec_time, min_exec_time, max_exec_time, mean_exec_time, stddev_exec_time, ROUND(blk_read_time::numeric,4) AS blk_read_time, ROUND(blk_write_time::numeric,4) AS blk_write_time, cpu_user_time, cpu_sys_time FROM pg_stat_monitor WHERE query LIKE \'%bench%\' ORDER BY query,calls DESC;', extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT bucket, bucket_start_time, queryid, substr(query,0,30) AS query, calls, rows, total_exec_time, min_exec_time, max_exec_time, mean_exec_time, stddev_exec_time, ROUND(${col_shared_blk_read_time}::numeric,4) AS ${col_shared_blk_read_time}, ROUND(${col_shared_blk_write_time}::numeric,4) AS ${col_shared_blk_write_time}, cpu_user_time, cpu_sys_time FROM pg_stat_monitor WHERE query LIKE '%bench%' ORDER BY query,calls DESC;", extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
||||||
PGSM::append_to_debug_file($stdout);
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT substr(query,0,30) AS query,calls,rows,wal_records,wal_fpi,wal_bytes FROM pg_stat_statements WHERE query LIKE \'%bench%\' ORDER BY query,calls;', extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT substr(query,0,30) AS query,calls,rows,wal_records,wal_fpi,wal_bytes FROM pg_stat_statements WHERE query LIKE \'%bench%\' ORDER BY query,calls;', extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
||||||
|
@ -160,13 +169,13 @@ is($stdout,'t',"Compare: mean_exec_time is equal.");
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Compare: stddev_exec_time is equal.");
|
is($stdout,'t',"Compare: stddev_exec_time is equal.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(ROUND(PGSM.blk_read_time::numeric,4)) = SUM(ROUND(PGSS.blk_read_time::numeric,4)) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%INSERT INTO pgbench_history%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT SUM(ROUND(PGSM.${col_shared_blk_read_time}::numeric,4)) = SUM(ROUND(PGSS.${col_shared_blk_read_time}::numeric,4)) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%INSERT INTO pgbench_history%\' GROUP BY PGSM.query;", extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Compare: blk_read_time is equal.");
|
is($stdout,'t',"Compare: ${col_shared_blk_read_time} is equal.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(ROUND(PGSM.blk_write_time::numeric,4)) = SUM(ROUND(PGSS.blk_write_time::numeric,4)) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%INSERT INTO pgbench_history%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT SUM(ROUND(PGSM.${col_shared_blk_write_time}::numeric,4)) = SUM(ROUND(PGSS.${col_shared_blk_write_time}::numeric,4)) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%INSERT INTO pgbench_history%\' GROUP BY PGSM.query;", extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Compare: blk_write_time is equal.");
|
is($stdout,'t',"Compare: ${col_shared_blk_write_time} is equal.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(PGSM.wal_records) = SUM(PGSS.wal_records) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%INSERT INTO pgbench_history%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(PGSM.wal_records) = SUM(PGSS.wal_records) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%INSERT INTO pgbench_history%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
|
@ -209,13 +218,13 @@ is($stdout,'t',"Compare: mean_exec_time is equal.");
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Compare: stddev_exec_time is equal.");
|
is($stdout,'t',"Compare: stddev_exec_time is equal.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(ROUND(PGSM.blk_read_time::numeric,4)) = SUM(ROUND(PGSS.blk_read_time::numeric,4)) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%SELECT abalance FROM pgbench_accounts%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT SUM(ROUND(PGSM.${col_shared_blk_read_time}::numeric,4)) = SUM(ROUND(PGSS.${col_shared_blk_read_time}::numeric,4)) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%SELECT abalance FROM pgbench_accounts%\' GROUP BY PGSM.query;", extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Compare: blk_read_time is equal.");
|
is($stdout,'t',"Compare: ${col_shared_blk_read_time} is equal.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(ROUND(PGSM.blk_write_time::numeric,4)) = SUM(ROUND(PGSS.blk_write_time::numeric,4)) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%SELECT abalance FROM pgbench_accounts%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT SUM(ROUND(PGSM.${col_shared_blk_write_time}::numeric,4)) = SUM(ROUND(PGSS.${col_shared_blk_write_time}::numeric,4)) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%SELECT abalance FROM pgbench_accounts%\' GROUP BY PGSM.query;", extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Compare: blk_write_time is equal.");
|
is($stdout,'t',"Compare: ${col_shared_blk_write_time} is equal.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(PGSM.wal_records) = SUM(PGSS.wal_records) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%SELECT abalance FROM pgbench_accounts%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(PGSM.wal_records) = SUM(PGSS.wal_records) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%SELECT abalance FROM pgbench_accounts%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
|
@ -258,9 +267,9 @@ is($stdout,'t',"Compare: mean_exec_time is equal.");
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Compare: stddev_exec_time is equal.");
|
is($stdout,'t',"Compare: stddev_exec_time is equal.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(ROUND(PGSM.blk_write_time::numeric,4)) = SUM(ROUND(PGSS.blk_write_time::numeric,4)) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%UPDATE pgbench_accounts%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT SUM(ROUND(PGSM.${col_shared_blk_write_time}::numeric,4)) = SUM(ROUND(PGSS.${col_shared_blk_write_time}::numeric,4)) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%UPDATE pgbench_accounts%\' GROUP BY PGSM.query;", extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Compare: blk_write_time is equal.");
|
is($stdout,'t',"Compare: ${col_shared_blk_write_time} is equal.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(PGSM.wal_records) = SUM(PGSS.wal_records) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%UPDATE pgbench_accounts%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(PGSM.wal_records) = SUM(PGSS.wal_records) FROM pg_stat_monitor AS PGSM INNER JOIN pg_stat_statements AS PGSS ON PGSS.query = PGSM.query WHERE PGSM.query LIKE \'%UPDATE pgbench_accounts%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
|
|
|
@ -35,6 +35,15 @@ $node->append_conf('postgresql.conf', "pg_stat_monitor.pgsm_normalized_query = y
|
||||||
my $rt_value = $node->start;
|
my $rt_value = $node->start;
|
||||||
ok($rt_value == 1, "Start Server");
|
ok($rt_value == 1, "Start Server");
|
||||||
|
|
||||||
|
my $col_shared_blk_read_time = "shared_blk_read_time";
|
||||||
|
my $col_shared_blk_write_time = "shared_blk_write_time";
|
||||||
|
|
||||||
|
if ($PGSM::PG_MAJOR_VERSION <= 16)
|
||||||
|
{
|
||||||
|
$col_shared_blk_read_time = "blk_read_time";
|
||||||
|
$col_shared_blk_write_time = "blk_write_time";
|
||||||
|
}
|
||||||
|
|
||||||
# CREATE EXTENSION and change out file permissions
|
# CREATE EXTENSION and change out file permissions
|
||||||
my ($cmdret, $stdout, $stderr) = $node->psql('postgres', 'CREATE EXTENSION pg_stat_statements;', extra_params => ['-a']);
|
my ($cmdret, $stdout, $stderr) = $node->psql('postgres', 'CREATE EXTENSION pg_stat_statements;', extra_params => ['-a']);
|
||||||
ok($cmdret == 0, "CREATE PGSS EXTENSION");
|
ok($cmdret == 0, "CREATE PGSS EXTENSION");
|
||||||
|
@ -86,7 +95,7 @@ PGSM::append_to_debug_file($stdout);
|
||||||
PGSM::append_to_debug_file($stdout);
|
PGSM::append_to_debug_file($stdout);
|
||||||
PGSM::append_to_debug_file("--------");
|
PGSM::append_to_debug_file("--------");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT substr(query,0,130) AS query, calls, rows, shared_blks_hit, shared_blks_read, shared_blks_dirtied, shared_blks_written, blk_read_time, blk_write_time FROM pg_stat_monitor WHERE query LIKE \'%bench%\' ORDER BY query,calls DESC;', extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT substr(query,0,130) AS query, calls, rows, shared_blks_hit, shared_blks_read, shared_blks_dirtied, shared_blks_written, ${col_shared_blk_read_time}, ${col_shared_blk_write_time} FROM pg_stat_monitor WHERE query LIKE '%bench%' ORDER BY query,calls DESC;", extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
||||||
PGSM::append_to_debug_file($stdout);
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
# Compare values for query 'DELETE FROM pgbench_accounts WHERE $1 = $2'
|
# Compare values for query 'DELETE FROM pgbench_accounts WHERE $1 = $2'
|
||||||
|
@ -106,13 +115,13 @@ is($stdout,'t',"Check: shared_blks_dirtied should not be 0.");
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: shared_blks_written should not be 0.");
|
is($stdout,'t',"Check: shared_blks_written should not be 0.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres','SELECT SUM(PGSM.blk_read_time) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%DELETE FROM pgbench_accounts%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres',"SELECT SUM(PGSM.${col_shared_blk_read_time}) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE '%DELETE FROM pgbench_accounts%' GROUP BY PGSM.query;", extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: blk_read_time should not be 0.");
|
is($stdout,'t',"Check: ${col_shared_blk_read_time} should not be 0.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres','SELECT SUM(PGSM.blk_write_time) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%DELETE FROM pgbench_accounts%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres',"SELECT SUM(PGSM.${col_shared_blk_write_time}) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE '%DELETE FROM pgbench_accounts%' GROUP BY PGSM.query;", extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: blk_write_time should not be 0.");
|
is($stdout,'t',"Check: ${col_shared_blk_write_time} should not be 0.");
|
||||||
|
|
||||||
# Compare values for query 'INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP)'
|
# Compare values for query 'INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP)'
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres','SELECT SUM(PGSM.shared_blks_hit) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%INSERT INTO pgbench_history%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres','SELECT SUM(PGSM.shared_blks_hit) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%INSERT INTO pgbench_history%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
|
@ -127,9 +136,9 @@ is($stdout,'t',"Check: shared_blks_dirtied should not be 0.");
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: shared_blks_written should not be 0.");
|
is($stdout,'t',"Check: shared_blks_written should not be 0.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres','SELECT SUM(PGSM.blk_write_time) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%INSERT INTO pgbench_history%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres',"SELECT SUM(PGSM.${col_shared_blk_write_time}) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE '%INSERT INTO pgbench_history%' GROUP BY PGSM.query;", extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: blk_write_time should not be 0.");
|
is($stdout,'t',"Check: ${col_shared_blk_write_time} should not be 0.");
|
||||||
|
|
||||||
# Compare values for query 'UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2'
|
# Compare values for query 'UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2'
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres','SELECT SUM(PGSM.shared_blks_hit) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%UPDATE pgbench_accounts SET abalance%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres','SELECT SUM(PGSM.shared_blks_hit) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%UPDATE pgbench_accounts SET abalance%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
|
@ -148,13 +157,13 @@ is($stdout,'t',"Check: shared_blks_dirtied should not be 0.");
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: shared_blks_written should not be 0.");
|
is($stdout,'t',"Check: shared_blks_written should not be 0.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres','SELECT SUM(PGSM.blk_read_time) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%UPDATE pgbench_accounts SET abalance%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT SUM(PGSM.${col_shared_blk_read_time}) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE '%UPDATE pgbench_accounts SET abalance%' GROUP BY PGSM.query;", extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: blk_read_time should not be 0.");
|
is($stdout,'t',"Check: ${col_shared_blk_read_time} should not be 0.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres','SELECT SUM(PGSM.blk_write_time) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%UPDATE pgbench_accounts SET abalance%\' GROUP BY PGSM.query;', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres',"SELECT SUM(PGSM.${col_shared_blk_write_time}) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE '%UPDATE pgbench_accounts SET abalance%' GROUP BY PGSM.query;", extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: blk_write_time should not be 0.");
|
is($stdout,'t',"Check: ${col_shared_blk_write_time} should not be 0.");
|
||||||
|
|
||||||
# DROP EXTENSION
|
# DROP EXTENSION
|
||||||
$stdout = $node->safe_psql('postgres', 'DROP EXTENSION pg_stat_monitor;', extra_params => ['-a']);
|
$stdout = $node->safe_psql('postgres', 'DROP EXTENSION pg_stat_monitor;', extra_params => ['-a']);
|
||||||
|
|
|
@ -70,10 +70,26 @@ is($stdout,'t',"Check: local_blks_hit should not be 0.");
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: local_blks_dirtied should not be 0.");
|
is($stdout,'t',"Check: local_blks_dirtied should not be 0.");
|
||||||
|
|
||||||
|
if ($PGSM::PG_MAJOR_VERSION >= 17)
|
||||||
|
{
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(PGSM.local_blk_write_time) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%INSERT INTO t1%\'', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
|
trim($stdout);
|
||||||
|
is($stdout,'t',"Check: local_blk_write_time should not be 0.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Compare values for query 'SELECT * FROM t1'
|
# Compare values for query 'SELECT * FROM t1'
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT PGSM.local_blks_hit != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%FROM t1%\';', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT PGSM.local_blks_hit != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%FROM t1%\';', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: shared_blks_hit should not be 0.");
|
is($stdout,'t',"Check: local_blks_hit should not be 0.");
|
||||||
|
|
||||||
|
# TODO: Find a way how to bypass cache and get real block reads
|
||||||
|
# if ($PGSM::PG_MAJOR_VERSION >= 17)
|
||||||
|
# {
|
||||||
|
# ($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(PGSM.local_blk_read_time) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%FROM t1%\';', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
|
# trim($stdout);
|
||||||
|
# is($stdout,'t',"Check: local_blk_read_time should not be 0.");
|
||||||
|
# }
|
||||||
|
|
||||||
# DROP EXTENSION
|
# DROP EXTENSION
|
||||||
$stdout = $node->safe_psql('postgres', 'DROP EXTENSION pg_stat_monitor;', extra_params => ['-a']);
|
$stdout = $node->safe_psql('postgres', 'DROP EXTENSION pg_stat_monitor;', extra_params => ['-a']);
|
||||||
|
|
|
@ -85,11 +85,22 @@ PGSM::append_to_debug_file($stdout);
|
||||||
# Compare values for query 'SELECT * FROM t1'
|
# Compare values for query 'SELECT * FROM t1'
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT PGSM.temp_blks_read != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%FROM t1%\';', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT PGSM.temp_blks_read != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%FROM t1%\';', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: shared_blks_hit should not be 0.");
|
is($stdout,'t',"Check: temp_blks_read should not be 0.");
|
||||||
|
|
||||||
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT PGSM.temp_blks_written != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%FROM t1%\';', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT PGSM.temp_blks_written != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%FROM t1%\';', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
trim($stdout);
|
trim($stdout);
|
||||||
is($stdout,'t',"Check: temp_blks_read should not be 0.");
|
is($stdout,'t',"Check: temp_blks_written should not be 0.");
|
||||||
|
|
||||||
|
if ($PGSM::PG_MAJOR_VERSION >= 15)
|
||||||
|
{
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(PGSM.temp_blk_read_time) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%FROM t1%\';', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
|
trim($stdout);
|
||||||
|
is($stdout,'t',"Check: temp_blk_read_time should not be 0.");
|
||||||
|
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT SUM(PGSM.temp_blk_write_time) != 0 FROM pg_stat_monitor AS PGSM WHERE PGSM.query LIKE \'%FROM t1%\'', extra_params => ['-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
|
trim($stdout);
|
||||||
|
is($stdout,'t',"Check: temp_blk_write_time should not be 0.");
|
||||||
|
}
|
||||||
|
|
||||||
# DROP EXTENSION
|
# DROP EXTENSION
|
||||||
$stdout = $node->safe_psql('postgres', 'DROP EXTENSION pg_stat_monitor;', extra_params => ['-a']);
|
$stdout = $node->safe_psql('postgres', 'DROP EXTENSION pg_stat_monitor;', extra_params => ['-a']);
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use File::Basename;
|
||||||
|
use File::Compare;
|
||||||
|
use File::Copy;
|
||||||
|
use Text::Trim qw(trim);
|
||||||
|
use Test::More;
|
||||||
|
use lib 't';
|
||||||
|
use pgsm;
|
||||||
|
|
||||||
|
# Get filename and create out file name and dirs where requried
|
||||||
|
PGSM::setup_files_dir(basename($0));
|
||||||
|
|
||||||
|
if ($PGSM::PG_MAJOR_VERSION <= 16)
|
||||||
|
{
|
||||||
|
plan skip_all => "pg_stat_monitor test cases for versions 16 and below.";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create new PostgreSQL node and do initdb
|
||||||
|
my $node = PGSM->pgsm_init_pg();
|
||||||
|
my $pgdata = $node->data_dir;
|
||||||
|
|
||||||
|
# Update postgresql.conf to include/load pg_stat_monitor library
|
||||||
|
$node->append_conf('postgresql.conf', "shared_preload_libraries = 'pg_stat_monitor'");
|
||||||
|
|
||||||
|
# Set change postgresql.conf for this test case.
|
||||||
|
$node->append_conf('postgresql.conf', "pg_stat_monitor.pgsm_bucket_time = 1");
|
||||||
|
$node->append_conf('postgresql.conf', "pg_stat_monitor.pgsm_max_buckets = 3");
|
||||||
|
$node->append_conf('postgresql.conf', "pg_stat_monitor.pgsm_normalized_query = yes");
|
||||||
|
$node->append_conf('postgresql.conf', "pg_stat_monitor.pgsm_track = 'all'");
|
||||||
|
|
||||||
|
# Start server
|
||||||
|
my $rt_value = $node->start;
|
||||||
|
ok($rt_value == 1, "Start Server");
|
||||||
|
|
||||||
|
# Create EXTENSION and change out file permissions
|
||||||
|
my ($cmdret, $stdout, $stderr) = $node->psql('postgres', 'CREATE EXTENSION pg_stat_monitor;', extra_params => ['-a']);
|
||||||
|
ok($cmdret == 0, "Create PGSM EXTENSION");
|
||||||
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
|
# Run 'SELECT pg_stat_monitor settings' and dump output to out file
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name LIKE '%pg_stat_monitor%';", extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
||||||
|
ok($cmdret == 0, "Print PGSM EXTENSION Settings");
|
||||||
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
|
# Run required commands/queries and dump output to out file.
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT pg_stat_monitor_reset();', extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
||||||
|
ok($cmdret == 0, "Reset PGSM EXTENSION");
|
||||||
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT pg_sleep(1);', extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
||||||
|
ok($cmdret == 0, "1 - Run pg_sleep(1)");
|
||||||
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT pg_sleep(1);', extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
||||||
|
ok($cmdret == 0, "2 - Run pg_sleep(1)");
|
||||||
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', 'SELECT pg_sleep(1);', extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
||||||
|
ok($cmdret == 0, "3 - Run pg_sleep(1)");
|
||||||
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
|
# Check that we have more than one bucket
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT COUNT(bucket) != 0 AS PGSM FROM pg_stat_monitor WHERE query LIKE '%sleep%';", extra_params => ['-t', '-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
|
trim($stdout);
|
||||||
|
is($stdout,'t',"Check: we have more that one bucket");
|
||||||
|
|
||||||
|
# Check that stats timestamps are different for each query/bucket
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT COUNT(DISTINCT stats_since) = COUNT(stats_since) AS PGSM FROM pg_stat_monitor WHERE query LIKE '%sleep%';", extra_params => ['-t', '-Pformat=unaligned','-Ptuples_only=on']);
|
||||||
|
trim($stdout);
|
||||||
|
is($stdout,'t',"Check: for every bucket stats_since should be unique");
|
||||||
|
|
||||||
|
# Check that minmax_stats_since always match stats_since
|
||||||
|
($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT COUNT(*) AS ST FROM pg_stat_monitor WHERE query LIKE '%sleep%' AND stats_since != minmax_stats_since;", extra_params => ['-a', '-Pformat=aligned','-Ptuples_only=off']);
|
||||||
|
ok($stdout == 0, "Compare: Calls count is 1");
|
||||||
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
|
# DROP EXTENSION
|
||||||
|
$stdout = $node->safe_psql('postgres', 'DROP EXTENSION pg_stat_monitor;', extra_params => ['-a']);
|
||||||
|
ok($cmdret == 0, "DROP PGSM EXTENSION");
|
||||||
|
PGSM::append_to_debug_file($stdout);
|
||||||
|
|
||||||
|
# Stop the server
|
||||||
|
$node->stop;
|
||||||
|
|
||||||
|
# Done testing for this testcase file.
|
||||||
|
done_testing();
|
|
@ -0,0 +1,151 @@
|
||||||
|
CREATE EXTENSION pg_stat_monitor;
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_query_shared_buffer';
|
||||||
|
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||||
|
------------------------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||||
|
pg_stat_monitor.pgsm_query_shared_buffer | 1 | MB | postmaster | integer | configuration file | 1 | 10000 | | 20 | 1 | f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE database example;
|
||||||
|
SELECT datname, substr(query,0,150) AS query, SUM(calls) AS calls FROM pg_stat_monitor GROUP BY datname, query ORDER BY datname, query, calls DESC Limit 20;
|
||||||
|
datname | query | calls
|
||||||
|
---------+-------------------------------------------------------------------------------------------------------------------------------------------------------+-------
|
||||||
|
example | INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP) | 10000
|
||||||
|
example | SELECT abalance FROM pgbench_accounts WHERE aid = $1 | 10000
|
||||||
|
example | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2 | 10000
|
||||||
|
example | UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2 | 10000
|
||||||
|
example | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2 | 10000
|
||||||
|
example | alter table pgbench_accounts add primary key (aid) | 1
|
||||||
|
example | alter table pgbench_branches add primary key (bid) | 1
|
||||||
|
example | alter table pgbench_tellers add primary key (tid) | 1
|
||||||
|
example | begin | 10001
|
||||||
|
example | commit | 10001
|
||||||
|
example | copy pgbench_accounts from stdin with (freeze on) | 1
|
||||||
|
example | copy pgbench_branches from stdin with (freeze on) | 1
|
||||||
|
example | copy pgbench_tellers from stdin with (freeze on) | 1
|
||||||
|
example | create table pgbench_accounts(aid int not null,bid int,abalance int,filler char(84)) with (fillfactor=100) | 1
|
||||||
|
example | create table pgbench_branches(bid int not null,bbalance int,filler char(88)) with (fillfactor=100) | 1
|
||||||
|
example | create table pgbench_history(tid int,bid int,aid int,delta int,mtime timestamp,filler char(22)) | 1
|
||||||
|
example | create table pgbench_tellers(tid int not null,bid int,tbalance int,filler char(84)) with (fillfactor=100) | 1
|
||||||
|
example | drop table if exists pgbench_accounts, pgbench_branches, pgbench_history, pgbench_tellers | 1
|
||||||
|
example | select count(*) from pgbench_branches | 1
|
||||||
|
example | select o.n, p.partstrat, pg_catalog.count(i.inhparent) from pg_catalog.pg_class as c join pg_catalog.pg_namespace as n on (n.oid = c.relnamespace) cr | 1
|
||||||
|
(20 rows)
|
||||||
|
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_query_shared_buffer';
|
||||||
|
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||||
|
------------------------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||||
|
pg_stat_monitor.pgsm_query_shared_buffer | 2 | MB | postmaster | integer | configuration file | 1 | 10000 | | 20 | 2 | f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT datname, substr(query,0,150) AS query, SUM(calls) AS calls FROM pg_stat_monitor GROUP BY datname, query ORDER BY datname, query, calls DESC Limit 20;
|
||||||
|
datname | query | calls
|
||||||
|
---------+-------------------------------------------------------------------------------------------------------------------------------------------------------+-------
|
||||||
|
example | INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP) | 10000
|
||||||
|
example | SELECT abalance FROM pgbench_accounts WHERE aid = $1 | 10000
|
||||||
|
example | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2 | 10000
|
||||||
|
example | UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2 | 10000
|
||||||
|
example | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2 | 10000
|
||||||
|
example | alter table pgbench_accounts add primary key (aid) | 1
|
||||||
|
example | alter table pgbench_branches add primary key (bid) | 1
|
||||||
|
example | alter table pgbench_tellers add primary key (tid) | 1
|
||||||
|
example | begin | 10001
|
||||||
|
example | commit | 10001
|
||||||
|
example | copy pgbench_accounts from stdin with (freeze on) | 1
|
||||||
|
example | copy pgbench_branches from stdin with (freeze on) | 1
|
||||||
|
example | copy pgbench_tellers from stdin with (freeze on) | 1
|
||||||
|
example | create table pgbench_accounts(aid int not null,bid int,abalance int,filler char(84)) with (fillfactor=100) | 1
|
||||||
|
example | create table pgbench_branches(bid int not null,bbalance int,filler char(88)) with (fillfactor=100) | 1
|
||||||
|
example | create table pgbench_history(tid int,bid int,aid int,delta int,mtime timestamp,filler char(22)) | 1
|
||||||
|
example | create table pgbench_tellers(tid int not null,bid int,tbalance int,filler char(84)) with (fillfactor=100) | 1
|
||||||
|
example | drop table if exists pgbench_accounts, pgbench_branches, pgbench_history, pgbench_tellers | 1
|
||||||
|
example | select count(*) from pgbench_branches | 1
|
||||||
|
example | select o.n, p.partstrat, pg_catalog.count(i.inhparent) from pg_catalog.pg_class as c join pg_catalog.pg_namespace as n on (n.oid = c.relnamespace) cr | 1
|
||||||
|
(20 rows)
|
||||||
|
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_query_shared_buffer';
|
||||||
|
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||||
|
------------------------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||||
|
pg_stat_monitor.pgsm_query_shared_buffer | 20 | MB | postmaster | integer | configuration file | 1 | 10000 | | 20 | 20 | f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT datname, substr(query,0,150) AS query, SUM(calls) AS calls FROM pg_stat_monitor GROUP BY datname, query ORDER BY datname, query, calls DESC Limit 20;
|
||||||
|
datname | query | calls
|
||||||
|
---------+-------------------------------------------------------------------------------------------------------------------------------------------------------+-------
|
||||||
|
example | INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP) | 10000
|
||||||
|
example | SELECT abalance FROM pgbench_accounts WHERE aid = $1 | 10000
|
||||||
|
example | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2 | 10000
|
||||||
|
example | UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2 | 10000
|
||||||
|
example | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2 | 10000
|
||||||
|
example | alter table pgbench_accounts add primary key (aid) | 1
|
||||||
|
example | alter table pgbench_branches add primary key (bid) | 1
|
||||||
|
example | alter table pgbench_tellers add primary key (tid) | 1
|
||||||
|
example | begin | 10001
|
||||||
|
example | commit | 10001
|
||||||
|
example | copy pgbench_accounts from stdin with (freeze on) | 1
|
||||||
|
example | copy pgbench_branches from stdin with (freeze on) | 1
|
||||||
|
example | copy pgbench_tellers from stdin with (freeze on) | 1
|
||||||
|
example | create table pgbench_accounts(aid int not null,bid int,abalance int,filler char(84)) with (fillfactor=100) | 1
|
||||||
|
example | create table pgbench_branches(bid int not null,bbalance int,filler char(88)) with (fillfactor=100) | 1
|
||||||
|
example | create table pgbench_history(tid int,bid int,aid int,delta int,mtime timestamp,filler char(22)) | 1
|
||||||
|
example | create table pgbench_tellers(tid int not null,bid int,tbalance int,filler char(84)) with (fillfactor=100) | 1
|
||||||
|
example | drop table if exists pgbench_accounts, pgbench_branches, pgbench_history, pgbench_tellers | 1
|
||||||
|
example | select count(*) from pgbench_branches | 1
|
||||||
|
example | select o.n, p.partstrat, pg_catalog.count(i.inhparent) from pg_catalog.pg_class as c join pg_catalog.pg_namespace as n on (n.oid = c.relnamespace) cr | 1
|
||||||
|
(20 rows)
|
||||||
|
|
||||||
|
SELECT pg_stat_monitor_reset();
|
||||||
|
pg_stat_monitor_reset
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT name, setting, unit, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, pending_restart FROM pg_settings WHERE name='pg_stat_monitor.pgsm_query_shared_buffer';
|
||||||
|
name | setting | unit | context | vartype | source | min_val | max_val | enumvals | boot_val | reset_val | pending_restart
|
||||||
|
------------------------------------------+---------+------+------------+---------+--------------------+---------+---------+----------+----------+-----------+-----------------
|
||||||
|
pg_stat_monitor.pgsm_query_shared_buffer | 2048 | MB | postmaster | integer | configuration file | 1 | 10000 | | 20 | 2048 | f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT datname, substr(query,0,150) AS query, SUM(calls) AS calls FROM pg_stat_monitor GROUP BY datname, query ORDER BY datname, query, calls DESC Limit 20;
|
||||||
|
datname | query | calls
|
||||||
|
---------+-------------------------------------------------------------------------------------------------------------------------------------------------------+-------
|
||||||
|
example | INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES ($1, $2, $3, $4, CURRENT_TIMESTAMP) | 10000
|
||||||
|
example | SELECT abalance FROM pgbench_accounts WHERE aid = $1 | 10000
|
||||||
|
example | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2 | 10000
|
||||||
|
example | UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2 | 10000
|
||||||
|
example | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2 | 10000
|
||||||
|
example | alter table pgbench_accounts add primary key (aid) | 1
|
||||||
|
example | alter table pgbench_branches add primary key (bid) | 1
|
||||||
|
example | alter table pgbench_tellers add primary key (tid) | 1
|
||||||
|
example | begin | 10001
|
||||||
|
example | commit | 10001
|
||||||
|
example | copy pgbench_accounts from stdin with (freeze on) | 1
|
||||||
|
example | copy pgbench_branches from stdin with (freeze on) | 1
|
||||||
|
example | copy pgbench_tellers from stdin with (freeze on) | 1
|
||||||
|
example | create table pgbench_accounts(aid int not null,bid int,abalance int,filler char(84)) with (fillfactor=100) | 1
|
||||||
|
example | create table pgbench_branches(bid int not null,bbalance int,filler char(88)) with (fillfactor=100) | 1
|
||||||
|
example | create table pgbench_history(tid int,bid int,aid int,delta int,mtime timestamp,filler char(22)) | 1
|
||||||
|
example | create table pgbench_tellers(tid int not null,bid int,tbalance int,filler char(84)) with (fillfactor=100) | 1
|
||||||
|
example | drop table if exists pgbench_accounts, pgbench_branches, pgbench_history, pgbench_tellers | 1
|
||||||
|
example | select count(*) from pgbench_branches | 1
|
||||||
|
example | select o.n, p.partstrat, pg_catalog.count(i.inhparent) from pg_catalog.pg_class as c join pg_catalog.pg_namespace as n on (n.oid = c.relnamespace) cr | 1
|
||||||
|
(20 rows)
|
||||||
|
|
||||||
|
DROP EXTENSION pg_stat_monitor;
|
Loading…
Reference in New Issue