Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbbd0b14

Browse files
author
Maksim Milyutin
committed
Add contrib sources
1 parenta0c217f commitbbd0b14

14 files changed

+2870
-0
lines changed

‎contrib/pg_query_state/Makefile

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# contrib/pg_query_state/Makefile
2+
3+
MODULE_big = pg_query_state
4+
OBJS = pg_query_state.o signal_handler.o$(WIN32RES)
5+
EXTENSION = pg_query_state
6+
EXTVERSION = 1.0
7+
DATA =$(EXTENSION)--$(EXTVERSION).sql
8+
PGFILEDESC = "pg_query_state - facility to track progress of plan execution"
9+
10+
EXTRA_CLEAN = ./isolation_output
11+
12+
ifdefUSE_PGXS
13+
PG_CONFIG = pg_config
14+
PGXS :=$(shell$(PG_CONFIG) --pgxs)
15+
include$(PGXS)
16+
else
17+
subdir = contrib/pg_query_state
18+
top_builddir = ../..
19+
include$(top_builddir)/src/Makefile.global
20+
include$(top_srcdir)/contrib/contrib-global.mk
21+
endif
22+
23+
check: isolationcheck
24+
25+
ISOLATIONCHECKS=corner_cases
26+
27+
submake-isolation:
28+
$(MAKE) -C$(top_builddir)/src/test/isolation all
29+
30+
isolationcheck: | submake-isolation temp-install
31+
$(MKDIR_P) isolation_output
32+
$(pg_isolation_regress_check)\
33+
--temp-config$(top_srcdir)/contrib/pg_query_state/test.conf\
34+
--outputdir=isolation_output\
35+
$(ISOLATIONCHECKS)
36+
37+
isolationcheck-install-force: all | submake-isolation temp-install
38+
$(MKDIR_P) isolation_output
39+
$(pg_isolation_regress_installcheck)\
40+
--outputdir=isolation_output\
41+
$(ISOLATIONCHECKS)
42+
43+
.PHONY: isolationcheck isolationcheck-install-force check
44+
45+
temp-install: EXTRA_INSTALL=contrib/pg_query_state

‎contrib/pg_query_state/README.md

