Skip to content

Commit 034456d

Browse files
author
Sergey Shinderuk
committed
Merge branch 'master' into stable
2 parents b984f33 + 57c1ecf commit 034456d

11 files changed

+319
-224
lines changed

Diff for: .gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
*.o
33
*.so
44
/results
5-
*pg_wait_sampling--1.1.sql
65
.log
76
Dockerfile
7+
/log/

Diff for: .travis.yml

+13-12
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@ script:
1717
- docker-compose run tests
1818

1919
env:
20-
- PG_VERSION=9.6 CHECK_CODE=clang
21-
- PG_VERSION=9.6 CHECK_CODE=cppcheck
22-
- PG_VERSION=9.6 CHECK_CODE=false
23-
- PG_VERSION=10 CHECK_CODE=clang
24-
- PG_VERSION=10 CHECK_CODE=cppcheck
25-
- PG_VERSION=10 CHECK_CODE=false
26-
- PG_VERSION=11 CHECK_CODE=clang
27-
- PG_VERSION=11 CHECK_CODE=false
28-
- PG_VERSION=12 CHECK_CODE=clang
29-
- PG_VERSION=12 CHECK_CODE=false
30-
- PG_VERSION=13 CHECK_CODE=clang
31-
- PG_VERSION=13 CHECK_CODE=false
20+
- PG_VERSION=10 CHECK_CODE=clang
21+
- PG_VERSION=10 CHECK_CODE=cppcheck
22+
- PG_VERSION=10 CHECK_CODE=false
23+
- PG_VERSION=11 CHECK_CODE=clang
24+
- PG_VERSION=11 CHECK_CODE=false
25+
- PG_VERSION=12 CHECK_CODE=clang
26+
- PG_VERSION=12 CHECK_CODE=false
27+
- PG_VERSION=13 CHECK_CODE=clang
28+
- PG_VERSION=13 CHECK_CODE=false
29+
- PG_VERSION=14 CHECK_CODE=clang
30+
- PG_VERSION=14 CHECK_CODE=false
31+
- PG_VERSION=15beta3 CHECK_CODE=clang
32+
- PG_VERSION=15beta3 CHECK_CODE=false

Diff for: META.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "pg_wait_sampling",
33
"abstract": "Sampling based statistics of wait events",
44
"description": "pg_wait_sampling provides functions for detailed per backend and per query statistics about PostgreSQL wait events",
5-
"version": "1.1.3",
5+
"version": "1.1.4",
66
"maintainer": [
77
"Alexander Korotkov <[email protected]>",
88
"Ildus Kurbangaliev <[email protected]>"
@@ -21,7 +21,7 @@
2121
"pg_wait_sampling": {
2222
"file": "pg_wait_sampling--1.1.sql",
2323
"docfile": "README.md",
24-
"version": "1.1.3",
24+
"version": "1.1.4",
2525
"abstract": "Sampling based statistics of wait events"
2626
}
2727
},

Diff for: Makefile

+6-13
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
# contrib/pg_wait_sampling/Makefile
22

33
MODULE_big = pg_wait_sampling
4-
OBJS = pg_wait_sampling.o collector.o compat.o
4+
OBJS = pg_wait_sampling.o collector.o
55

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

119
REGRESS = load queries
1210

1311
EXTRA_REGRESS_OPTS=--temp-config=$(top_srcdir)/$(subdir)/conf.add
14-
EXTRA_CLEAN = pg_wait_sampling--$(EXTVERSION).sql
1512

1613
ifdef USE_PGXS
1714
PG_CONFIG = pg_config
@@ -24,15 +21,11 @@ include $(top_builddir)/src/Makefile.global
2421
include $(top_srcdir)/contrib/contrib-global.mk
2522
endif
2623

27-
$(EXTENSION)--$(EXTVERSION).sql: setup.sql
28-
cat $^ > $@
29-
3024
# Prepare the package for PGXN submission
31-
DISTVERSION := $(shell git tag -l | tail -n 1 | cut -d 'v' -f 2)
32-
package: dist dist/$(EXTENSION)-$(DISTVERSION).zip
25+
package: dist .git
26+
$(eval DISTVERSION := $(shell git tag -l | tail -n 1 | cut -d 'v' -f 2))
27+
$(info Generating zip file for version $(DISTVERSION)...)
28+
git archive --format zip --prefix=$(EXTENSION)-${DISTVERSION}/ --output dist/$(EXTENSION)-${DISTVERSION}.zip HEAD
3329

