mirror of https://github.com/citusdata/citus.git
Merge pull request #4196 from citusdata/support-explain-analyze-wal
Support EXPLAIN(ANALYZE, WAL)pull/4213/head
commit
6a341b6ab8
|
@ -83,6 +83,7 @@ typedef struct
|
|||
bool verbose;
|
||||
bool costs;
|
||||
bool buffers;
|
||||
bool wal;
|
||||
bool timing;
|
||||
bool summary;
|
||||
ExplainFormat format;
|
||||
|
@ -91,7 +92,7 @@ typedef struct
|
|||
|
||||
/* EXPLAIN flags of current distributed explain */
|
||||
static ExplainOptions CurrentDistributedQueryExplainOptions = {
|
||||
0, 0, 0, 0, 0, EXPLAIN_FORMAT_TEXT
|
||||
0, 0, 0, 0, 0, 0, EXPLAIN_FORMAT_TEXT
|
||||
};
|
||||
|
||||
/* Result for a single remote EXPLAIN command */
|
||||
|
@ -904,12 +905,18 @@ BuildRemoteExplainQuery(char *queryString, ExplainState *es)
|
|||
|
||||
appendStringInfo(explainQuery,
|
||||
"EXPLAIN (ANALYZE %s, VERBOSE %s, "
|
||||
"COSTS %s, BUFFERS %s, TIMING %s, SUMMARY %s, "
|
||||
"FORMAT %s) %s",
|
||||
"COSTS %s, BUFFERS %s, "
|
||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
||||
"WAL %s, "
|
||||
#endif
|
||||
"TIMING %s, SUMMARY %s, FORMAT %s) %s",
|
||||
es->analyze ? "TRUE" : "FALSE",
|
||||
es->verbose ? "TRUE" : "FALSE",
|
||||
es->costs ? "TRUE" : "FALSE",
|
||||
es->buffers ? "TRUE" : "FALSE",
|
||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
||||
es->wal ? "TRUE" : "FALSE",
|
||||
#endif
|
||||
es->timing ? "TRUE" : "FALSE",
|
||||
es->summary ? "TRUE" : "FALSE",
|
||||
formatStr,
|
||||
|
@ -1005,6 +1012,9 @@ worker_save_query_explain_analyze(PG_FUNCTION_ARGS)
|
|||
|
||||
/* use the same defaults as NewExplainState() for following options */
|
||||
es->buffers = ExtractFieldBoolean(explainOptions, "buffers", es->buffers);
|
||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
||||
es->wal = ExtractFieldBoolean(explainOptions, "wal", es->wal);
|
||||
#endif
|
||||
es->costs = ExtractFieldBoolean(explainOptions, "costs", es->costs);
|
||||
es->summary = ExtractFieldBoolean(explainOptions, "summary", es->summary);
|
||||
es->verbose = ExtractFieldBoolean(explainOptions, "verbose", es->verbose);
|
||||
|
@ -1206,6 +1216,9 @@ CitusExplainOneQuery(Query *query, int cursorOptions, IntoClause *into,
|
|||
/* save the flags of current EXPLAIN command */
|
||||
CurrentDistributedQueryExplainOptions.costs = es->costs;
|
||||
CurrentDistributedQueryExplainOptions.buffers = es->buffers;
|
||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
||||
CurrentDistributedQueryExplainOptions.wal = es->wal;
|
||||
#endif
|
||||
CurrentDistributedQueryExplainOptions.verbose = es->verbose;
|
||||
CurrentDistributedQueryExplainOptions.summary = es->summary;
|
||||
CurrentDistributedQueryExplainOptions.timing = es->timing;
|
||||
|
@ -1482,11 +1495,18 @@ WrapQueryForExplainAnalyze(const char *queryString, TupleDesc tupleDesc)
|
|||
}
|
||||
|
||||
StringInfo explainOptions = makeStringInfo();
|
||||
appendStringInfo(explainOptions, "{\"verbose\": %s, \"costs\": %s, \"buffers\": %s, "
|
||||
appendStringInfo(explainOptions,
|
||||
"{\"verbose\": %s, \"costs\": %s, \"buffers\": %s, "
|
||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
||||
"\"wal\": %s, "
|
||||
#endif
|
||||
"\"timing\": %s, \"summary\": %s, \"format\": \"%s\"}",
|
||||
CurrentDistributedQueryExplainOptions.verbose ? "true" : "false",
|
||||
CurrentDistributedQueryExplainOptions.costs ? "true" : "false",
|
||||
CurrentDistributedQueryExplainOptions.buffers ? "true" : "false",
|
||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
||||
CurrentDistributedQueryExplainOptions.wal ? "true" : "false",
|
||||
#endif
|
||||
CurrentDistributedQueryExplainOptions.timing ? "true" : "false",
|
||||
CurrentDistributedQueryExplainOptions.summary ? "true" : "false",
|
||||
ExplainFormatStr(CurrentDistributedQueryExplainOptions.format));
|
||||
|
@ -1632,7 +1652,10 @@ ExplainWorkerPlan(PlannedStmt *plannedstmt, DestReceiver *dest, ExplainState *es
|
|||
|
||||
if (es->buffers)
|
||||
instrument_option |= INSTRUMENT_BUFFERS;
|
||||
|
||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
||||
if (es->wal)
|
||||
instrument_option |= INSTRUMENT_WAL;
|
||||
#endif
|
||||
/*
|
||||
* We always collect timing for the entire statement, even when node-level
|
||||
* timing is off, so we don't look at es->timing here. (We could skip
|
||||
|
|
|
@ -170,15 +170,97 @@ SELECT create_distributed_table('test_table', 'a');
|
|||
-- we currently don't support this
|
||||
CREATE INDEX test_table_index ON test_table USING gist (b tsvector_ops(siglen = 100));
|
||||
ERROR: citus currently doesn't support operator class parameters in indexes
|
||||
-- testing WAL
|
||||
CREATE TABLE test_wal(a int, b int);
|
||||
-- test WAL without ANALYZE, this should raise an error
|
||||
EXPLAIN (WAL) INSERT INTO test_wal VALUES(1,11);
|
||||
ERROR: EXPLAIN option WAL requires ANALYZE
|
||||
-- test WAL working properly for router queries
|
||||
EXPLAIN (ANALYZE TRUE, WAL TRUE, COSTS FALSE, SUMMARY FALSE, BUFFERS FALSE, TIMING FALSE)
|
||||
INSERT INTO test_wal VALUES(1,11);
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Insert on test_wal (actual rows=0 loops=1)
|
||||
WAL: records=1 bytes=63
|
||||
-> Result (actual rows=1 loops=1)
|
||||
(3 rows)
|
||||
|
||||
SELECT create_distributed_table('test_wal', 'a');
|
||||
NOTICE: Copying data from local table...
|
||||
NOTICE: copying the data has completed
|
||||
DETAIL: The local data in the table is no longer visible, but is still on disk.
|
||||
HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$test_pg13.test_wal$$)
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (ANALYZE TRUE, WAL TRUE, COSTS FALSE, SUMMARY FALSE, BUFFERS FALSE, TIMING FALSE)
|
||||
INSERT INTO test_wal VALUES(2,22);
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Custom Scan (Citus Adaptive) (actual rows=0 loops=1)
|
||||
Task Count: 1
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=xxxxx dbname=regression
|
||||
-> Insert on test_wal_65013 (actual rows=0 loops=1)
|
||||
WAL: records=1 bytes=63
|
||||
-> Result (actual rows=1 loops=1)
|
||||
(8 rows)
|
||||
|
||||
-- Test WAL working for multi-shard query
|
||||
SET citus.explain_all_tasks TO on;
|
||||
EXPLAIN (ANALYZE TRUE, WAL TRUE, COSTS FALSE, SUMMARY FALSE, BUFFERS FALSE, TIMING FALSE)
|
||||
INSERT INTO test_wal VALUES(3,33),(4,44),(5,55) RETURNING *;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Custom Scan (Citus Adaptive) (actual rows=3 loops=1)
|
||||
Task Count: 1
|
||||
Tuple data received from nodes: 9 bytes
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Tuple data received from node: 9 bytes
|
||||
Node: host=localhost port=xxxxx dbname=regression
|
||||
-> Insert on test_wal_65012 citus_table_alias (actual rows=3 loops=1)
|
||||
WAL: records=3 bytes=189
|
||||
-> Values Scan on "*VALUES*" (actual rows=3 loops=1)
|
||||
(10 rows)
|
||||
|
||||
-- make sure WAL works in distributed subplans
|
||||
EXPLAIN (ANALYZE TRUE, WAL TRUE, COSTS FALSE, SUMMARY FALSE, BUFFERS FALSE, TIMING FALSE)
|
||||
WITH cte_1 AS (INSERT INTO test_wal VALUES(6,66),(7,77),(8,88) RETURNING *)
|
||||
SELECT * FROM cte_1;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Custom Scan (Citus Adaptive) (actual rows=3 loops=1)
|
||||
-> Distributed Subplan XXX_1
|
||||
Intermediate Data Size: 54 bytes
|
||||
Result destination: Write locally
|
||||
-> Custom Scan (Citus Adaptive) (actual rows=3 loops=1)
|
||||
Task Count: 2
|
||||
Tuple data received from nodes: 9 bytes
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Tuple data received from node: 6 bytes
|
||||
Node: host=localhost port=xxxxx dbname=regression
|
||||
-> Insert on test_wal_65012 citus_table_alias (actual rows=2 loops=1)
|
||||
WAL: records=2 bytes=126
|
||||
-> Values Scan on "*VALUES*" (actual rows=2 loops=1)
|
||||
-> Task
|
||||
Tuple data received from node: 3 bytes
|
||||
Node: host=localhost port=xxxxx dbname=regression
|
||||
-> Insert on test_wal_65013 citus_table_alias (actual rows=1 loops=1)
|
||||
WAL: records=1 bytes=63
|
||||
-> Result (actual rows=1 loops=1)
|
||||
Task Count: 1
|
||||
Tuple data received from nodes: 9 bytes
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Tuple data received from node: 9 bytes
|
||||
Node: host=localhost port=xxxxx dbname=regression
|
||||
-> Function Scan on read_intermediate_result intermediate_result (actual rows=3 loops=1)
|
||||
(27 rows)
|
||||
|
||||
SET client_min_messages TO WARNING;
|
||||
drop schema test_pg13 cascade;
|
||||
NOTICE: drop cascades to 10 other objects
|
||||
DETAIL: drop cascades to table dist_table
|
||||
drop cascades to table generated_col_table
|
||||
drop cascades to view v
|
||||
drop cascades to table ab
|
||||
drop cascades to table text_table
|
||||
drop cascades to function myvarcharout(myvarchar)
|
||||
drop cascades to type myvarchar
|
||||
drop cascades to function myvarcharin(cstring,oid,integer)
|
||||
drop cascades to table my_table
|
||||
drop cascades to table test_table
|
||||
|
|
|
@ -94,4 +94,26 @@ SELECT create_distributed_table('test_table', 'a');
|
|||
-- we currently don't support this
|
||||
CREATE INDEX test_table_index ON test_table USING gist (b tsvector_ops(siglen = 100));
|
||||
|
||||
-- testing WAL
|
||||
CREATE TABLE test_wal(a int, b int);
|
||||
-- test WAL without ANALYZE, this should raise an error
|
||||
EXPLAIN (WAL) INSERT INTO test_wal VALUES(1,11);
|
||||
-- test WAL working properly for router queries
|
||||
EXPLAIN (ANALYZE TRUE, WAL TRUE, COSTS FALSE, SUMMARY FALSE, BUFFERS FALSE, TIMING FALSE)
|
||||
INSERT INTO test_wal VALUES(1,11);
|
||||
SELECT create_distributed_table('test_wal', 'a');
|
||||
EXPLAIN (ANALYZE TRUE, WAL TRUE, COSTS FALSE, SUMMARY FALSE, BUFFERS FALSE, TIMING FALSE)
|
||||
INSERT INTO test_wal VALUES(2,22);
|
||||
|
||||
-- Test WAL working for multi-shard query
|
||||
SET citus.explain_all_tasks TO on;
|
||||
EXPLAIN (ANALYZE TRUE, WAL TRUE, COSTS FALSE, SUMMARY FALSE, BUFFERS FALSE, TIMING FALSE)
|
||||
INSERT INTO test_wal VALUES(3,33),(4,44),(5,55) RETURNING *;
|
||||
|
||||
-- make sure WAL works in distributed subplans
|
||||
EXPLAIN (ANALYZE TRUE, WAL TRUE, COSTS FALSE, SUMMARY FALSE, BUFFERS FALSE, TIMING FALSE)
|
||||
WITH cte_1 AS (INSERT INTO test_wal VALUES(6,66),(7,77),(8,88) RETURNING *)
|
||||
SELECT * FROM cte_1;
|
||||
|
||||
SET client_min_messages TO WARNING;
|
||||
drop schema test_pg13 cascade;
|
||||
|
|
Loading…
Reference in New Issue