Skip to content

Commit 52677a6

Browse files
committed
Merge branch 'PGPROEE9_6' into PGPROEE9_6_MULTIMASTER
2 parents 5c69322 + fbf45e3 commit 52677a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2512
-688
lines changed

contrib/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ SUBDIRS = \
4444
pgrowlocks \
4545
pgstattuple \
4646
pg_visibility \
47+
pg_wait_sampling \
4748
postgres_fdw \
4849
rum \
4950
seg \

contrib/pg_visibility/pg_visibility--1.1.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ AS 'MODULE_PATHNAME', 'pg_truncate_visibility_map'
6464
LANGUAGE C STRICT
6565
PARALLEL UNSAFE; -- let's not make this any more dangerous
6666

67+
-- Show visibility map and page-level visibility information.
68+
CREATE FUNCTION pg_cfm(regclass, segno int,
69+
physSize OUT int, virtSize OUT int,
70+
usedSize OUT int, generation OUT bigint)
71+
RETURNS record
72+
AS 'MODULE_PATHNAME', 'pg_cfm'
73+
LANGUAGE C STRICT;
74+
6775
-- Don't want these to be available to public.
6876
REVOKE ALL ON FUNCTION pg_visibility_map(regclass, bigint) FROM PUBLIC;
6977
REVOKE ALL ON FUNCTION pg_visibility(regclass, bigint) FROM PUBLIC;

contrib/pg_visibility/pg_visibility.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@
2020
#include "storage/procarray.h"
2121
#include "storage/smgr.h"
2222
#include "utils/rel.h"
23+
#include "storage/cfs.h"
24+
#ifndef WIN32
25+
#include <sys/mman.h>
26+
#endif
27+
#include "portability/mem.h"
28+
#include <sys/file.h>
29+
#include <sys/param.h>
30+
#include <sys/stat.h>
31+
#include <limits.h>
32+
#include <unistd.h>
33+
#include <fcntl.h>
2334

2435
PG_MODULE_MAGIC;
2536

@@ -747,3 +758,53 @@ tuple_all_visible(HeapTuple tup, TransactionId OldestXmin, Buffer buffer)
747758

748759
return true;
749760
}
761+
762+
PG_FUNCTION_INFO_V1(pg_cfm);
763+
764+
Datum
765+
pg_cfm(PG_FUNCTION_ARGS)
766+
{
767+
Oid relid = PG_GETARG_OID(0);
768+
int32 segno = PG_GETARG_INT32(1);
769+
Relation rel = relation_open(relid, AccessShareLock);
770+
char* path = relpathbackend(rel->rd_node, rel->rd_backend, MAIN_FORKNUM);
771+
char* map_path = (char*)palloc(strlen(path) + 16);
772+
int md;
773+
FileMap* map;
774+
TupleDesc tupdesc;
775+
Datum values[4];
776+
bool nulls[4];
777+
778+
if (segno == 0)
779+
sprintf(map_path, "%s.cfm", path);
780+
else
781+
sprintf(map_path, "%s.%u.cfm", path, segno);
782+
783+
md = open(map_path, O_RDWR|PG_BINARY, 0);
784+
785+
map = cfs_mmap(md);
786+
if (map == MAP_FAILED)
787+
elog(ERROR, "pg_cfm failed to read map file %s: %m", map_path);
788+
789+
tupdesc = CreateTemplateTupleDesc(4, false);
790+
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "physSize", INT4OID, -1, 0);
791+
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "virtSize", INT4OID, -1, 0);
792+
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "usedSize", INT4OID, -1, 0);
793+
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "generation", INT8OID, -1, 0);
794+
tupdesc = BlessTupleDesc(tupdesc);
795+
796+
MemSet(nulls, 0, sizeof(nulls));
797+
values[0] = UInt32GetDatum(pg_atomic_read_u32(&map->physSize));
798+
values[1] = UInt32GetDatum(pg_atomic_read_u32(&map->virtSize));
799+
values[2] = UInt32GetDatum(pg_atomic_read_u32(&map->usedSize));
800+
values[3] = UInt64GetDatum(map->generation);
801+
802+
803+
if (cfs_munmap(map) < 0)
804+
elog(ERROR, "pg_cfm failed to unmap file %s: %m", map_path);
805+
if (close(md) < 0)
806+
elog(ERROR, "pg_cfm failed to close file %s: %m", map_path);
807+
relation_close(rel, AccessShareLock);
808+
809+
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
810+
}

contrib/pg_wait_sampling/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.deps
2+
*.o
3+
*.so

contrib/pg_wait_sampling/Makefile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# contrib/pg_wait_sampling/Makefile
2+
3+
MODULE_big = pg_wait_sampling
4+
OBJS = pg_wait_sampling.o collector.o
5+
6+
EXTENSION = pg_wait_sampling
7+
DATA = pg_wait_sampling--1.0.sql
8+
9+
REGRESS = load
10+
11+
EXTRA_REGRESS_OPTS=--temp-config=$(top_srcdir)/$(subdir)/conf.add
12+
13+
ifdef USE_PGXS
14+
PG_CONFIG = pg_config
15+
PGXS := $(shell $(PG_CONFIG) --pgxs)
16+
include $(PGXS)
17+
else
18+
subdir = contrib/pg_wait_sampling
19+
top_builddir = ../..
20+
include $(top_builddir)/src/Makefile.global
21+
include $(top_srcdir)/contrib/contrib-global.mk
22+
endif