3430
dist:
3531
mkdir -p dist
36-
37-
dist/$(EXTENSION)-$(DISTVERSION).zip:
38-
git archive --format zip --prefix=$(EXTENSION)-$(DISTVERSION)/ --output $@ HEAD

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ GUCs.
125125
| pg_wait_sampling.history_period | int4 | Period for history sampling in milliseconds | 10 |
126126
| pg_wait_sampling.profile_period | int4 | Period for profile sampling in milliseconds | 10 |
127127
| pg_wait_sampling.profile_pid | bool | Whether profile should be per pid | true |
128-
| pg_wait_sampling.profile_queries | bool | Whether profile should be per query | false |
128+
| pg_wait_sampling.profile_queries | bool | Whether profile should be per query | true |
129129

130130
If `pg_wait_sampling.profile_pid` is set to false, sampling profile wouldn't be
131131
collected in per-process manner. In this case the value of pid could would

Diff for: collector.c

+74-74
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "utils/resowner.h"
2727
#include "pgstat.h"
2828

29+
#include "compat.h"
2930
#include "pg_wait_sampling.h"
3031

3132
static volatile sig_atomic_t shutdown_requested = false;
@@ -36,18 +37,18 @@ static void handle_sigterm(SIGNAL_ARGS);
3637
* Register background worker for collecting waits history.
3738
*/
3839
void
39-
register_wait_collector(void)
40+
pgws_register_wait_collector(void)
4041
{
4142
BackgroundWorker worker;
4243

4344
/* Set up background worker parameters */
4445
memset(&worker, 0, sizeof(worker));
4546
worker.bgw_flags = BGWORKER_SHMEM_ACCESS;
4647
worker.bgw_start_time = BgWorkerStart_ConsistentState;
47-
worker.bgw_restart_time = 0;
48+
worker.bgw_restart_time = 1;
4849
worker.bgw_notify_pid = 0;
4950
snprintf(worker.bgw_library_name, BGW_MAXLEN, "pg_wait_sampling");
50-
snprintf(worker.bgw_function_name, BGW_MAXLEN, CppAsString(collector_main));
51+
snprintf(worker.bgw_function_name, BGW_MAXLEN, CppAsString(pgws_collector_main));
5152
snprintf(worker.bgw_name, BGW_MAXLEN, "pg_wait_sampling collector");
5253
worker.bgw_main_arg = (Datum) 0;
5354
RegisterBackgroundWorker(&worker);
@@ -56,7 +57,7 @@ register_wait_collector(void)
5657
/*
5758
* Allocate memory for waits history.
5859
*/
59-
void
60+
static void
6061
alloc_history(History *observations, int count)
6162
{
6263
observations->items = (HistoryItem *) palloc0(sizeof(HistoryItem) * count);
@@ -150,7 +151,7 @@ probe_waits(History *observations, HTAB *profile_hash,
150151
TimestampTz ts = GetCurrentTimestamp();
151152

152153
/* Realloc waits history if needed */
153-
newSize = collector_hdr->historySize;
154+
newSize = pgws_collector_hdr->historySize;
154155
if (observations->count != newSize)
155156
realloc_history(observations, newSize);
156157

@@ -172,8 +173,8 @@ probe_waits(History *observations, HTAB *profile_hash,
172173
item.pid = proc->pid;
173174
item.wait_event_info = proc->wait_event_info;
174175

175-
if (collector_hdr->profileQueries)
176-
item.queryId = proc_queryids[i];
176+
if (pgws_collector_hdr->profileQueries)
177+
item.queryId = pgws_proc_queryids[i];
177178
else
178179
item.queryId = 0;
179180

@@ -220,7 +221,7 @@ send_history(History *observations, shm_mq_handle *mqh)
220221
else
221222
count = observations->index;
222223

223-
mq_result = shm_mq_send(mqh, sizeof(count), &count, false);
224+
mq_result = shm_mq_send_compat(mqh, sizeof(count), &count, false, true);
224225
if (mq_result == SHM_MQ_DETACHED)
225226
{
226227
ereport(WARNING,
@@ -230,10 +231,11 @@ send_history(History *observations, shm_mq_handle *mqh)
230231
}
231232
for (i = 0; i < count; i++)
232233
{
233-
mq_result = shm_mq_send(mqh,
234+
mq_result = shm_mq_send_compat(mqh,
234235
sizeof(HistoryItem),
235236
&observations->items[i],
236-
false);
237+
false,
238+
true);
237239
if (mq_result == SHM_MQ_DETACHED)
238240
{
239241
ereport(WARNING,
@@ -255,7 +257,7 @@ send_profile(HTAB *profile_hash, shm_mq_handle *mqh)
255257
Size count = hash_get_num_entries(profile_hash);
256258
shm_mq_result mq_result;
257259

258-
mq_result = shm_mq_send(mqh, sizeof(count), &count, false);
260+
mq_result = shm_mq_send_compat(mqh, sizeof(count), &count, false, true);
259261
if (mq_result == SHM_MQ_DETACHED)
260262
{
261263
ereport(WARNING,
@@ -266,7 +268,8 @@ send_profile(HTAB *profile_hash, shm_mq_handle *mqh)
266268
hash_seq_init(&scan_status, profile_hash);
267269
while ((item = (ProfileItem *) hash_seq_search(&scan_status)) != NULL)
268270
{
269-
mq_result = shm_mq_send(mqh, sizeof(ProfileItem), item, false);
271+
mq_result = shm_mq_send_compat(mqh, sizeof(ProfileItem), item, false,
272+
true);
270273
if (mq_result == SHM_MQ_DETACHED)
271274
{
272275
hash_seq_term(&scan_status);
@@ -289,7 +292,7 @@ make_profile_hash()
289292
hash_ctl.hash = tag_hash;
290293
hash_ctl.hcxt = TopMemoryContext;
291294

292-
if (collector_hdr->profileQueries)
295+
if (pgws_collector_hdr->profileQueries)
293296
hash_ctl.keysize = offsetof(ProfileItem, count);
294297
else
295298
hash_ctl.keysize = offsetof(ProfileItem, queryId);
@@ -318,7 +321,7 @@ millisecs_diff(TimestampTz tz1, TimestampTz tz2)
318321
* Main routine of wait history collector.
319322
*/
320323
void
321-
collector_main(Datum main_arg)
324+
pgws_collector_main(Datum main_arg)
322325
{
323326
HTAB *profile_hash = NULL;
324327
History observations;
@@ -337,28 +340,31 @@ collector_main(Datum main_arg)
337340
* any equivalent of the backend's command-read loop, where interrupts can
338341
* be processed immediately, so make sure ImmediateInterruptOK is turned
339342
* off.
343+
*
344+
* We also want to respond to the ProcSignal notifications. This is done
345+
* in the upstream provided procsignal_sigusr1_handler, which is
346+
* automatically used if a bgworker connects to a database. But since our
347+
* worker doesn't connect to any database even though it calls
348+
* InitPostgres, which will still initializze a new backend and thus
349+
* partitipate to the ProcSignal infrastructure.
340350
*/
341351
pqsignal(SIGTERM, handle_sigterm);
352+
pqsignal(SIGUSR1, procsignal_sigusr1_handler);
342353
BackgroundWorkerUnblockSignals();
343-
344-
#if PG_VERSION_NUM >= 110000
345-
InitPostgres(NULL, InvalidOid, NULL, InvalidOid, NULL, false);
346-
#else
347-
InitPostgres(NULL, InvalidOid, NULL, InvalidOid, NULL);
348-
#endif
354+
InitPostgresCompat(NULL, InvalidOid, NULL, InvalidOid, false, false, NULL);
349355
SetProcessingMode(NormalProcessing);
350356

351357
/* Make pg_wait_sampling recognisable in pg_stat_activity */
352358
pgstat_report_appname("pg_wait_sampling collector");
353359

354360
profile_hash = make_profile_hash();
355-
collector_hdr->latch = &MyProc->procLatch;
361+
pgws_collector_hdr->latch = &MyProc->procLatch;
356362

357363
CurrentResourceOwner = ResourceOwnerCreate(NULL, "pg_wait_sampling collector");
358364
collector_context = AllocSetContextCreate(TopMemoryContext,
359365
"pg_wait_sampling context", ALLOCSET_DEFAULT_SIZES);
360366
old_context = MemoryContextSwitchTo(collector_context);
361-
alloc_history(&observations, collector_hdr->historySize);
367+
alloc_history(&observations, pgws_collector_hdr->historySize);
362368
MemoryContextSwitchTo(old_context);
363369

364370
ereport(LOG, (errmsg("pg_wait_sampling collector started")));
@@ -377,21 +383,24 @@ collector_main(Datum main_arg)
377383
bool write_history,
378384
write_profile;
379385

386+
/* We need an explicit call for at least ProcSignal notifications. */
387+
CHECK_FOR_INTERRUPTS();
388+
380389
/* Wait calculate time to next sample for history or profile */
381390
current_ts = GetCurrentTimestamp();
382391

383392
history_diff = millisecs_diff(history_ts, current_ts);
384393
profile_diff = millisecs_diff(profile_ts, current_ts);
385-
history_period = collector_hdr->historyPeriod;
386-
profile_period = collector_hdr->profilePeriod;
394+
history_period = pgws_collector_hdr->historyPeriod;
395+
profile_period = pgws_collector_hdr->profilePeriod;
387396

388397
write_history = (history_diff >= (int64)history_period);
389398
write_profile = (profile_diff >= (int64)profile_period);
390399

391400
if (write_history || write_profile)
392401
{
393402
probe_waits(&observations, profile_hash,
394-
write_history, write_profile, collector_hdr->profilePid);
403+
write_history, write_profile, pgws_collector_hdr->profilePid);
395404

396405
if (write_history)
397406
{
@@ -430,67 +439,58 @@ collector_main(Datum main_arg)
430439
ResetLatch(&MyProc->procLatch);
431440

432441
/* Handle request if any */
433-
if (collector_hdr->request != NO_REQUEST)
442+
if (pgws_collector_hdr->request != NO_REQUEST)
434443
{
435444
LOCKTAG tag;
436-
SHMRequest request = collector_hdr->request;
445+
SHMRequest request;
437446

438-
init_lock_tag(&tag, PGWS_COLLECTOR_LOCK);
447+
pgws_init_lock_tag(&tag, PGWS_COLLECTOR_LOCK);
439448

440449
LockAcquire(&tag, ExclusiveLock, false, false);
441-
collector_hdr->request = NO_REQUEST;
450+
request = pgws_collector_hdr->request;
451+
pgws_collector_hdr->request = NO_REQUEST;
442452

443-
PG_TRY();
453+
if (request == HISTORY_REQUEST || request == PROFILE_REQUEST)
444454
{
445-
if (request == HISTORY_REQUEST || request == PROFILE_REQUEST)
446-
{
447-
shm_mq_result mq_result;
448-
449-
/* Send history or profile */
450-
shm_mq_set_sender(collector_mq, MyProc);
451-
mqh = shm_mq_attach(collector_mq, NULL, NULL);
452-
mq_result = shm_mq_wait_for_attach(mqh);
453-
switch (mq_result)
454-
{
455-
case SHM_MQ_SUCCESS:
456-
switch (request)
457-
{
458-
case HISTORY_REQUEST:
459-
send_history(&observations, mqh);
460-
break;
461-
case PROFILE_REQUEST:
462-
send_profile(profile_hash, mqh);
463-
break;
464-
default:
465-
AssertState(false);
466-
}
467-
break;
468-
case SHM_MQ_DETACHED:
469-
ereport(WARNING,
470-
(errmsg("pg_wait_sampling collector: "
471-
"receiver of message queue has been "
472-
"detached")));
473-
break;
474-
default:
475-
AssertState(false);
476-
}
477-
shm_mq_detach_compat(mqh, collector_mq);
478-
}
479-
else if (request == PROFILE_RESET)
455+
shm_mq_result mq_result;
456+
457+
/* Send history or profile */
458+
shm_mq_set_sender(pgws_collector_mq, MyProc);
459+
mqh = shm_mq_attach(pgws_collector_mq, NULL, NULL);
460+
mq_result = shm_mq_wait_for_attach(mqh);
461+
switch (mq_result)
480462
{
481-
/* Reset profile hash */
482-
hash_destroy(profile_hash);
483-
profile_hash = make_profile_hash();
463+
case SHM_MQ_SUCCESS:
464+
switch (request)
465+
{
466+
case HISTORY_REQUEST:
467+
send_history(&observations, mqh);
468+
break;
469+
case PROFILE_REQUEST:
470+
send_profile(profile_hash, mqh);
471+
break;
472+
default:
473+
AssertState(false);
474+
}
475+
break;
476+
case SHM_MQ_DETACHED:
477+
ereport(WARNING,
478+
(errmsg("pg_wait_sampling collector: "
479+
"receiver of message queue have been "
480+
"detached")));
481+
break;
482+
default:
483+
AssertState(false);
484484
}
485-
486-
LockRelease(&tag, ExclusiveLock, false);
485+
shm_mq_detach_compat(mqh, pgws_collector_mq);
487486
}
488-
PG_CATCH();
487+
else if (request == PROFILE_RESET)
489488
{
490-
LockRelease(&tag, ExclusiveLock, false);
491-
PG_RE_THROW();
489+
/* Reset profile hash */
490+
hash_destroy(profile_hash);
491+
profile_hash = make_profile_hash();
492492
}
493-
PG_END_TRY();
493+
LockRelease(&tag, ExclusiveLock, false);
494494
}
495495
}
496496

0 commit comments

Comments
 (0)