同步source code

日期: 12-26
    revision: ee5b054c
This commit is contained in:
dengxuyue
2020-12-28 22:19:21 +08:00
parent b7337ff802
commit 1567043064
6076 changed files with 2376818 additions and 741042 deletions

View File

@ -43,8 +43,10 @@
#include "pgxc/pgxcnode.h"
#include "utils/acl.h"
#include "utils/lsyscache.h"
#include "utils/tqual.h"
#include "access/heapam.h"
#include "workload/memctl.h"
#include "access/hash.h"
#include "utils/dynahash.h"
/* ------------------------------------------------------------------------- */
/* Data structure */
@ -205,7 +207,7 @@ static Bitmapset* ng_node_oid_array_to_id_bms_skip_null(Oid* members, int nmembe
* (2) u_sess->opt_cxt.compute_permission_group_distribution
* (3) u_sess->opt_cxt.query_union_set_group_distribution
* (4) u_sess->opt_cxt.is_multiple_nodegroup_scenario
* (5) u_sess->opt_cxt.is_all_in_installation_nodegroup_scenario
* (5) u_sess->opt_cxt.different_nodegroup_count
* if it's a multiple node group scenario, we should shut down SMP here
*
* @param (in) query:
@ -251,7 +253,7 @@ void ng_init_nodegroup_optimizer(Query* query)
/* Check wheather it is a multiple node group scenario */
u_sess->opt_cxt.is_multiple_nodegroup_scenario = true;
u_sess->opt_cxt.is_all_in_installation_nodegroup_scenario = false;
u_sess->opt_cxt.different_nodegroup_count = 2;
if (baserels_in_same_group) {
Distribution* default_computing_group_distribution = ng_get_default_computing_group_distribution();
if (ng_is_same_group(
@ -259,11 +261,24 @@ void ng_init_nodegroup_optimizer(Query* query)
u_sess->opt_cxt.is_multiple_nodegroup_scenario = false;
if (ng_is_same_group(u_sess->opt_cxt.query_union_set_group_distribution, installation_group_distribution)) {
u_sess->opt_cxt.is_all_in_installation_nodegroup_scenario = true;
u_sess->opt_cxt.different_nodegroup_count--;
}
}
}
u_sess->opt_cxt.enable_nodegroup_explain = !u_sess->opt_cxt.is_all_in_installation_nodegroup_scenario;
u_sess->opt_cxt.single_node_distribution = NULL;
/* Init dn gather's single node distribution */
if (IS_PGXC_COORDINATOR && u_sess->attr.attr_sql.enable_dngather
&& bms_num_members(u_sess->opt_cxt.query_union_set_group_distribution->bms_data_nodeids) >= 1
&& u_sess->opt_cxt.query_dop <= 1) {
u_sess->opt_cxt.single_node_distribution = ng_get_random_single_dn_distribution(u_sess->opt_cxt.query_union_set_group_distribution);
if (!ng_is_same_group(u_sess->opt_cxt.query_union_set_group_distribution, u_sess->opt_cxt.single_node_distribution)) {
u_sess->opt_cxt.is_multiple_nodegroup_scenario = true;
u_sess->opt_cxt.different_nodegroup_count++;
}
}
u_sess->opt_cxt.enable_nodegroup_explain = u_sess->opt_cxt.different_nodegroup_count > 1;
}
/*
@ -276,14 +291,16 @@ void ng_init_nodegroup_optimizer(Query* query)
* the params to backup options
*/
void ng_backup_nodegroup_options(bool* p_is_multiple_nodegroup_scenario,
bool* p_is_all_in_installation_nodegroup_scenario, Distribution** p_in_redistribution_group_distribution,
Distribution** p_compute_permission_group_distribution, Distribution** p_query_union_set_group_distribution)
int* p_different_nodegroup_count, Distribution** p_in_redistribution_group_distribution,
Distribution** p_compute_permission_group_distribution, Distribution** p_query_union_set_group_distribution,
Distribution** p_single_node_distribution)
{
*p_is_multiple_nodegroup_scenario = u_sess->opt_cxt.is_multiple_nodegroup_scenario;
*p_is_all_in_installation_nodegroup_scenario = u_sess->opt_cxt.is_all_in_installation_nodegroup_scenario;
*p_different_nodegroup_count = u_sess->opt_cxt.different_nodegroup_count;
*p_in_redistribution_group_distribution = u_sess->opt_cxt.in_redistribution_group_distribution;
*p_compute_permission_group_distribution = u_sess->opt_cxt.compute_permission_group_distribution;
*p_query_union_set_group_distribution = u_sess->opt_cxt.query_union_set_group_distribution;
*p_single_node_distribution = u_sess->opt_cxt.single_node_distribution;
}
/*
@ -297,18 +314,20 @@ void ng_backup_nodegroup_options(bool* p_is_multiple_nodegroup_scenario,
* the params holds the original options
*/
void ng_restore_nodegroup_options(bool p_is_multiple_nodegroup_scenario,
bool p_is_all_in_installation_nodegroup_scenario, Distribution* p_in_redistribution_group_distribution,
Distribution* p_compute_permission_group_distribution, Distribution* p_query_union_set_group_distribution)
int p_different_nodegroup_count, Distribution* p_in_redistribution_group_distribution,
Distribution* p_compute_permission_group_distribution, Distribution* p_query_union_set_group_distribution,
Distribution* p_single_node_distribution)
{
/* for further explain */
u_sess->opt_cxt.enable_nodegroup_explain = !u_sess->opt_cxt.is_all_in_installation_nodegroup_scenario;
u_sess->opt_cxt.enable_nodegroup_explain = u_sess->opt_cxt.different_nodegroup_count > 1;
/* restore nodegroup optimizer options */
u_sess->opt_cxt.is_multiple_nodegroup_scenario = p_is_multiple_nodegroup_scenario;
u_sess->opt_cxt.is_all_in_installation_nodegroup_scenario = p_is_all_in_installation_nodegroup_scenario;
u_sess->opt_cxt.different_nodegroup_count = p_different_nodegroup_count;
u_sess->opt_cxt.in_redistribution_group_distribution = p_in_redistribution_group_distribution;
u_sess->opt_cxt.compute_permission_group_distribution = p_compute_permission_group_distribution;
u_sess->opt_cxt.query_union_set_group_distribution = p_query_union_set_group_distribution;
u_sess->opt_cxt.single_node_distribution = p_single_node_distribution;
}
/*
@ -427,13 +446,13 @@ Distribution* ng_get_compute_permission_group_distribution()
/* Just for initialize of computing permission group */
if (u_sess->opt_cxt.compute_permission_group_distribution == NULL) {
Oid user_oid = GetUserId();
List* group_oid_list = Get_nodegroup_oid_compute(user_oid);
List* group_oid_list = GetNodeGroupOidCompute(user_oid);
Distribution* distribution = NULL;
ListCell* lc = NULL;
foreach (lc, group_oid_list) {
Oid group_oid = (Oid)lfirst_oid(lc);
Distribution* d = ng_get_group_distribution(group_oid);
distribution = ng_get_union_distribution(distribution, d);
distribution = ng_get_union_distribution_recycle(distribution, d);
}
if (distribution == NULL || bms_is_empty(distribution->bms_data_nodeids)) {
@ -479,7 +498,7 @@ Distribution* ng_get_query_union_set_group_distribution(List* baserel_rte_list,
AssertEreport(rte->rtekind == RTE_RELATION, MOD_OPT, "");
/* Only check plain relaion */
if (RELKIND_VIEW == rte->relkind) {
if (RELKIND_VIEW == rte->relkind || RELKIND_CONTQUERY == rte->relkind) {
continue;
}
@ -490,7 +509,7 @@ Distribution* ng_get_query_union_set_group_distribution(List* baserel_rte_list,
} else {
if (!ng_is_same_group(union_distribution, rel_distribution)) {
*baserels_in_same_group = false;
union_distribution = ng_get_union_distribution(union_distribution, rel_distribution);
union_distribution = ng_get_union_distribution_recycle(union_distribution, rel_distribution);
}
}
}
@ -551,7 +570,7 @@ Distribution* ng_get_expected_computing_group_distribution()
if (InvalidOid == distribution->group_oid) {
ereport(DEBUG1, (errmodule(MOD_OPT), errmsg("Expected computing node group does not exist.")));
distribution = ng_get_query_union_set_group_distribution();
distribution = ng_copy_distribution(ng_get_query_union_set_group_distribution());
}
return distribution;
@ -651,6 +670,10 @@ Distribution* ng_get_default_computing_group_distribution()
return NULL;
}
Distribution* ng_get_single_node_distribution() {
return u_sess->opt_cxt.single_node_distribution;
}
/*
* ng_get_correlated_subplan_group_distribution
* Get Distribution information for a correlated sub-plan.
@ -674,9 +697,9 @@ Distribution* ng_get_correlated_subplan_group_distribution()
}
case CNG_MODE_COSTBASED_EXPECT:
case CNG_MODE_FORCE: {
Distribution* distribution_1 = ng_get_query_union_set_group_distribution();
Distribution* distribution_1 = ng_copy_distribution(ng_get_query_union_set_group_distribution());
Distribution* distribution_2 = ng_get_expected_computing_group_distribution();
return ng_get_union_distribution(distribution_1, distribution_2);
return ng_get_union_distribution_recycle(distribution_1, distribution_2);
}
default:
break;
@ -740,6 +763,34 @@ char* ng_get_group_group_name(Oid group_oid)
}
}
/*
* ng_get_dist_group_name
* get group name from distribution
*/
char* ng_get_dist_group_name(Distribution *distribution)
{
if (IS_PGXC_COORDINATOR && u_sess->attr.attr_sql.enable_dngather
&& u_sess->opt_cxt.is_dngather_support && distribution->group_oid == InvalidOid) {
char *sep = "";
StringInfo node_names = makeStringInfo();
NameData nodename = {{0}};
int node_no = -1;
while ((node_no = bms_next_member(distribution->bms_data_nodeids, node_no)) >= 0) {
appendStringInfo(node_names,
"%s%s",
sep,
get_pgxc_nodename(PGXCNodeGetNodeOid(node_no, PGXC_NODE_DATANODE), &nodename));
sep = ", ";
}
return node_names->data;
}
return ng_get_group_group_name(distribution->group_oid);
}
/*
* ng_get_group_nodeids
* Get node index bitmap set from group oid
@ -760,29 +811,34 @@ Bitmapset* ng_get_group_nodeids(const Oid groupoid)
return ng_convert_to_nodeids(nodeid_list);
}
/* First check if we already have default nodegroup set */
Oid* members = NULL;
int nmembers = get_pgxc_groupmembers(groupoid, &members);
bms_nodeids = ngroup_info_hash_search(groupoid);
if (!bms_nodeids) {
/* First check if we already have default nodegroup set */
Oid* members = NULL;
int nmembers = get_pgxc_groupmembers(groupoid, &members);
/* in logic cluster case, elastic_nodegroup can contain no members */
if (nmembers == 0 && in_logic_cluster() && groupoid == ng_get_group_groupoid(VNG_OPTION_ELASTIC_GROUP))
return NULL;
/* in logic cluster case, elastic_nodegroup can contain no members */
if (nmembers == 0 && in_logic_cluster() && groupoid == ng_get_group_groupoid(VNG_OPTION_ELASTIC_GROUP))
return NULL;
Assert(nmembers > 0);
Assert(nmembers > 0);
/*
* Creating a bitmap from array.
* Notice : installation group's group_members in pgxc_group may be not match with u_sess->pgxc_cxt.dn_handles
* when node changed in online expansion, so we skip it here and this currently looks ok.
*
* Note: we only have to do the special processing for installation node group, because in
* cluster expansion stage(adding node), only installation group's node will change.
*/
if (groupoid == ng_get_installation_group_oid())
bms_nodeids = ng_node_oid_array_to_id_bms_skip_null(members, nmembers, PGXC_NODE_DATANODE);
else
bms_nodeids = ng_node_oid_array_to_id_bms(members, nmembers, PGXC_NODE_DATANODE);
pfree_ext(members);
/*
* Creating a bitmap from array.
* Notice : installation group's group_members in pgxc_group may be not match with u_sess->pgxc_cxt.dn_handles
* when node changed in online expansion, so we skip it here and this currently looks ok.
*
* Note: we only have to do the special processing for installation node group, because in
* cluster expansion stage(adding node), only installation group's node will change.
*/
if (groupoid == ng_get_installation_group_oid())
bms_nodeids = ng_node_oid_array_to_id_bms_skip_null(members, nmembers, PGXC_NODE_DATANODE);
else
bms_nodeids = ng_node_oid_array_to_id_bms(members, nmembers, PGXC_NODE_DATANODE);
pfree_ext(members);
ngroup_info_hash_insert(groupoid, bms_nodeids);
}
return bms_nodeids;
}
@ -852,13 +908,13 @@ static bool need_get_installation_group(Oid tableoid, char relkind)
return true;
/* Normal tables will not use installation group */
if (relkind == RELKIND_RELATION || relkind == RELKIND_INDEX) {
if (relkind == RELKIND_RELATION || relkind == RELKIND_INDEX || relkind == RELKIND_MATVIEW) {
return false;
}
if (in_logic_cluster()) {
/* Distributed foreign tables(in pgxc_class) will not use installation group in logic cluster. */
if (relkind == RELKIND_FOREIGN_TABLE && is_pgxc_class_table(tableoid))
/* Distributed foreign tables(in pgxc_class) will not use installation group in logic cluster.*/
if ((RELKIND_FOREIGN_TABLE == relkind || RELKIND_STREAM == relkind) && is_pgxc_class_table(tableoid))
return false;
}
@ -1124,6 +1180,10 @@ unsigned int ng_get_dest_num_data_nodes(Path* path)
{
AssertEreport(path != NULL, MOD_OPT, "");
#ifndef ENABLE_MULTIPLE_NODES
return 1;
#endif
if (!IS_STREAM_PLAN) {
return 1;
}
@ -1131,7 +1191,9 @@ unsigned int ng_get_dest_num_data_nodes(Path* path)
if (ng_is_all_in_installation_nodegroup_scenario()) {
switch (path->pathtype) {
case T_CStoreScan:
#ifdef ENABLE_MULTIPLE_NODES
case T_TsStoreScan:
#endif /* ENABLE_MULTIPLE_NODES */
return u_sess->pgxc_cxt.NumDataNodes;
default:
break;
@ -1161,6 +1223,10 @@ unsigned int ng_get_dest_num_data_nodes(Plan* plan)
{
AssertEreport(plan != NULL, MOD_OPT, "");
#ifndef ENABLE_MULTIPLE_NODES
return 1;
#endif
if (!IS_STREAM_PLAN) {
return 1;
}
@ -1169,7 +1235,9 @@ unsigned int ng_get_dest_num_data_nodes(Plan* plan)
switch (plan->type) {
case T_SeqScan:
case T_CStoreScan:
#ifdef ENABLE_MULTIPLE_NODES
case T_TsStoreScan:
#endif /* ENABLE_MULTIPLE_NODES */
case T_IndexScan:
case T_IndexOnlyScan:
case T_CStoreIndexScan:
@ -1215,6 +1283,10 @@ unsigned int ng_get_dest_num_data_nodes(RelOptInfo* rel)
{
AssertEreport(rel != NULL, MOD_OPT, "");
#ifndef ENABLE_MULTIPLE_NODES
return 1;
#endif
if (!IS_STREAM_PLAN) {
return 1;
}
@ -1251,7 +1323,16 @@ unsigned int ng_get_dest_num_data_nodes(PlannerInfo* root, RelOptInfo* rel)
{
AssertEreport(rel != NULL, MOD_OPT, "");
#ifndef ENABLE_MULTIPLE_NODES
return 1;
#endif
if (rel->num_data_nodes != 0) {
return rel->num_data_nodes;
}
if (!IS_STREAM_PLAN) {
rel->num_data_nodes = 1;
return 1;
}
@ -1295,6 +1376,8 @@ unsigned int ng_get_dest_num_data_nodes(PlannerInfo* root, RelOptInfo* rel)
elog(DEBUG1, "[ng_get_dest_num_data_nodes] num of data nodes is 0");
num_data_nodes = 1;
}
rel->num_data_nodes = num_data_nodes;
return num_data_nodes;
}
@ -1377,6 +1460,9 @@ Distribution* ng_copy_distribution(Distribution* src_distribution)
void ng_copy_distribution(Distribution* dest_distribution, const Distribution* src_distribution)
{
dest_distribution->group_oid = src_distribution->group_oid;
/* bms_copy will palloc a new bms */
if (dest_distribution->bms_data_nodeids != NULL)
bms_free(dest_distribution->bms_data_nodeids);
dest_distribution->bms_data_nodeids = bms_copy(src_distribution->bms_data_nodeids);
}
@ -1444,7 +1530,7 @@ Distribution* ng_get_overlap_distribution(Distribution* distribution_1, Distribu
* second Distribution(s) to union
*
* @return:
* the union Distribution
* the copied union Distribution and leaving their inputs untouched
*/
Distribution* ng_get_union_distribution(Distribution* distribution_1, Distribution* distribution_2)
{
@ -1468,6 +1554,27 @@ Distribution* ng_get_union_distribution(Distribution* distribution_1, Distributi
}
}
/*
* ng_get_union_distribution_recycle
* get union of two Distribution(s)
*
* @param (in) distribution_1:
* first Distribution(s) to union, it could be NULL
* if this parameter is NULL, reture the second Distribution as union
* @param (in) distribution_2:
* second Distribution(s) to union
*
* @return:
* the copied union Distribution and recycle their inputs
*/
Distribution* ng_get_union_distribution_recycle(Distribution* distribution_1, Distribution* distribution_2)
{
Distribution* result = ng_get_union_distribution(distribution_1, distribution_2);
DestroyDistribution(distribution_1);
DestroyDistribution(distribution_2);
return result;
}
Distribution* ng_get_random_single_dn_distribution(Distribution* distribution)
{
Distribution* result_distribution = NewDistribution();
@ -1478,6 +1585,7 @@ Distribution* ng_get_random_single_dn_distribution(Distribution* distribution)
}
AssertEreport(dn_oid >= 0, MOD_OPT, "");
result_distribution->bms_data_nodeids = bms_add_member(result_distribution->bms_data_nodeids, dn_oid);
result_distribution->group_oid = InvalidOid;
return result_distribution;
}
@ -1616,11 +1724,29 @@ ExecNodes* ng_convert_to_exec_nodes(Distribution* distribution, char locator_typ
return execnodes;
}
/*
* Check whether the distribution exists in the distributions.
*/
bool is_distribution_exists(List* distributions, Distribution* distribution)
{
bool find = false;
ListCell* lc = NULL;
foreach(lc, distributions) {
Distribution* tmp_distribution = (Distribution*)lfirst(lc);
if (tmp_distribution != NULL && ng_is_same_group(tmp_distribution, distribution)) {
find = true;
break;
}
}
return find;
}
/*
* Heuristic methods
*/
/*
* ng_get_candidate_distribution_list
* ng_get_join_candidate_distribution_list
* Get candidate Distribution list of a Join
* Three candidates will be taken:
* (1) the node group of outer path
@ -1636,35 +1762,45 @@ ExecNodes* ng_convert_to_exec_nodes(Distribution* distribution, char locator_typ
* @return:
* the candidates list
*/
List* ng_get_candidate_distribution_list(Path* outer_path, Path* inner_path)
List* ng_get_join_candidate_distribution_list(Path* outer_path, Path* inner_path, DistrbutionPreferenceType type)
{
List* candidate_list = NIL;
Distribution* distribution = NULL;
Distribution* distribution = ng_get_default_computing_group_distribution();
candidate_list = lappend(candidate_list, distribution);
/* Default compute distribution. */
if (type == DPT_ALL || type == DPT_SHUFFLE) {
distribution = ng_get_default_computing_group_distribution();
candidate_list = lappend(candidate_list, distribution);
ComputingNodeGroupMode cng_mode = ng_get_computing_nodegroup_mode();
if (CNG_MODE_FORCE == cng_mode) {
return candidate_list;
}
}
ComputingNodeGroupMode cng_mode = ng_get_computing_nodegroup_mode();
if (CNG_MODE_FORCE == cng_mode) {
return candidate_list;
/* Single node distribution. */
if (type == DPT_ALL || type == DPT_SINGLE) {
distribution = ng_get_single_node_distribution();
if (distribution != NULL && !is_distribution_exists(candidate_list, distribution)) {
candidate_list = lappend(candidate_list, distribution);
}
}
Distribution* outer_distribution = ng_get_dest_distribution(outer_path);
Distribution* inner_distribution = ng_get_dest_distribution(inner_path);
if (!ng_is_same_group(distribution, outer_distribution)) {
candidate_list = lappend(candidate_list, outer_distribution);
/* Join outer's distribution. */
distribution = ng_get_dest_distribution(outer_path);
if (!is_distribution_exists(candidate_list, distribution)) {
candidate_list = lappend(candidate_list, distribution);
}
if (!ng_is_same_group(distribution, inner_distribution) &&
(!ng_is_same_group(outer_distribution, inner_distribution))) {
candidate_list = lappend(candidate_list, inner_distribution);
/* Join inner's distribution. */
distribution = ng_get_dest_distribution(inner_path);
if (!is_distribution_exists(candidate_list, distribution)) {
candidate_list = lappend(candidate_list, distribution);
}
return candidate_list;
}
/*
* ng_get_candidate_distribution_list
* ng_get_join_candidate_distribution_list
* Get candidate Distribution list of a Join
* It will be different for correlated query block and un-correlated query block
* (1) for correlated query block, it's join should be in a special node group for correlated sub-plan
@ -1678,19 +1814,19 @@ List* ng_get_candidate_distribution_list(Path* outer_path, Path* inner_path)
* @return:
* the candidates list
*/
List* ng_get_candidate_distribution_list(Path* outer_path, Path* inner_path, bool is_correlated)
List* ng_get_join_candidate_distribution_list(Path* outer_path, Path* inner_path, bool is_correlated, DistrbutionPreferenceType type)
{
if (is_correlated) {
Distribution* installation_distribution = ng_get_correlated_subplan_group_distribution();
List* candidate_list = list_make1(installation_distribution);
return candidate_list;
} else {
return ng_get_candidate_distribution_list(outer_path, inner_path);
return ng_get_join_candidate_distribution_list(outer_path, inner_path, type);
}
}
/*
* ng_get_candidate_distribution_list
* ng_get_agg_candidate_distribution_list
* Get candidate Distribution list of an Agg
* Two candidates will be taken:
* (1) the default computing group of current computing mode
@ -1702,7 +1838,7 @@ List* ng_get_candidate_distribution_list(Path* outer_path, Path* inner_path, boo
* @return:
* the candidate Distribution list
*/
List* ng_get_candidate_distribution_list(Plan* plan, bool is_correlated)
List* ng_get_agg_candidate_distribution_list(Plan* plan, bool is_correlated, DistrbutionPreferenceType type)
{
if (is_correlated) {
Distribution* installation_distribution = ng_get_correlated_subplan_group_distribution();
@ -1711,26 +1847,36 @@ List* ng_get_candidate_distribution_list(Plan* plan, bool is_correlated)
}
List* candidate_list = NIL;
Distribution* distribution = NULL;
Distribution* distribution = ng_get_default_computing_group_distribution();
candidate_list = lappend(candidate_list, distribution);
ComputingNodeGroupMode cng_mode = ng_get_computing_nodegroup_mode();
if (CNG_MODE_FORCE == cng_mode) {
return candidate_list;
/* Default compute distribution. */
if (type == DPT_ALL || type == DPT_SHUFFLE) {
distribution = ng_get_default_computing_group_distribution();
candidate_list = lappend(candidate_list, distribution);
ComputingNodeGroupMode cng_mode = ng_get_computing_nodegroup_mode();
if (CNG_MODE_FORCE == cng_mode) {
return candidate_list;
}
}
Distribution* plan_distribution = ng_get_dest_distribution(plan);
if (!ng_is_same_group(distribution, plan_distribution)) {
candidate_list = lappend(candidate_list, plan_distribution);
/* Single node distribution. */
if (type == DPT_ALL || type == DPT_SINGLE) {
distribution = ng_get_single_node_distribution();
if (distribution != NULL && !is_distribution_exists(candidate_list, distribution)) {
candidate_list = lappend(candidate_list, distribution);
}
}
/* Agg's dest distribution. */
distribution = ng_get_dest_distribution(plan);
if (!is_distribution_exists(candidate_list, distribution)) {
candidate_list = lappend(candidate_list, distribution);
}
return candidate_list;
}
/*
* ng_get_candidate_distribution_list
* ng_get_setop_candidate_distribution_list
* Get candidate Distribution list of an setop
* Groups of all branchs will be taken.
*
@ -1740,7 +1886,7 @@ List* ng_get_candidate_distribution_list(Plan* plan, bool is_correlated)
* @return:
* the candidate Distribution list
*/
List* ng_get_candidate_distribution_list(List* subPlans, bool is_correlated)
List* ng_get_setop_candidate_distribution_list(List* subPlans, bool is_correlated)
{
if (is_correlated) {
Distribution* installation_distribution = ng_get_correlated_subplan_group_distribution();
@ -1753,19 +1899,9 @@ List* ng_get_candidate_distribution_list(List* subPlans, bool is_correlated)
ListCell* lc = NULL;
foreach (lc, subPlans) {
Plan* subPlan = (Plan*)lfirst(lc);
AssertEreport(subPlan->exec_nodes->nodeList != NIL, MOD_OPT, "");
Assert(subPlan->exec_nodes->nodeList != NIL);
Distribution* distribution = ng_get_dest_distribution(subPlan);
bool found = false;
ListCell* lc2 = NULL;
foreach (lc2, candidate_distribution_list) {
Distribution* prev_distribution = (Distribution*)lfirst(lc2);
if (ng_is_same_group(prev_distribution, distribution)) {
found = true;
}
}
if (!found) {
if (!is_distribution_exists(candidate_distribution_list, distribution)) {
candidate_distribution_list = lappend(candidate_distribution_list, distribution);
}
}
@ -1832,13 +1968,11 @@ Cost ng_calculate_setop_branch_stream_cost(
Plan* subPlan, unsigned int producer_num_datanodes, unsigned int consumer_num_datanodes)
{
Cost cost = 0;
const int AVERAGE_ROW_WIDTH = 8;
if (is_replicated_plan(subPlan)) {
/* 8 is average row width */
cost = (PLAN_LOCAL_ROWS(subPlan) / ((double)(consumer_num_datanodes))) * Max(subPlan->plan_width, AVERAGE_ROW_WIDTH);
if (is_replicated_plan(subPlan)) {
cost = (PLAN_LOCAL_ROWS(subPlan) / ((double)(consumer_num_datanodes))) * Max(subPlan->plan_width, 8);
} else {
cost = PLAN_LOCAL_ROWS(subPlan) * Max(subPlan->plan_width, AVERAGE_ROW_WIDTH);
cost = PLAN_LOCAL_ROWS(subPlan) * Max(subPlan->plan_width, 8);
}
return cost;
@ -1979,7 +2113,7 @@ Distribution* ng_get_best_setop_distribution(List* subPlans, bool isUnionAll, bo
return union_all_with_no_replicate;
}
List* candidate_distribution_list = ng_get_candidate_distribution_list(subPlans, is_correlated);
List* candidate_distribution_list = ng_get_setop_candidate_distribution_list(subPlans, is_correlated);
Cost min_total_cost = -1.0;
Distribution* best_distribution = NULL;
@ -2045,6 +2179,7 @@ void ng_stream_side_paths_for_replicate(PlannerInfo* root, Path** outer_path, Pa
bool is_outer_replicated = is_replicated_path(*outer_path);
bool is_inner_replicated = is_replicated_path(*inner_path);
if (!is_outer_replicated && !is_inner_replicated) {
ereport(ERROR,
(errmodule(MOD_OPT),
@ -2256,12 +2391,12 @@ bool ng_is_multiple_nodegroup_scenario()
}
/*
* ng_u_sess->opt_cxt.is_all_in_installation_nodegroup_scenario
* ng_u_sess->opt_cxt.different_nodegroup_count
* get wheather it's a everything in installation node group scenario
*/
bool ng_is_all_in_installation_nodegroup_scenario()
{
return u_sess->opt_cxt.is_all_in_installation_nodegroup_scenario;
return u_sess->opt_cxt.different_nodegroup_count == 1;
}
/*
@ -2528,3 +2663,149 @@ ExecNodes* ng_get_single_node_group_exec_node()
return exec_nodes;
}
char* dist_to_str(Distribution* distribution)
{
StringInfo str = makeStringInfo();
appendStringInfo(str, "groupid(%u) nodeids(", distribution->group_oid);
_outBitmapset(str, distribution->bms_data_nodeids);
appendStringInfo(str, ")");
return str->data;
}
bool ng_is_single_node_group_distribution(Distribution* distribution)
{
Distribution* single_node_distribution = u_sess->opt_cxt.single_node_distribution;
if (single_node_distribution == NULL || distribution == NULL) {
return false;
}
if (single_node_distribution == distribution) {
return true;
}
return ng_is_same_group(single_node_distribution, distribution);
}
int ng_get_different_nodegroup_count()
{
return u_sess->opt_cxt.different_nodegroup_count;
}
static int ngroup_hash_partition_id(int id)
{
return id % NUM_NGROUP_INFO_PARTITIONS;
}
static LWLock *ngroup_mapping_partitionlock(int hashcode)
{
int id = FirstNGroupMappingLock + ngroup_hash_partition_id(hashcode);
return &t_thrd.shemem_ptr_cxt.mainLWLockArray[id].lock;
}
void ngroup_info_hash_create()
{
const int num_hash_elems = 1024;
HASHCTL hash_ctl;
errno_t rc = memset_s(&hash_ctl, sizeof(hash_ctl), 0, sizeof(hash_ctl));
securec_check(rc, "", "");
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(NGroupInfo);
hash_ctl.hash = oid_hash;
hash_ctl.hcxt = g_instance.cache_cxt.global_cache_mem;
hash_ctl.num_partitions = NUM_NGROUP_INFO_PARTITIONS;
int flags = HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_EXTERN_CONTEXT | HASH_NOEXCEPT | HASH_PARTITION;
g_instance.ngroup_hash_table = hash_create("ngroup cache hash", num_hash_elems, &hash_ctl, flags);
if (g_instance.ngroup_hash_table == NULL) {
ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("nodegroup hash create failed")));
}
}
Bitmapset *ngroup_info_hash_search(Oid ngroup_oid)
{
Bitmapset *bms_nodeids = NULL;
bool found = false;
if (InvalidOid == ngroup_oid) {
List *nodeid_list = GetAllDataNodes();
bms_nodeids = ng_convert_to_nodeids(nodeid_list);
list_free(nodeid_list);
return bms_nodeids;
}
uint32 hashcode = oid_hash((const void *)&ngroup_oid, sizeof(ngroup_oid));
LWLock *new_partition_lock = ngroup_mapping_partitionlock(hashcode);
(void)LWLockAcquire(new_partition_lock, LW_SHARED);
NGroupInfo *ngroup_info = (NGroupInfo *)hash_search(g_instance.ngroup_hash_table, &ngroup_oid, HASH_FIND, &found);
if (found) {
/* the memory is release by caller */
bms_nodeids = bms_copy(ngroup_info->bms_nodeids);
}
LWLockRelease(new_partition_lock);
return bms_nodeids;
}
void ngroup_info_hash_insert(Oid ngroup_oid, Bitmapset *bms_node_ids)
{
bool found = false;
uint32 hashcode = oid_hash((const void *)&ngroup_oid, sizeof(ngroup_oid));
LWLock *new_partition_lock = ngroup_mapping_partitionlock(hashcode);
Bitmapset *bms_node_ids_copy = NULL;
MemoryContext old_mem_context = MemoryContextSwitchTo(g_instance.ngroup_hash_table->hcxt);
bms_node_ids_copy = bms_copy(bms_node_ids);
MemoryContextSwitchTo(old_mem_context);
(void)LWLockAcquire(new_partition_lock, LW_EXCLUSIVE);
NGroupInfo *ngroup_info = (NGroupInfo *)hash_search(g_instance.ngroup_hash_table, &ngroup_oid, HASH_ENTER, &found);
if (ngroup_info) {
ngroup_info->oid = ngroup_oid;
ngroup_info->bms_nodeids = bms_node_ids_copy;
} else {
LWLockRelease(new_partition_lock);
pfree(bms_node_ids_copy);
ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("failed to insert node group hash table")));
}
LWLockRelease(new_partition_lock);
}
void ngroup_info_hash_delete(Oid ngroup_oid)
{
if (InvalidOid == ngroup_oid) {
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NODE_STATE),
errmsg("NodeGroup Oid is invalid, invalid Oid is %u.", ngroup_oid)));
}
bool found = false;
Bitmapset *bms_ptr = NULL;
uint32 hashcode = oid_hash((const void *)&ngroup_oid, sizeof(ngroup_oid));
LWLock *new_partition_lock = ngroup_mapping_partitionlock(hashcode);
(void)LWLockAcquire(new_partition_lock, LW_EXCLUSIVE);
NGroupInfo *ngroup_info = (NGroupInfo *)hash_search(g_instance.ngroup_hash_table, &ngroup_oid, HASH_FIND, &found);
if (ngroup_info)
bms_ptr = ngroup_info->bms_nodeids;
hash_search(g_instance.ngroup_hash_table, &ngroup_oid, HASH_REMOVE, &found);
LWLockRelease(new_partition_lock);
if (!found && ngroup_info) {
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NODE_STATE),
errmsg("delete failed from nodegroup hash table, Oid is %u.", ngroup_oid)));
}
if (bms_ptr)
pfree(bms_ptr);
}