diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-03-27 18:03:03 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-03-27 18:03:03 +0200 |
commit | e538cb095f6290c40e8928e3813db6ac679740a2 (patch) | |
tree | 51f12fad5a2928fc1d398e7f45fc40c1c09e2512 /sql | |
parent | 356c149603285086d964c8a51107be97b981c15c (diff) | |
parent | 80459bcbd4ca2cfd149f58c41428882fcfc49e03 (diff) | |
download | mariadb-git-e538cb095f6290c40e8928e3813db6ac679740a2.tar.gz |
Merge 10.5 into 10.6
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 5 | ||||
-rw-r--r-- | sql/log.cc | 61 | ||||
-rw-r--r-- | sql/opt_split.cc | 48 | ||||
-rw-r--r-- | sql/sql_insert.cc | 3 | ||||
-rw-r--r-- | sql/sql_join_cache.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 17 | ||||
-rw-r--r-- | sql/sql_test.cc | 8 |
7 files changed, 114 insertions, 30 deletions
diff --git a/sql/item.cc b/sql/item.cc index 1a86b8b3114..3dbe3badadf 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5493,8 +5493,9 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) Name_resolution_context *outer_context= 0; SELECT_LEX *select= 0; /* Currently derived tables cannot be correlated */ - if (current_sel->master_unit()->first_select()->get_linkage() != - DERIVED_TABLE_TYPE) + if ((current_sel->master_unit()->first_select()->get_linkage() != + DERIVED_TABLE_TYPE) && + current_sel->master_unit()->outer_select()) outer_context= context->outer_context; /* diff --git a/sql/log.cc b/sql/log.cc index 3b1322035eb..894fecf93f1 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2018, Oracle and/or its affiliates. - Copyright (c) 2009, 2020, MariaDB Corporation. + Copyright (c) 2009, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -7674,6 +7674,8 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd, new transaction directly to participate in the group commit. @retval < 0 Error + @retval -2 WSREP error with commit ordering + @retval -3 WSREP return code to mark the leader @retval > 0 If queued as the first entry in the queue (meaning this is the leader) @retval 0 Otherwise (queued as participant, leader handles the commit) @@ -7971,6 +7973,22 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry) cur= entry->thd->wait_for_commit_ptr; } +#ifdef WITH_WSREP + if (wsrep_is_active(entry->thd) && + wsrep_run_commit_hook(entry->thd, entry->all)) + { + /* Release commit order here */ + if (wsrep_ordered_commit(entry->thd, entry->all)) + result= -2; + + /* return -3, if this is leader */ + if (orig_queue == NULL) + result= -3; + } + else + DBUG_ASSERT(result != -2 && result != -3); +#endif /* WITH_WSREP */ + if (opt_binlog_commit_wait_count > 0 && orig_queue != NULL) mysql_cond_signal(&COND_prepare_ordered); mysql_mutex_unlock(&LOCK_prepare_ordered); @@ -7992,25 +8010,32 @@ MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry) { int is_leader= queue_for_group_commit(entry); #ifdef WITH_WSREP - if (wsrep_is_active(entry->thd) && - wsrep_run_commit_hook(entry->thd, entry->all)) - { - /* - Release commit order and if leader, wait for prior commit to - complete. This establishes total order for group leaders. - */ - if (wsrep_ordered_commit(entry->thd, entry->all)) - { - entry->thd->wakeup_subsequent_commits(1); - return 1; - } - if (is_leader) - { - if (entry->thd->wait_for_prior_commit()) - return 1; - } + /* commit order was released in queue_for_group_commit() call, + here we check if wsrep_commit_ordered() failed or if we are leader */ + switch (is_leader) + { + case -2: /* wsrep_ordered_commit() has failed */ + DBUG_ASSERT(wsrep_is_active(entry->thd)); + DBUG_ASSERT(wsrep_run_commit_hook(entry->thd, entry->all)); + entry->thd->wakeup_subsequent_commits(1); + return true; + case -3: /* this is leader, wait for prior commit to + complete. This establishes total order for group leaders + */ + DBUG_ASSERT(wsrep_is_active(entry->thd)); + DBUG_ASSERT(wsrep_run_commit_hook(entry->thd, entry->all)); + if (entry->thd->wait_for_prior_commit()) + return true; + + /* retain the correct is_leader value */ + is_leader= 1; + break; + + default: /* native MariaDB cases */ + break; } #endif /* WITH_WSREP */ + /* The first in the queue handles group commit for all; the others just wait to be signalled when group commit is done. diff --git a/sql/opt_split.cc b/sql/opt_split.cc index 6cb4a12e51f..2aa65bdf03b 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -236,6 +236,8 @@ public: SplM_field_info *spl_fields; /* The number of elements in the above list */ uint spl_field_cnt; + /* The list of equalities injected into WHERE for split optimization */ + List<Item> inj_cond_list; /* Contains the structures to generate all KEYUSEs for pushable equalities */ List<KEY_FIELD> added_key_fields; /* The cache of evaluated execution plans for 'join' with pushed equalities */ @@ -1045,22 +1047,22 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count, bool JOIN::inject_best_splitting_cond(table_map remaining_tables) { Item *inj_cond= 0; - List<Item> inj_cond_list; + List<Item> *inj_cond_list= &spl_opt_info->inj_cond_list; List_iterator<KEY_FIELD> li(spl_opt_info->added_key_fields); KEY_FIELD *added_key_field; while ((added_key_field= li++)) { if (remaining_tables & added_key_field->val->used_tables()) continue; - if (inj_cond_list.push_back(added_key_field->cond, thd->mem_root)) + if (inj_cond_list->push_back(added_key_field->cond, thd->mem_root)) return true; } - DBUG_ASSERT(inj_cond_list.elements); - switch (inj_cond_list.elements) { + DBUG_ASSERT(inj_cond_list->elements); + switch (inj_cond_list->elements) { case 1: - inj_cond= inj_cond_list.head(); break; + inj_cond= inj_cond_list->head(); break; default: - inj_cond= new (thd->mem_root) Item_cond_and(thd, inj_cond_list); + inj_cond= new (thd->mem_root) Item_cond_and(thd, *inj_cond_list); if (!inj_cond) return true; } @@ -1080,6 +1082,40 @@ bool JOIN::inject_best_splitting_cond(table_map remaining_tables) /** @brief + Test if equality is injected for split optimization + + @param + eq_item equality to to test + + @retval + true eq_item is equality injected for split optimization + false otherwise +*/ + +bool is_eq_cond_injected_for_split_opt(Item_func_eq *eq_item) +{ + Item *left_item= eq_item->arguments()[0]->real_item(); + if (left_item->type() != Item::FIELD_ITEM) + return false; + Field *field= ((Item_field *) left_item)->field; + if (!field->table->reginfo.join_tab) + return false; + JOIN *join= field->table->reginfo.join_tab->join; + if (!join->spl_opt_info) + return false; + List_iterator_fast<Item> li(join->spl_opt_info->inj_cond_list); + Item *item; + while ((item= li++)) + { + if (item == eq_item) + return true; + } + return false; +} + + +/** + @brief Fix the splitting chosen for a splittable table in the final query plan @param diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f0b84ab126f..041a64d402d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4937,7 +4937,8 @@ bool select_create::send_eof() if (!table->s->tmp_table) { #ifdef WITH_WSREP - if (WSREP(thd)) + if (WSREP(thd) && + table->file->ht->db_type == DB_TYPE_INNODB) { if (thd->wsrep_trx_id() == WSREP_UNDEFINED_TRX_ID) { diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 8fae2073b01..620c52a3f40 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -1201,7 +1201,7 @@ bool JOIN_CACHE::check_emb_key_usage() Item *item= ref->items[i]->real_item(); Field *fld= ((Item_field *) item)->field; CACHE_FIELD *init_copy= field_descr+flag_fields+i; - for (j= i, copy= init_copy; i < local_key_arg_fields; i++, copy++) + for (j= i, copy= init_copy; j < local_key_arg_fields; j++, copy++) { if (fld->eq(copy->field)) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 155c68545fc..794bc4d69ae 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -299,6 +299,8 @@ void set_postjoin_aggr_write_func(JOIN_TAB *tab); static Item **get_sargable_cond(JOIN *join, TABLE *table); +bool is_eq_cond_injected_for_split_opt(Item_func_eq *eq_item); + static bool build_notnull_conds_for_range_scans(JOIN *join, COND *cond, table_map allowed); @@ -22783,6 +22785,21 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond, cond->marker=3; // Checked when read return (COND*) 0; } + /* + If cond is an equality injected for split optimization then + a. when retain_ref_cond == false : cond is removed unconditionally + (cond that supports ref access is removed by the preceding code) + b. when retain_ref_cond == true : cond is removed if it does not + support ref access + */ + if (left_item->type() == Item::FIELD_ITEM && + is_eq_cond_injected_for_split_opt((Item_func_eq *) cond) && + (!retain_ref_cond || + !test_if_ref(root_cond, (Item_field*) left_item,right_item))) + { + cond->marker=3; + return (COND*) 0; + } } cond->marker=2; cond->set_join_tab_idx(join_tab_idx_arg); diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 3f1728d334f..3ff23219f87 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -617,8 +617,12 @@ Next alarm time: %lu\n", (ulong)alarm_info.next_alarm_time); #endif display_table_locks(); -#ifdef HAVE_MALLINFO - struct mallinfo info= mallinfo(); +#if defined(HAVE_MALLINFO2) + struct mallinfo2 info = mallinfo2(); +#elif defined(HAVE_MALLINFO) + struct mallinfo info= mallinfo(); +#endif +#if defined(HAVE_MALLINFO) || defined(HAVE_MALLINFO2) char llbuff[10][22]; printf("\nMemory status:\n\ Non-mmapped space allocated from system: %s\n\ |