contrib/pg_wait_sampling/README.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
pg\_wait\_sampling – sampling based statistics of wait events
2+
=============================================================
3+
4+
Introduction
5+
------------
6+
7+
PostgreSQL 9.6+ provides an information about current wait event of particular
8+
process. However, in order to gather descriptive statistics of server
9+
behavior user have to sample current wait event multiple times.
10+
pg\_wait\_sampling is an extension for collecting sampling statistics of wait
11+
events.
12+
13+
The module must be loaded by adding pg\_wait\_sampling to
14+
shared\_preload\_libraries in postgresql.conf, because it requires additional
15+
shared memory and launches background worker. This means that a server restart
16+
is needed to add or remove the module.
17+
18+
When pg\_wait\_sampling is enabled, it collects two kinds of statistics.
19+
20+
* History of waits events. It's implemented as in-memory ring buffer where
21+
samples of each process wait events are written with given (configurable)
22+
period. Therefore, for each running process user can see some number of
23+
recent samples depending on history size (configurable). Assuming there is
24+
a client who periodically read this history and dump it somewhere, user
25+
can have continuous history.
26+
* Waits profile. It's implemented as in-memory hash table where count
27+
of samples are accumulated per each process and each wait event. This hash
28+
table can be reset by user request. Assuming there is a client who
29+
periodically dumps profile and resets it, user can have statistics of
30+
intensivity of wait events among time.
31+
32+
pg\_wait\_sampling launches special background worker for gathering the
33+
statistics above.
34+
35+
Authors
36+
-------
37+
38+
* Alexander Korotkov <a.korotkov@postgrespro.ru>, Postgres Professional,
39+
Moscow, Russia
40+
41+
Availability
42+
------------
43+
44+
pg\_wait\_sampling is realized as an extension and not available in default
45+
PostgreSQL installation. It is available from
46+
[github](https://github.com/postgrespro/pg_wait_sampling)
47+
under the same license as
48+
[PostgreSQL](http://www.postgresql.org/about/licence/)
49+
and supports PostgreSQL 9.6+.
50+
51+
Installation
52+
------------
53+
54+
pg\_wait\_sampling is PostgreSQL extension which requires PostgreSQL 9.6 or
55+
higher. Before build and install you should ensure following:
56+
57+
* PostgreSQL version is 9.6 or higher.
58+
* You have development package of PostgreSQL installed or you built
59+
PostgreSQL from source.
60+
* Your PATH variable is configured so that pg\_config command available, or
61+
set PG_CONFIG variable.
62+
63+
Typical installation procedure may look like this:
64+
65+
$ git clone https://github.com/postgrespro/pg_wait_sampling.git
66+
$ cd pg_wait_sampling
67+
$ make USE_PGXS=1
68+
$ sudo make USE_PGXS=1 install
69+
$ make USE_PGXS=1 installcheck
70+
$ psql DB -c "CREATE EXTENSION pg_wait_sampling;"
71+
72+
Usage
73+
-----
74+
75+
pg\_wait\_sampling interacts with user by set of views and functions.
76+
77+
pg\_wait\_sampling\_current view – information about current wait events for
78+
all processed including background workers.
79+
80+
| Column name | Column type | Description |
81+
| ----------- | ----------- | ----------------------- |
82+
| pid | int4 | Id of process |
83+
| event_type | text | Name of wait event type |
84+
| event | text | Name of wait event |
85+
86+
pg_wait_sampling_get_current(pid int4) returns the same table for single given
87+
process.
88+
89+
pg\_wait\_sampling\_history view – history of wait events obtained by sampling into
90+
in-memory ring buffer.
91+
92+
| Column name | Column type | Description |
93+
| ----------- | ----------- | ----------------------- |
94+
| pid | int4 | Id of process |
95+
| ts | timestamptz | Sample timestamp |
96+
| event_type | text | Name of wait event type |
97+
| event | text | Name of wait event |
98+
99+
pg\_wait\_sampling\_profile view – profile of wait events obtained by sampling into
100+
in-memory hash table.
101+
102+
| Column name | Column type | Description |
103+
| ----------- | ----------- | ----------------------- |
104+
| pid | int4 | Id of process |
105+
| event_type | text | Name of wait event type |
106+
| event | text | Name of wait event |
107+
| count | text | Count of samples |
108+
109+
pg_wait_sampling_reset_profile() function resets the profile.
110+
111+
The work of wait event statistics collector worker is controlled by following
112+
GUCs.
113+
114+
| Parameter name | Data type | Description | Default value |
115+
| ------------------------------- | --------- | ------------------------------------------- | ------------: |
116+
| pg_wait_sampling.history_size | int4 | Size of history in-memory ring buffer | 5000 |
117+
| pg_wait_sampling.history_period | int4 | Period for history sampling in milliseconds | 10 |
118+
| pg_wait_sampling.profile_period | int4 | Period for profile sampling in milliseconds | 10 |
119+
| pg_wait_sampling.profile_pid | bool | Whether profile should be per pid | true |
120+
121+
If pg\_wait\_sampling.profile\_pid is set to false, sampling profile wouldn't be
122+
collected in per-process manner. In this case the value of pid could would
123+
be always zero and corresponding row contain samples among all the processes.
124+
125+
These GUCs are allowed to be changed by superuser. Also, they are placed into
126+
shared memory. Thus, they could be changed from any backend and affects worker
127+
runtime.
128+
129+
130+
See
131+
[PostgreSQL documentation](http://www.postgresql.org/docs/devel/static/monitoring-stats.html#WAIT-EVENT-TABLE)
132+
for list of possible wait events.
133+
134+
Contribution
135+
------------
136+
137+
Please, notice, that pg\_wait\_sampling is still under development and while
138+
it's stable and tested, it may contains some bugs. Don't hesitate to raise
139+
[issues at github](https://github.com/postgrespro/pg_wait_sampling/issues) with
140+
your bug reports.
141+
142+
If you're lacking of some functionality in pg\_wait\_sampling and feeling power
143+
to implement it then you're welcome to make pull requests.
144+

0 commit comments

Comments
 (0)