Skip to content

Commit f943143

Browse files
committed
Add support for pg_stat_statements queryId
1 parent 98c4d4c commit f943143

8 files changed

+189
-95
lines changed

Makefile

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ MODULE_big = pg_wait_sampling
44
OBJS = pg_wait_sampling.o collector.o
55

66
EXTENSION = pg_wait_sampling
7-
DATA = pg_wait_sampling--1.0.sql
7+
EXTVERSION = 1.1
8+
DATA_built = pg_wait_sampling--$(EXTVERSION).sql
9+
DATA = pg_wait_sampling--1.0--1.1.sql
810

911
REGRESS = load queries
1012

1113
EXTRA_REGRESS_OPTS=--temp-config=$(top_srcdir)/$(subdir)/conf.add
14+
EXTRA_CLEAN = pg_wait_sampling--$(EXTVERSION).sql
1215

1316
ifdef USE_PGXS
1417
PG_CONFIG = pg_config
@@ -20,3 +23,6 @@ top_builddir = ../..
2023
include $(top_builddir)/src/Makefile.global
2124
include $(top_srcdir)/contrib/contrib-global.mk
2225
endif
26+
27+
$(EXTENSION)--$(EXTVERSION).sql: setup.sql
28+
cat $^ > $@

README.md

+27-15
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,22 @@ When `pg_wait_sampling` is enabled, it collects two kinds of statistics.
2727
a client who periodically read this history and dump it somewhere, user
2828
can have continuous history.
2929
* Waits profile. It's implemented as in-memory hash table where count
30-
of samples are accumulated per each process and each wait event. This hash
30+
of samples are accumulated per each process and each wait event
31+
(and each query with `pg_stat_statements`). This hash
3132
table can be reset by user request. Assuming there is a client who
3233
periodically dumps profile and resets it, user can have statistics of
3334
intensivity of wait events among time.
3435

36+
In combination with `pg_stat_statements` this extension can also provide
37+
per query statistics.
38+
3539
`pg_wait_sampling` launches special background worker for gathering the
3640
statistics above.
3741

38-
Authors
39-
-------
40-
41-
* Alexander Korotkov <[email protected]>, Postgres Professional,
42-
Moscow, Russia
43-
4442
Availability
4543
------------
4644