Lines changed: 291 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
2+
index a3d6ac5..60732a6 100644
3+
--- a/src/backend/storage/ipc/procsignal.c
4+
+++ b/src/backend/storage/ipc/procsignal.c
5+
@@ -26,6 +26,7 @@
6+
#include "storage/shmem.h"
7+
#include "storage/sinval.h"
8+
#include "tcop/tcopprot.h"
9+
+#include "utils/memutils.h"
10+
11+
12+
/*
13+
@@ -59,12 +60,17 @@ typedef struct
14+
*/
15+
#define NumProcSignalSlots(MaxBackends + NUM_AUXPROCTYPES)
16+
17+
+static bool CustomSignalPendings[NUM_CUSTOM_PROCSIGNALS];
18+
+static ProcSignalHandler_type CustomHandlers[NUM_CUSTOM_PROCSIGNALS];
19+
+
20+
static ProcSignalSlot *ProcSignalSlots = NULL;
21+
static volatile ProcSignalSlot *MyProcSignalSlot = NULL;
22+
23+
static bool CheckProcSignal(ProcSignalReason reason);
24+
static void CleanupProcSignalState(int status, Datum arg);
25+
26+
+static void CustomSignalInterrupt(ProcSignalReason reason);
27+
+
28+
/*
29+
* ProcSignalShmemSize
30+
*Compute space needed for procsignal's shared memory
31+
@@ -165,6 +171,57 @@ CleanupProcSignalState(int status, Datum arg)
32+
}
33+
34+
/*
35+
+ * RegisterCustomProcSignalHandler
36+
+ * Assign specific handler of custom process signal with new ProcSignalReason key.
37+
+ * Return INVALID_PROCSIGNAL if all custom signals have been assigned.
38+
+ */
39+
+ProcSignalReason
40+
+RegisterCustomProcSignalHandler(ProcSignalHandler_type handler)
41+
+{
42+
+ProcSignalReason reason;
43+
+
44+
+/* iterate through custom signal keys to find free spot */
45+
+for (reason = PROCSIG_CUSTOM_1; reason <= PROCSIG_CUSTOM_N; reason++)
46+
+if (!CustomHandlers[reason - PROCSIG_CUSTOM_1])
47+
+{
48+
+CustomHandlers[reason - PROCSIG_CUSTOM_1] = handler;
49+
+return reason;
50+
+}
51+
+return INVALID_PROCSIGNAL;
52+
+}
53+
+
54+
+/*
55+
+ * AssignCustomProcSignalHandler
56+
+ * Assign handler of custom process signal with specific ProcSignalReason key.
57+
+ * Return old ProcSignal handler.
58+
+ * Assume incoming reason is one of custom ProcSignals.
59+
+ */
60+
+ProcSignalHandler_type
61+
+AssignCustomProcSignalHandler(ProcSignalReason reason, ProcSignalHandler_type handler)
62+
+{
63+
+ProcSignalHandler_type old;
64+
+
65+
+Assert(reason >= PROCSIG_CUSTOM_1 && reason <= PROCSIG_CUSTOM_N);
66+
+
67+
+old = CustomHandlers[reason - PROCSIG_CUSTOM_1];
68+
+CustomHandlers[reason - PROCSIG_CUSTOM_1] = handler;
69+
+return old;
70+
+}
71+
+
72+
+/*
73+
+ * GetCustomProcSignalHandler
74+
+ * Get handler of custom process signal.
75+
+ *Assume incoming reason is one of custom ProcSignals.
76+
+ */
77+
+ProcSignalHandler_type
78+
+GetCustomProcSignalHandler(ProcSignalReason reason)
79+
+{
80+
+Assert(reason >= PROCSIG_CUSTOM_1 && reason <= PROCSIG_CUSTOM_N);
81+
+
82+
+return CustomHandlers[reason - PROCSIG_CUSTOM_1];
83+
+}
84+
+
85+
+/*
86+
* SendProcSignal
87+
*Send a signal to a Postgres process
88+
*
89+
@@ -259,7 +316,8 @@ CheckProcSignal(ProcSignalReason reason)
90+
void
91+
procsignal_sigusr1_handler(SIGNAL_ARGS)
92+
{
93+
-intsave_errno = errno;
94+
+intsave_errno = errno;
95+
+ProcSignalReason reason;
96+
97+
if (CheckProcSignal(PROCSIG_CATCHUP_INTERRUPT))
98+
HandleCatchupInterrupt();
99+
@@ -288,9 +346,88 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
100+
if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
101+
RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
102+
103+
+for (reason = PROCSIG_CUSTOM_1; reason <= PROCSIG_CUSTOM_N; reason++)
104+
+if (CheckProcSignal(reason))
105+
+CustomSignalInterrupt(reason);
106+
+
107+
SetLatch(MyLatch);
108+
109+
latch_sigusr1_handler();
110+
111+
errno = save_errno;
112+
}
113+
+
114+
+/*
115+
+ * Handle receipt of an interrupt indicating a custom process signal.
116+
+ */
117+
+static void
118+
+CustomSignalInterrupt(ProcSignalReason reason)
119+
+{
120+
+intsave_errno = errno;
121+
+
122+
+Assert(reason >= PROCSIG_CUSTOM_1 && reason <= PROCSIG_CUSTOM_N);
123+
+
124+
+/* set interrupt flags */
125+
+InterruptPending = true;
126+
+CustomSignalPendings[reason - PROCSIG_CUSTOM_1] = true;
127+
+
128+
+/* make sure the event is processed in due course */
129+
+SetLatch(MyLatch);
130+
+
131+
+errno = save_errno;
132+
+}
133+
+
134+
+/*
135+
+ * CheckAndHandleCustomSignals
136+
+ * Check custom signal flags and call handler assigned to that signal if it is not NULL.
137+
+ * This function is called within CHECK_FOR_INTERRUPTS if interrupt have been occurred.
138+
+ */
139+
+void
140+
+CheckAndHandleCustomSignals(void)
141+
+{
142+
+int i;
143+
+MemoryContext oldcontext;
144+
+
145+
+static MemoryContext hcs_context = NULL;
146+
+
147+
+/*
148+
+ * This is invoked from ProcessInterrupts(), and since some of the
149+
+ * functions it calls contain CHECK_FOR_INTERRUPTS(), there is a potential
150+
+ * for recursive calls if more signals are received while this runs. It's
151+
+ * unclear that recursive entry would be safe, and it doesn't seem useful
152+
+ * even if it is safe, so let's block interrupts until done.
153+
+ */
154+
+HOLD_INTERRUPTS();
155+
+
156+
+/*
157+
+ * Moreover, CurrentMemoryContext might be pointing almost anywhere. We
158+
+ * don't want to risk leaking data into long-lived contexts, so let's do
159+
+ * our work here in a private context that we can reset on each use.
160+
+ */
161+
+if (hcs_context == NULL)/* first time through? */
162+
+hcs_context = AllocSetContextCreate(TopMemoryContext,
163+
+"HandleCustomSignals",
164+
+ALLOCSET_DEFAULT_SIZES);
165+
+else
166+
+MemoryContextReset(hcs_context);
167+
+
168+
+oldcontext = MemoryContextSwitchTo(hcs_context);
169+
+
170+
+for (i = 0; i < NUM_CUSTOM_PROCSIGNALS; i++)
171+
+if (CustomSignalPendings[i])
172+
+{
173+
+ProcSignalHandler_type handler;
174+
+
175+
+CustomSignalPendings[i] = false;
176+
+handler = CustomHandlers[i];
177+
+if (handler)
178+
+handler();
179+
+}
180+
+
181+
+MemoryContextSwitchTo(oldcontext);
182+
+
183+
+/* Might as well clear the context on our way out */
184+
+MemoryContextReset(hcs_context);
185+
+
186+
+RESUME_INTERRUPTS();
187+
+}
188+
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
189+
index 98ccbbb..c5d649c 100644
190+
--- a/src/backend/tcop/postgres.c
191+
+++ b/src/backend/tcop/postgres.c
192+
@@ -3005,6 +3005,8 @@ ProcessInterrupts(void)
193+
194+
if (ParallelMessagePending)
195+
HandleParallelMessages();
196+
+
197+
+CheckAndHandleCustomSignals();
198+
}
199+
200+
201+
diff --git a/src/include/storage/procsignal.h b/src/include/storage/procsignal.h
202+
index f67b982..e941dcb 100644
203+
--- a/src/include/storage/procsignal.h
204+
+++ b/src/include/storage/procsignal.h
205+
@@ -17,6 +17,8 @@
206+
#include "storage/backendid.h"
207+
208+
209+
+#define NUM_CUSTOM_PROCSIGNALS 64
210+
+
211+
/*
212+
* Reasons for signalling a Postgres child process (a backend or an auxiliary
213+
* process, like checkpointer). We can cope with concurrent signals for different
214+
@@ -29,6 +31,8 @@
215+
*/
216+
typedef enum
217+
{
218+
+INVALID_PROCSIGNAL = -1,/* Must be first */
219+
+
220+
PROCSIG_CATCHUP_INTERRUPT,/* sinval catchup interrupt */
221+
PROCSIG_NOTIFY_INTERRUPT,/* listen/notify interrupt */
222+
PROCSIG_PARALLEL_MESSAGE,/* message from cooperating parallel backend */
223+
@@ -41,9 +45,20 @@ typedef enum
224+
PROCSIG_RECOVERY_CONFLICT_BUFFERPIN,
225+
PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,
226+
227+
+PROCSIG_CUSTOM_1,
228+
+/*
229+
+ * PROCSIG_CUSTOM_2,
230+
+ * ...,
231+
+ * PROCSIG_CUSTOM_N-1,
232+
+ */
233+
+PROCSIG_CUSTOM_N = PROCSIG_CUSTOM_1 + NUM_CUSTOM_PROCSIGNALS - 1,
234+
+
235+
NUM_PROCSIGNALS/* Must be last! */
236+
} ProcSignalReason;
237+
238+
+/* Handler of custom process signal */
239+
+typedef void (*ProcSignalHandler_type) (void);
240+
+
241+
/*
242+
* prototypes for functions in procsignal.c
243+
*/
244+
@@ -51,9 +66,15 @@ extern Size ProcSignalShmemSize(void);
245+
extern void ProcSignalShmemInit(void);
246+
247+
extern void ProcSignalInit(int pss_idx);
248+
+extern ProcSignalReason RegisterCustomProcSignalHandler(ProcSignalHandler_type handler);
249+
+extern ProcSignalHandler_type AssignCustomProcSignalHandler(ProcSignalReason reason,
250+
+ ProcSignalHandler_type handler);
251+
+extern ProcSignalHandler_type GetCustomProcSignalHandler(ProcSignalReason reason);
252+
extern int SendProcSignal(pid_t pid, ProcSignalReason reason,
253+
BackendId backendId);
254+
255+
+extern void CheckAndHandleCustomSignals(void);
256+
+
257+
extern void procsignal_sigusr1_handler(SIGNAL_ARGS);
258+
259+
#endif /* PROCSIGNAL_H */
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
Parsed test spec with 2 sessions
2+
3+
starting permutation: s1_pg_qs_1
4+
step s1_pg_qs_1: select pg_query_state(1);
5+
ERROR: backend with pid=1 not found
6+
7+
starting permutation: s1_pg_qs_2
8+
step s1_pg_qs_2: select pg_query_state(pg_backend_pid());
9+
ERROR: attempt to extract state of current process
10+
11+
starting permutation: s1_save_pid s2_pg_qs_counterpart
12+
step s1_save_pid: select save_own_pid(0);
13+
save_own_pid
14+
15+
16+
INFO: state of backend is idle
17+
step s2_pg_qs_counterpart: select pg_query_state(counterpart_pid(0));
18+
pg_query_state
19+
20+
21+
starting permutation: s1_save_pid s1_disable_pg_qs s2_pg_qs_counterpart
22+
step s1_save_pid: select save_own_pid(0);
23+
save_own_pid
24+
25+
26+
step s1_disable_pg_qs: set pg_query_state.enable to off;
27+
INFO: query execution statistics disabled
28+
step s2_pg_qs_counterpart: select pg_query_state(counterpart_pid(0));
29+
pg_query_state
30+
31+
32+
starting permutation: s1_set_bob s2_set_bob s1_save_pid s2_pg_qs_counterpart
33+
step s1_set_bob: set role bob;
34+
step s2_set_bob: set role bob;
35+
step s1_save_pid: select save_own_pid(0);
36+
save_own_pid
37+
38+
39+
INFO: state of backend is idle
40+
step s2_pg_qs_counterpart: select pg_query_state(counterpart_pid(0));
41+
pg_query_state
42+
43+
44+
starting permutation: s1_set_bob s2_set_su s1_save_pid s2_pg_qs_counterpart
45+
step s1_set_bob: set role bob;
46+
step s2_set_su: set role super;
47+
step s1_save_pid: select save_own_pid(0);
48+
save_own_pid
49+
50+
51+
INFO: state of backend is idle
52+
step s2_pg_qs_counterpart: select pg_query_state(counterpart_pid(0));
53+
pg_query_state
54+
55+
56+
starting permutation: s1_set_bob s2_set_alice s1_save_pid s2_pg_qs_counterpart
57+
step s1_set_bob: set role bob;
58+
step s2_set_alice: set role alice;
59+
step s1_save_pid: select save_own_pid(0);
60+
save_own_pid
61+
62+
63+
step s2_pg_qs_counterpart: select pg_query_state(counterpart_pid(0));
64+
ERROR: permission denied
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
2+
\echo Use"CREATE EXTENSION pg_query_state" to load this file. \quit
3+
4+
CREATEFUNCTIONpg_query_state(pidinteger
5+
, verboseboolean= FALSE
6+
, costsboolean= FALSE
7+
, timingboolean= FALSE
8+
, buffersboolean= FALSE
9+
, triggersboolean= FALSE
10+
, formattext='text')
11+
RETURNS TABLE (pidinteger
12+
, frame_numberinteger
13+
, query_texttext
14+
, plantext
15+
, leader_pidinteger)
16+
AS'MODULE_PATHNAME'
17+
LANGUAGE C STRICT VOLATILE;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp