summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-03-27 18:03:03 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-03-27 18:03:03 +0200
commite538cb095f6290c40e8928e3813db6ac679740a2 (patch)
tree51f12fad5a2928fc1d398e7f45fc40c1c09e2512 /sql
parent356c149603285086d964c8a51107be97b981c15c (diff)
parent80459bcbd4ca2cfd149f58c41428882fcfc49e03 (diff)
downloadmariadb-git-e538cb095f6290c40e8928e3813db6ac679740a2.tar.gz
Merge 10.5 into 10.6
Diffstat (limited to 'sql')
-rw-r--r--sql/item.cc5
-rw-r--r--sql/log.cc61
-rw-r--r--sql/opt_split.cc48
-rw-r--r--sql/sql_insert.cc3
-rw-r--r--sql/sql_join_cache.cc2
-rw-r--r--sql/sql_select.cc17
-rw-r--r--sql/sql_test.cc8
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\