diff options
author | Pavan Deolasee | 2017-04-06 05:34:14 +0000 |
---|---|---|
committer | Pavan Deolasee | 2017-05-05 04:59:34 +0000 |
commit | 671d817915fee9f49ca7993ca035e116cd700568 (patch) | |
tree | 47d32fdd6a69ae10e387e105793cbcb3b8d53d36 | |
parent | 275ef1024983bd39dc07a6d73944ef7a8b9a9594 (diff) |
Support an additional syntax ANALYZE (COORDINATOR) to allow users to rebuild
coordinator side statistics without running ANALYZE again on the datanodes.
When ANALYZE (COORDINATOR) is run, we don't update planner statistics on the
datanodes. But simply gather the existing statistics and update coordinator
side view of the global stats. The command only updates statistics on the
current coordinator and to update stats on all coordintors, the command must be
executed on all coordintors separately.
-rw-r--r-- | doc/src/sgml/ref/analyze.sgml | 12 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 28 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 9 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 6 |
4 files changed, 50 insertions, 5 deletions
diff --git a/doc/src/sgml/ref/analyze.sgml b/doc/src/sgml/ref/analyze.sgml index 27ab4fca42..f2f3f97e0a 100644 --- a/doc/src/sgml/ref/analyze.sgml +++ b/doc/src/sgml/ref/analyze.sgml @@ -22,6 +22,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table_name</replaceable> [ ( <replaceable class="PARAMETER">column_name</replaceable> [, ...] ) ] ] +ANALYZE [ ( { VERBOSE | COORDINATOR } ) ] [ <replaceable class="PARAMETER">table_name</replaceable> [ ( <replaceable class="PARAMETER">column_name</replaceable> [, ...] ) ] ] </synopsis> </refsynopsisdiv> @@ -59,6 +60,17 @@ ANALYZE [ VERBOSE ] [ <replaceable class="PARAMETER">table_name</replaceable> [ </varlistentry> <varlistentry> + <term><literal>COORDINATOR</literal></term> + <listitem> + <para> + Only updates statistics on the coordinator side using current statistics +on the datanodes. The datanode statistics are not updated and the current +values are used as they are. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><replaceable class="PARAMETER">table_name</replaceable></term> <listitem> <para> diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 00744a4980..54af976917 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -308,6 +308,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <ival> opt_lock lock_type cast_context %type <ival> vacuum_option_list vacuum_option_elem +%type <ival> analyze_option_list analyze_option_elem %type <boolean> opt_force opt_or_replace opt_grant_grant_option opt_grant_admin_option opt_nowait opt_if_exists opt_with_data @@ -9766,6 +9767,22 @@ AnalyzeStmt: n->va_cols = $4; $$ = (Node *)n; } + | analyze_keyword '(' analyze_option_list ')' + { + VacuumStmt *n = makeNode(VacuumStmt); + n->options = VACOPT_ANALYZE | $3; + n->relation = NULL; + n->va_cols = NIL; + $$ = (Node *)n; + } + | analyze_keyword '(' analyze_option_list ')' qualified_name opt_name_list + { + VacuumStmt *n = makeNode(VacuumStmt); + n->options = VACOPT_ANALYZE | $3; + n->relation = $5; + n->va_cols = $6; + $$ = (Node *)n; + } ; analyze_keyword: @@ -9786,6 +9803,17 @@ opt_freeze: FREEZE { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; + +analyze_option_list: + analyze_option_elem { $$ = $1; } + | analyze_option_list ',' analyze_option_elem { $$ = $1 | $3; } + ; + +analyze_option_elem: + VERBOSE { $$ = VACOPT_VERBOSE; } + | COORDINATOR { $$ = VACOPT_COORDINATOR; } + ; + opt_name_list: '(' name_list ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 0f42512466..7680a6451a 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -893,14 +893,15 @@ standard_ProcessUtility(Node *parsetree, /* we choose to allow this during "read only" transactions */ PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE"); -#ifdef PGXC /* * We have to run the command on nodes before Coordinator because * vacuum() pops active snapshot and we can not send it to nodes */ - if (IS_PGXC_LOCAL_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, sentToRemote, true, EXEC_ON_DATANODES, false); -#endif + if (IS_PGXC_LOCAL_COORDINATOR && + !(stmt->options & VACOPT_COORDINATOR)) + ExecUtilityStmtOnNodes(queryString, NULL, sentToRemote, + true, + EXEC_ON_DATANODES, false); /* forbidden in parallel mode due to CommandIsReadOnly */ ExecVacuum(stmt, isTopLevel); } diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 751f67285a..8c78e3eb2b 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2855,7 +2855,11 @@ typedef enum VacuumOption VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */ VACOPT_NOWAIT = 1 << 5, /* don't wait to get lock (autovacuum only) */ VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */ - VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */ + VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7, /* don't skip any pages */ + VACOPT_COORDINATOR = 1 << 8 /* don't trigger analyze on the datanodes, but + * just collect existing info and populate + * coordinator side stats. + */ } VacuumOption; typedef struct VacuumStmt |