47-
`pg_wait_sampling` is realized as an extension and not available in default
45+
`pg_wait_sampling` is implemented as an extension and not available in default
4846
PostgreSQL installation. It is available from
4947
[github](https://github.com/postgrespro/pg_wait_sampling)
5048
under the same license as
@@ -88,6 +86,7 @@ all processed including background workers.
8886
| pid | int4 | Id of process |
8987
| event_type | text | Name of wait event type |
9088
| event | text | Name of wait event |
89+
| queryid | int8 | Id of query |
9190

9291
`pg_wait_sampling_get_current(pid int4)` returns the same table for single given
9392
process.
@@ -101,6 +100,7 @@ in-memory ring buffer.
101100
| ts | timestamptz | Sample timestamp |
102101
| event_type | text | Name of wait event type |
103102
| event | text | Name of wait event |
103+
| queryid | int8 | Id of query |
104104

105105
`pg_wait_sampling_profile` view – profile of wait events obtained by sampling into
106106
in-memory hash table.
@@ -110,29 +110,33 @@ in-memory hash table.
110110
| pid | int4 | Id of process |
111111
| event_type | text | Name of wait event type |
112112
| event | text | Name of wait event |
113+
| queryid | int8 | Id of query |
113114
| count | text | Count of samples |
114115

115116
`pg_wait_sampling_reset_profile()` function resets the profile.
116117

117118
The work of wait event statistics collector worker is controlled by following
118119
GUCs.
119120

120-
| Parameter name | Data type | Description | Default value |
121-
| ------------------------------- | --------- | ------------------------------------------- | ------------: |
122-
| pg_wait_sampling.history_size | int4 | Size of history in-memory ring buffer | 5000 |
123-
| pg_wait_sampling.history_period | int4 | Period for history sampling in milliseconds | 10 |
124-
| pg_wait_sampling.profile_period | int4 | Period for profile sampling in milliseconds | 10 |
125-
| pg_wait_sampling.profile_pid | bool | Whether profile should be per pid | true |
121+
| Parameter name | Data type | Description | Default value |
122+
| ----------------------------------- | --------- | ------------------------------------------- | ------------: |
123+
| pg_wait_sampling.history_size | int4 | Size of history in-memory ring buffer | 5000 |
124+
| pg_wait_sampling.history_period | int4 | Period for history sampling in milliseconds | 10 |
125+
| pg_wait_sampling.profile_period | int4 | Period for profile sampling in milliseconds | 10 |
126+
| pg_wait_sampling.profile_pid | bool | Whether profile should be per pid | true |
127+
| pg_wait_sampling.profile_queries | bool | Whether profile should be per query | false |
126128

127129
If `pg_wait_sampling.profile_pid` is set to false, sampling profile wouldn't be
128130
collected in per-process manner. In this case the value of pid could would
129131
be always zero and corresponding row contain samples among all the processes.
130132

133+
While `pg_wait_sampling.profile_queries` is set to false `queryid` field in
134+
views will be zero.
135+
131136
These GUCs are allowed to be changed by superuser. Also, they are placed into
132137
shared memory. Thus, they could be changed from any backend and affects worker
133138
runtime.
134139

135-
136140
See
137141
[PostgreSQL documentation](http://www.postgresql.org/docs/devel/static/monitoring-stats.html#WAIT-EVENT-TABLE)
138142
for list of possible wait events.
@@ -148,3 +152,11 @@ your bug reports.
148152
If you're lacking of some functionality in `pg_wait_sampling` and feeling power
149153
to implement it then you're welcome to make pull requests.
150154

155+
Authors
156+
-------
157+
158+
* Alexander Korotkov <[email protected]>, Postgres Professional,
159+
Moscow, Russia
160+
* Ildus Kurbangaliev <[email protected]>, Postgres Professional,
161+
Moscow, Russia
162+

collector.c

+13-3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ register_wait_collector(void)
4949
worker.bgw_main = collector_main;
5050
#endif
5151
snprintf(worker.bgw_name, BGW_MAXLEN, "pg_wait_sampling collector");
52-
worker.bgw_main_arg = (Datum)0;
52+
worker.bgw_main_arg = (Datum) 0;
5353
RegisterBackgroundWorker(&worker);
5454
}
5555

@@ -168,6 +168,12 @@ probe_waits(History *observations, HTAB *profile_hash,
168168
/* Collect next wait event sample */
169169
item.pid = proc->pid;
170170
item.wait_event_info = proc->wait_event_info;
171+
172+
if (collector_hdr->profileQueries)
173+
item.queryId = proc_queryids[i];
174+
else
175+
item.queryId = 0;
176+
171177
item.ts = ts;
172178

173179
/* Write to the history if needed */
@@ -243,9 +249,13 @@ make_profile_hash()
243249

244250
hash_ctl.hash = tag_hash;
245251
hash_ctl.hcxt = TopMemoryContext;
246-
hash_ctl.keysize = offsetof(ProfileItem, count);
247-
hash_ctl.entrysize = sizeof(ProfileItem);
248252

253+
if (collector_hdr->profileQueries)
254+
hash_ctl.keysize = offsetof(ProfileItem, count);
255+
else
256+
hash_ctl.keysize = offsetof(ProfileItem, queryId);
257+
258+
hash_ctl.entrysize = sizeof(ProfileItem);
249259
return hash_create("Waits profile hash", 1024, &hash_ctl,
250260
HASH_FUNCTION | HASH_ELEM);
251261
}

expected/load_1.out

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CREATE EXTENSION pg_wait_sampling;
66
pid | integer | | |
77
event_type | text | | |
88
event | text | | |
9+
queryid | bigint | | |
910

1011
\d pg_wait_sampling_history
1112
View "public.pg_wait_sampling_history"
@@ -15,6 +16,7 @@ CREATE EXTENSION pg_wait_sampling;
1516
ts | timestamp with time zone | | |
1617
event_type | text | | |
1718
event | text | | |
19+
queryid | bigint | | |
1820

1921
\d pg_wait_sampling_profile
2022
View "public.pg_wait_sampling_profile"
@@ -23,6 +25,7 @@ CREATE EXTENSION pg_wait_sampling;
2325
pid | integer | | |
2426
event_type | text | | |
2527
event | text | | |
28+
queryid | bigint | | |
2629
count | bigint | | |
2730

2831
DROP EXTENSION pg_wait_sampling;

pg_wait_sampling--1.0.sql

-57
This file was deleted.

0 commit comments

Comments
 (0)