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

Commit73b7295

Browse files
author
Maksim Milyutin
committed
Transform output from pg_query_state for parallel queries
1 parent19f8936 commit73b7295

File tree

3 files changed

+27
-10
lines changed

3 files changed

+27
-10
lines changed

‎README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ To install `pg_query_state`, please apply patches `custom_signal.patch`, `execut
1717
Correspondence branch names to PostgreSQL version numbers:
1818
-_PG9_5_ --- PostgreSQL 9.5
1919
-_PGPRO9_5_ --- PostgresPro 9.5
20+
-_master_ --- development version for PostgreSQL 10devel
2021

2122
Then execute this in the module's directory:
2223
```
@@ -58,7 +59,9 @@ pg_query_state(integer pid,
5859
triggersboolean DEFAULT FALSE,
5960
formattext DEFAULT'text')
6061
```
61-
Extract current query state from backend with specified`pid`. Since a function call causes nested subqueries so that state of execution may be viewed as stack of running queries, return value of`pg_query_state` has type`TABLE (query_text text, plan text)` and represents table where each row specifies stack frame -- correspondence between query and plan tree.
62+
Extract current query state from backend with specified`pid`. Since parallel query can spawn workers and function call causes nested subqueries so that state of execution may be viewed as stack of running queries, return value of`pg_query_state` has type`TABLE (pid integer, frame_number integer, query_text text, plan text, leader_pid integer)`. It represents tree structure consisting of leader process and its spawned workers. Each worker refers to leader through`leader_pid` column. For leader process the value of this column is` null`. For each process the stack frames are specified as correspondence between`frame_number`,`query_text` and`plan` columns.
63+
64+
Thus, user can see the states of main query and queries generated from function calls for leader process and all workers spawned from it.
6265

6366
In process of execution some nodes of plan tree can take loops of full execution. Therefore statistics for each node consists of two parts: average statistics for previous loops just like in EXPLAIN ANALYZE output and statistics for current loop if node have not finished.
6467

‎pg_query_state--1.0.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ CREATE FUNCTION pg_query_state(pid integer
88
, buffersboolean= FALSE
99
, triggersboolean= FALSE
1010
, formattext='text')
11-
RETURNS TABLE (query_texttext, plantext)
11+
RETURNS TABLE (pidinteger
12+
, frame_numberinteger
13+
, query_texttext
14+
, plantext
15+
, leader_pidinteger)
1216
AS'MODULE_PATHNAME'
1317
LANGUAGE C STRICT VOLATILE;
1418

‎pg_query_state.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -550,17 +550,19 @@ pg_query_state(PG_FUNCTION_ARGS)
550550
typedefstruct
551551
{
552552
ListCell*cursor;
553+
intindex;
553554
List*stack;
554555
}pg_qs_fctx;
555556

556557
FuncCallContext*funcctx;
557558
MemoryContextoldcontext;
558559
pg_qs_fctx*fctx;
560+
constintN_ATTRS=5;
561+
pid_tpid=PG_GETARG_INT32(0);
559562

560563
if (SRF_IS_FIRSTCALL())
561564
{
562565
LOCKTAGtag;
563-
pid_tpid=PG_GETARG_INT32(0);
564566
boolverbose=PG_GETARG_BOOL(1),
565567
costs=PG_GETARG_BOOL(2),
566568
timing=PG_GETARG_BOOL(3),
@@ -681,15 +683,19 @@ pg_query_state(PG_FUNCTION_ARGS)
681683
fctx= (pg_qs_fctx*)palloc(sizeof(pg_qs_fctx));
682684
qs_stack=deserialize_stack(msg->stack,msg->stack_depth);
683685
fctx->stack=qs_stack;
686+
fctx->index=0;
684687
fctx->cursor=list_head(qs_stack);
685688

686689
funcctx->user_fctx=fctx;
687690
funcctx->max_calls=list_length(qs_stack);
688691

689692
/* Make tuple descriptor */
690-
tupdesc=CreateTemplateTupleDesc(2, false);
691-
TupleDescInitEntry(tupdesc, (AttrNumber)1,"query_text",TEXTOID,-1,0);
692-
TupleDescInitEntry(tupdesc, (AttrNumber)2,"plan",TEXTOID,-1,0);
693+
tupdesc=CreateTemplateTupleDesc(N_ATTRS, false);
694+
TupleDescInitEntry(tupdesc, (AttrNumber)1,"pid",INT4OID,-1,0);
695+
TupleDescInitEntry(tupdesc, (AttrNumber)2,"frame_number",INT4OID,-1,0);
696+
TupleDescInitEntry(tupdesc, (AttrNumber)3,"query_text",TEXTOID,-1,0);
697+
TupleDescInitEntry(tupdesc, (AttrNumber)4,"plan",TEXTOID,-1,0);
698+
TupleDescInitEntry(tupdesc, (AttrNumber)5,"leader_pid",INT4OID,-1,0);
693699
funcctx->tuple_desc=BlessTupleDesc(tupdesc);
694700

695701
LockRelease(&tag,ExclusiveLock, false);
@@ -706,19 +712,23 @@ pg_query_state(PG_FUNCTION_ARGS)
706712
if (funcctx->call_cntr<funcctx->max_calls)
707713
{
708714
HeapTupletuple;
709-
Datumvalues[2];
710-
boolnulls[2];
715+
Datumvalues[N_ATTRS];
716+
boolnulls[N_ATTRS];
711717
stack_frame*frame= (stack_frame*)lfirst(fctx->cursor);
712718

713719
/* Make and return next tuple to caller */
714720
MemSet(values,0,sizeof(values));
715721
MemSet(nulls,0,sizeof(nulls));
716-
values[0]=PointerGetDatum(frame->query);
717-
values[1]=PointerGetDatum(frame->plan);
722+
values[0]=Int32GetDatum(pid);
723+
values[1]=Int32GetDatum(fctx->index);
724+
values[2]=PointerGetDatum(frame->query);
725+
values[3]=PointerGetDatum(frame->plan);
726+
nulls[4]= true;
718727
tuple=heap_form_tuple(funcctx->tuple_desc,values,nulls);
719728

720729
/* increment cursor */
721730
fctx->cursor=lnext(fctx->cursor);
731+
fctx->index++;
722732

723733
SRF_RETURN_NEXT(funcctx,HeapTupleGetDatum(tuple));
724734
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp