summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-03-29 12:59:18 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-03-29 12:59:18 +0300
commitd62b0368ca53cc10b45b703bbeefcf0b674bd39d (patch)
treee65926bf20605d24a87619553374a74e7ef1c2c8 /sql
parent9d6d1221230e2acf9fac2ab6fe685c0a2a7845aa (diff)
parent088b37b5eaa8c3198c7f8ea0358d15135833f6bb (diff)
downloadmariadb-git-d62b0368ca53cc10b45b703bbeefcf0b674bd39d.tar.gz
Merge 10.4 into 10.5
Diffstat (limited to 'sql')
-rw-r--r--sql/contributors.h2
-rw-r--r--sql/handler.h4
-rw-r--r--sql/item.cc20
-rw-r--r--sql/item_cmpfunc.cc7
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/log.cc4
-rw-r--r--sql/rpl_rli.cc2
-rw-r--r--sql/semisync_master.cc1
-rw-r--r--sql/sp_head.cc1
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h26
-rw-r--r--sql/sql_lex.cc89
-rw-r--r--sql/sql_lex.h11
-rw-r--r--sql/sql_parse.cc22
-rw-r--r--sql/sql_prepare.cc12
-rw-r--r--sql/sql_show.cc12
-rw-r--r--sql/sql_table.cc49
-rw-r--r--sql/sql_tvc.cc31
-rw-r--r--sql/sql_update.cc5
-rw-r--r--sql/sql_view.cc3
-rw-r--r--sql/sql_yacc.yy50
-rw-r--r--sql/table.cc22
-rw-r--r--sql/unireg.cc11
-rw-r--r--sql/wsrep_client_service.cc1
-rw-r--r--sql/wsrep_high_priority_service.cc1
-rw-r--r--sql/wsrep_mysqld.cc87
-rw-r--r--sql/wsrep_mysqld.h1
-rw-r--r--sql/wsrep_sst.cc81
28 files changed, 465 insertions, 93 deletions
diff --git a/sql/contributors.h b/sql/contributors.h
index e16448ee985..bc8ba4eabbb 100644
--- a/sql/contributors.h
+++ b/sql/contributors.h
@@ -42,6 +42,8 @@ struct show_table_contributors_st show_table_contributors[]= {
{"Microsoft", "https://microsoft.com/", "Platinum Sponsor of the MariaDB Foundation"},
{"MariaDB Corporation", "https://mariadb.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
{"ServiceNow", "https://servicenow.com", "Platinum Sponsor of the MariaDB Foundation"},
+ {"Intel", "https://www.intel.com", "Platinum Sponsor of the MariaDB Foundation"},
+ {"SIT", "https://sit.org", "Platinum Sponsor of the MariaDB Foundation"},
{"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"},
{"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
{"IBM", "https://www.ibm.com", "Gold Sponsor of the MariaDB Foundation"},
diff --git a/sql/handler.h b/sql/handler.h
index ff67235cd70..9eec3f13c73 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -2,7 +2,7 @@
#define HANDLER_INCLUDED
/*
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2009, 2021, MariaDB
+ Copyright (c) 2009, 2022, MariaDB
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -5161,7 +5161,7 @@ static inline const char *ha_resolve_storage_engine_name(const handlerton *db_ty
static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
{
- return db_type == NULL ? FALSE : MY_TEST(db_type->flags & flag);
+ return db_type && (db_type->flags & flag);
}
static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
diff --git a/sql/item.cc b/sql/item.cc
index 5271adb7d50..e941fae9d4c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2730,9 +2730,11 @@ Item_sp::func_name(THD *thd) const
/* Calculate length to avoid reallocation of string for sure */
size_t len= (((m_name->m_explicit_name ? m_name->m_db.length : 0) +
m_name->m_name.length)*2 + //characters*quoting
- 2 + // ` and `
+ 2 + // quotes for the function name
+ 2 + // quotes for the package name
(m_name->m_explicit_name ?
3 : 0) + // '`', '`' and '.' for the db
+ 1 + // '.' between package and function
1 + // end of string
ALIGN_SIZE(1)); // to avoid String reallocation
String qname((char *)alloc_root(thd->mem_root, len), len,
@@ -2744,7 +2746,21 @@ Item_sp::func_name(THD *thd) const
append_identifier(thd, &qname, &m_name->m_db);
qname.append('.');
}
- append_identifier(thd, &qname, &m_name->m_name);
+ if (m_sp && m_sp->m_handler == &sp_handler_package_function)
+ {
+ /*
+ In case of a package function split `pkg.func` and print
+ quoted `pkg` and `func` separately, so the entire result looks like:
+ `db`.`pkg`.`func`
+ */
+ Database_qualified_name tmp= Database_qualified_name::split(m_name->m_name);
+ DBUG_ASSERT(tmp.m_db.length);
+ append_identifier(thd, &qname, &tmp.m_db);
+ qname.append('.');
+ append_identifier(thd, &qname, &tmp.m_name);
+ }
+ else
+ append_identifier(thd, &qname, &m_name->m_name);
return qname.c_ptr_safe();
}
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ddabdaaff53..ae798913163 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -4719,10 +4719,11 @@ void Item_func_in::mark_as_condition_AND_part(TABLE_LIST *embedding)
Query_arena *arena, backup;
arena= thd->activate_stmt_arena_if_needed(&backup);
- if (to_be_transformed_into_in_subq(thd))
+ if (!transform_into_subq_checked)
{
- transform_into_subq= true;
- thd->lex->current_select->in_funcs.push_back(this, thd->mem_root);
+ if ((transform_into_subq= to_be_transformed_into_in_subq(thd)))
+ thd->lex->current_select->in_funcs.push_back(this, thd->mem_root);
+ transform_into_subq_checked= true;
}
if (arena)
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index aa7269ab95a..4eb9416af17 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -2365,6 +2365,7 @@ protected:
SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
Field *field, Item *value);
bool transform_into_subq;
+ bool transform_into_subq_checked;
public:
/// An array of values, created when the bisection lookup method is used
in_vector *array;
@@ -2387,6 +2388,7 @@ public:
Item_func_opt_neg(thd, list),
Predicant_to_list_comparator(thd, arg_count - 1),
transform_into_subq(false),
+ transform_into_subq_checked(false),
array(0), have_null(0),
arg_types_compatible(FALSE), emb_on_expr_nest(0)
{ }
diff --git a/sql/log.cc b/sql/log.cc
index d0dcb5d3725..a8a50fe7b79 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, 2021, MariaDB Corporation.
+ Copyright (c) 2009, 2022, 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
@@ -5838,6 +5838,8 @@ THD::binlog_start_trans_and_stmt()
}
Gtid_log_event gtid_event(this, seqno, domain_id, true,
LOG_EVENT_SUPPRESS_USE_F, true, 0);
+ // Replicated events in writeset doesn't have checksum
+ gtid_event.checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
gtid_event.server_id= server_id;
writer.write(&gtid_event);
wsrep_write_cache_buf(&tmp_io_cache, &buf, &len);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 9a40114ad36..35d84792fcb 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1671,7 +1671,7 @@ end:
{
table->file->ha_index_or_rnd_end();
ha_commit_trans(thd, FALSE);
- ha_commit_trans(thd, TRUE);
+ trans_commit(thd);
}
if (table_opened)
{
diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc
index 2480eebf8d7..cfe29824328 100644
--- a/sql/semisync_master.cc
+++ b/sql/semisync_master.cc
@@ -1229,6 +1229,7 @@ int Repl_semi_sync_master::flush_net(THD *thd,
net_clear(net, 0);
net->pkt_nr++;
+ net->compress_pkt_nr++;
result = 0;
rpl_semi_sync_master_net_wait_num++;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 11571ed706c..2ba2e70ccce 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -3547,6 +3547,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
lex_query_tables_own_last= m_lex->query_tables_own_last;
prelocking_tables= *lex_query_tables_own_last;
*lex_query_tables_own_last= NULL;
+ m_lex->query_tables_last= m_lex->query_tables_own_last;
m_lex->mark_as_requiring_prelocking(NULL);
}
thd->rollback_item_tree_changes();
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 00b53c86688..c53fa5bf1ff 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -703,6 +703,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
wsrep_has_ignored_error(false),
wsrep_ignore_table(false),
wsrep_aborter(0),
+ wsrep_delayed_BF_abort(false),
/* wsrep-lib */
m_wsrep_next_trx_id(WSREP_UNDEFINED_TRX_ID),
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 65b039d89fb..6b8a0403d9d 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4354,13 +4354,13 @@ public:
*/
DBUG_PRINT("debug",
("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
- YESNO(has_thd_temporary_tables()), YESNO(in_sub_stmt),
+ YESNO(has_temporary_tables()), YESNO(in_sub_stmt),
show_system_thread(system_thread)));
if (in_sub_stmt == 0)
{
if (wsrep_binlog_format() == BINLOG_FORMAT_ROW)
set_current_stmt_binlog_format_row();
- else if (!has_thd_temporary_tables())
+ else if (!has_temporary_tables())
set_current_stmt_binlog_format_stmt();
}
DBUG_VOID_RETURN;
@@ -5062,6 +5062,10 @@ public:
/* thread who has started kill for this THD protected by LOCK_thd_data*/
my_thread_id wsrep_aborter;
+ /* true if BF abort is observed in do_command() right after reading
+ client's packet, and if the client has sent PS execute command. */
+ bool wsrep_delayed_BF_abort;
+
/*
Transaction id:
* m_wsrep_next_trx_id is assigned on the first query after
@@ -5093,7 +5097,10 @@ public:
{
return m_wsrep_next_trx_id;
}
-
+ /*
+ If node is async slave and have parallel execution, wait for prior commits.
+ */
+ bool wsrep_parallel_slave_wait_for_prior_commit();
private:
wsrep_trx_id_t m_wsrep_next_trx_id; /* cast from query_id_t */
/* wsrep-lib */
@@ -7271,6 +7278,19 @@ public:
}
void copy(MEM_ROOT *mem_root, const LEX_CSTRING &db,
const LEX_CSTRING &name);
+
+ static Database_qualified_name split(const LEX_CSTRING &txt)
+ {
+ DBUG_ASSERT(txt.str[txt.length] == '\0'); // Expect 0-terminated input
+ const char *dot= strchr(txt.str, '.');
+ if (!dot)
+ return Database_qualified_name(NULL, 0, txt.str, txt.length);
+ size_t dblen= dot - txt.str;
+ Lex_cstring db(txt.str, dblen);
+ Lex_cstring name(txt.str + dblen + 1, txt.length - dblen - 1);
+ return Database_qualified_name(db, name);
+ }
+
// Export db and name as a qualified name string: 'db.name'
size_t make_qname(char *dst, size_t dstlen) const
{
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index b64d94aac57..c2f2dc05da6 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2009, 2021, MariaDB Corporation.
+ Copyright (c) 2009, 2022, 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
@@ -9164,6 +9164,43 @@ bool LEX::call_statement_start(THD *thd, const Lex_ident_sys_st *name1,
}
+bool LEX::call_statement_start(THD *thd,
+ const Lex_ident_sys_st *db,
+ const Lex_ident_sys_st *pkg,
+ const Lex_ident_sys_st *proc)
+{
+ Database_qualified_name q_db_pkg(db, pkg);
+ Database_qualified_name q_pkg_proc(pkg, proc);
+ sp_name *spname;
+
+ sql_command= SQLCOM_CALL;
+
+ if (check_db_name(reinterpret_cast<LEX_STRING*>
+ (const_cast<LEX_CSTRING*>
+ (static_cast<const LEX_CSTRING*>(db)))))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
+ return NULL;
+ }
+ if (check_routine_name(pkg) ||
+ check_routine_name(proc))
+ return NULL;
+
+ // Concat `pkg` and `name` to `pkg.name`
+ LEX_CSTRING pkg_dot_proc;
+ if (q_pkg_proc.make_qname(thd->mem_root, &pkg_dot_proc) ||
+ check_ident_length(&pkg_dot_proc) ||
+ !(spname= new (thd->mem_root) sp_name(db, &pkg_dot_proc, true)))
+ return NULL;
+
+ sp_handler_package_function.add_used_routine(thd->lex, thd, spname);
+ sp_handler_package_body.add_used_routine(thd->lex, thd, &q_db_pkg);
+
+ return !(m_sql_cmd= new (thd->mem_root) Sql_cmd_call(spname,
+ &sp_handler_package_procedure));
+}
+
+
sp_package *LEX::get_sp_package() const
{
return sphead ? sphead->get_package() : NULL;
@@ -9418,6 +9455,56 @@ Item *LEX::make_item_func_call_generic(THD *thd, Lex_ident_cli_st *cdb,
}
+/*
+ Create a 3-step qualified function call.
+ Currently it's possible for package routines only, e.g.:
+ SELECT db.pkg.func();
+*/
+Item *LEX::make_item_func_call_generic(THD *thd,
+ Lex_ident_cli_st *cdb,
+ Lex_ident_cli_st *cpkg,
+ Lex_ident_cli_st *cfunc,
+ List<Item> *args)
+{
+ static Lex_cstring dot(".", 1);
+ Lex_ident_sys db(thd, cdb), pkg(thd, cpkg), func(thd, cfunc);
+ Database_qualified_name q_db_pkg(db, pkg);
+ Database_qualified_name q_pkg_func(pkg, func);
+ sp_name *qname;
+
+ if (db.is_null() || pkg.is_null() || func.is_null())
+ return NULL; // EOM
+
+ if (check_db_name((LEX_STRING*) static_cast<LEX_CSTRING*>(&db)))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
+ return NULL;
+ }
+ if (check_routine_name(&pkg) ||
+ check_routine_name(&func))
+ return NULL;
+
+ // Concat `pkg` and `name` to `pkg.name`
+ LEX_CSTRING pkg_dot_func;
+ if (q_pkg_func.make_qname(thd->mem_root, &pkg_dot_func) ||
+ check_ident_length(&pkg_dot_func) ||
+ !(qname= new (thd->mem_root) sp_name(&db, &pkg_dot_func, true)))
+ return NULL;
+
+ sp_handler_package_function.add_used_routine(thd->lex, thd, qname);
+ sp_handler_package_body.add_used_routine(thd->lex, thd, &q_db_pkg);
+
+ thd->lex->safe_to_cache_query= 0;
+
+ if (args && args->elements > 0)
+ return new (thd->mem_root) Item_func_sp(thd, thd->lex->current_context(),
+ qname, &sp_handler_package_function,
+ *args);
+ return new (thd->mem_root) Item_func_sp(thd, thd->lex->current_context(),
+ qname, &sp_handler_package_function);
+}
+
+
Item *LEX::make_item_func_call_native_or_parse_error(THD *thd,
Lex_ident_cli_st &name,
List<Item> *args)
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 3ef94c5bddb..afc93e5a646 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2010, 2021, MariaDB Corporation
+ Copyright (c) 2010, 2022, 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
@@ -3850,6 +3850,10 @@ public:
bool call_statement_start(THD *thd, const Lex_ident_sys_st *name);
bool call_statement_start(THD *thd, const Lex_ident_sys_st *name1,
const Lex_ident_sys_st *name2);
+ bool call_statement_start(THD *thd,
+ const Lex_ident_sys_st *db,
+ const Lex_ident_sys_st *pkg,
+ const Lex_ident_sys_st *proc);
sp_variable *find_variable(const LEX_CSTRING *name,
sp_pcontext **ctx,
const Sp_rcontext_handler **rh) const;
@@ -4093,6 +4097,11 @@ public:
Item *make_item_func_substr(THD *thd, Item *a, Item *b);
Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db,
Lex_ident_cli_st *name, List<Item> *args);
+ Item *make_item_func_call_generic(THD *thd,
+ Lex_ident_cli_st *db,
+ Lex_ident_cli_st *pkg,
+ Lex_ident_cli_st *name,
+ List<Item> *args);
Item *make_item_func_call_native_or_parse_error(THD *thd,
Lex_ident_cli_st &name,
List<Item> *args);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index ac8a4b5b142..55968fe7ddc 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1163,8 +1163,7 @@ static bool wsrep_tables_accessible_when_detached(const TABLE_LIST *tables)
static bool wsrep_command_no_result(char command)
{
- return (command == COM_STMT_PREPARE ||
- command == COM_STMT_FETCH ||
+ return (command == COM_STMT_FETCH ||
command == COM_STMT_SEND_LONG_DATA ||
command == COM_STMT_CLOSE);
}
@@ -1310,7 +1309,13 @@ bool do_command(THD *thd)
DBUG_ASSERT(!thd->mdl_context.has_locks());
DBUG_ASSERT(!thd->get_stmt_da()->is_set());
/* We let COM_QUIT and COM_STMT_CLOSE to execute even if wsrep aborted. */
- if (command != COM_STMT_CLOSE &&
+ if (command == COM_STMT_EXECUTE)
+ {
+ WSREP_DEBUG("PS BF aborted at do_command");
+ thd->wsrep_delayed_BF_abort= true;
+ }
+ if (command != COM_STMT_CLOSE &&
+ command != COM_STMT_EXECUTE &&
command != COM_QUIT)
{
my_error(ER_LOCK_DEADLOCK, MYF(0));
@@ -1383,6 +1388,17 @@ out:
if (unlikely(wsrep_service_started))
wsrep_after_command_after_result(thd);
}
+
+ if (thd->wsrep_delayed_BF_abort)
+ {
+ my_error(ER_LOCK_DEADLOCK, MYF(0));
+ WSREP_DEBUG("Deadlock error for PS query: %s", thd->query());
+ thd->reset_killed();
+ thd->mysys_var->abort = 0;
+ thd->wsrep_retry_counter = 0;
+
+ thd->wsrep_delayed_BF_abort= false;
+ }
#endif /* WITH_WSREP */
DBUG_RETURN(return_value);
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index a88ee423203..b5472d2b5c1 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2342,6 +2342,10 @@ static bool check_prepared_statement(Prepared_statement *stmt)
goto error;
}
+#ifdef WITH_WSREP
+ if (wsrep_sync_wait(thd, sql_command))
+ goto error;
+#endif
switch (sql_command) {
case SQLCOM_REPLACE:
case SQLCOM_INSERT:
@@ -4487,7 +4491,13 @@ Prepared_statement::execute_loop(String *expanded_query,
if (set_parameters(expanded_query, packet, packet_end))
return TRUE;
-
+#ifdef WITH_WSREP
+ if (thd->wsrep_delayed_BF_abort)
+ {
+ WSREP_DEBUG("delayed BF abort, quitting execute_loop, stmt: %d", id);
+ return TRUE;
+ }
+#endif /* WITH_WSREP */
reexecute:
// Make sure that reprepare() did not create any new Items.
DBUG_ASSERT(thd->free_list == NULL);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index ff6ec637025..5bf54fb1791 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2009, 2021, MariaDB
+ Copyright (c) 2009, 2022, MariaDB
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
@@ -3296,6 +3296,16 @@ static my_bool processlist_callback(THD *tmp, processlist_callback_arg *arg)
arg->table->field[11]->store((double) tmp->progress.counter /
(double) max_counter*100.0);
}
+ else
+ {
+ /*
+ This is a DECIMAL column without DEFAULT.
+ restore_record() fills its Field::ptr to zero bytes,
+ according to pack_length(). But an array of zero bytes
+ is not a valid decimal. Set it explicitly to 0.
+ */
+ arg->table->field[11]->store((longlong) 0, true);
+ }
mysql_mutex_unlock(&tmp->LOCK_thd_data);
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 13203ee28ad..16fb9870e07 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -9957,7 +9957,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
{
bool engine_changed, error;
bool no_ha_table= true; /* We have not created table in storage engine yet */
- TABLE *table, *new_table;
+ TABLE *table, *new_table= nullptr;
#ifdef WITH_PARTITION_STORAGE_ENGINE
bool partition_changed= false;
bool fast_alter_partition= false;
@@ -9980,7 +9980,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
bool varchar= create_info->varchar, table_creation_was_logged= 0;
bool binlog_as_create_select= 0, log_if_exists= 0;
uint tables_opened;
- handlerton *new_db_type, *old_db_type;
+ handlerton *new_db_type= create_info->db_type, *old_db_type;
ha_rows copied=0, deleted=0;
LEX_CUSTRING frm= {0,0};
char index_file[FN_REFLEN], data_file[FN_REFLEN];
@@ -10311,22 +10311,24 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
}
+ old_db_type= table->s->db_type();
+ new_db_type= create_info->db_type;
+
DBUG_PRINT("info", ("old type: %s new type: %s",
- ha_resolve_storage_engine_name(table->s->db_type()),
- ha_resolve_storage_engine_name(create_info->db_type)));
- if (ha_check_storage_engine_flag(table->s->db_type(), HTON_ALTER_NOT_SUPPORTED))
+ ha_resolve_storage_engine_name(old_db_type),
+ ha_resolve_storage_engine_name(new_db_type)));
+ if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED))
{
DBUG_PRINT("info", ("doesn't support alter"));
- my_error(ER_ILLEGAL_HA, MYF(0), hton_name(table->s->db_type())->str,
+ my_error(ER_ILLEGAL_HA, MYF(0), hton_name(old_db_type)->str,
alter_ctx.db.str, alter_ctx.table_name.str);
DBUG_RETURN(true);
}
- if (ha_check_storage_engine_flag(create_info->db_type,
- HTON_ALTER_NOT_SUPPORTED))
+ if (ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
{
DBUG_PRINT("info", ("doesn't support alter"));
- my_error(ER_ILLEGAL_HA, MYF(0), hton_name(create_info->db_type)->str,
+ my_error(ER_ILLEGAL_HA, MYF(0), hton_name(new_db_type)->str,
alter_ctx.new_db.str, alter_ctx.new_name.str);
DBUG_RETURN(true);
}
@@ -10477,6 +10479,17 @@ do_continue:;
DBUG_RETURN(true);
}
}
+ /*
+ If the old table had partitions and we are doing ALTER TABLE ...
+ engine= <new_engine>, the new table must preserve the original
+ partitioning. This means that the new engine is still the
+ partitioning engine, not the engine specified in the parser.
+ This is discovered in prep_alter_part_table, which in such case
+ updates create_info->db_type.
+ It's therefore important that the assignment below is done
+ after prep_alter_part_table.
+ */
+ new_db_type= create_info->db_type;
#endif
if (mysql_prepare_alter_table(thd, table, create_info, alter_info,
@@ -10557,7 +10570,7 @@ do_continue:;
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
|| is_inplace_alter_impossible(table, create_info, alter_info)
|| IF_PARTITIONING((partition_changed &&
- !(table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)), 0))
+ !(old_db_type->partition_flags() & HA_USE_AUTO_PARTITION)), 0))
{
if (alter_info->algorithm(thd) ==
Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
@@ -10575,25 +10588,11 @@ do_continue:;
request table rebuild. Set ALTER_RECREATE flag to force table
rebuild.
*/
- if (create_info->db_type == table->s->db_type() &&
+ if (new_db_type == old_db_type &&
create_info->used_fields & HA_CREATE_USED_ENGINE)
alter_info->flags|= ALTER_RECREATE;
/*
- If the old table had partitions and we are doing ALTER TABLE ...
- engine= <new_engine>, the new table must preserve the original
- partitioning. This means that the new engine is still the
- partitioning engine, not the engine specified in the parser.
- This is discovered in prep_alter_part_table, which in such case
- updates create_info->db_type.
- It's therefore important that the assignment below is done
- after prep_alter_part_table.
- */
- new_db_type= create_info->db_type;
- old_db_type= table->s->db_type();
- new_table= NULL;
-
- /*
Handling of symlinked tables:
If no rename:
Create new data file and index file on the same disk as the
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc
index 9b9b07d55cd..a29f6303607 100644
--- a/sql/sql_tvc.cc
+++ b/sql/sql_tvc.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, 2020, MariaDB
+/* Copyright (c) 2017, 2022, MariaDB
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
@@ -931,13 +931,11 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
{
if (!transform_into_subq)
return this;
-
+
Json_writer_object trace_wrapper(thd);
Json_writer_object trace_conv(thd, "in_to_subquery_conversion");
trace_conv.add("item", this);
- transform_into_subq= false;
-
List<List_item> values;
LEX *lex= thd->lex;
@@ -1111,15 +1109,38 @@ uint32 Item_func_in::max_length_of_left_expr()
bool Item_func_in::to_be_transformed_into_in_subq(THD *thd)
{
+ bool is_row_list= args[1]->type() == Item::ROW_ITEM;
uint values_count= arg_count-1;
- if (args[1]->type() == Item::ROW_ITEM)
+ if (is_row_list)
values_count*= ((Item_row *)(args[1]))->cols();
if (thd->variables.in_subquery_conversion_threshold == 0 ||
thd->variables.in_subquery_conversion_threshold > values_count)
return false;
+ if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_PREPARE))
+ return true;
+
+ /* Occurence of '?' in IN list is checked only for PREPARE <stmt> commands */
+ for (uint i=1; i < arg_count; i++)
+ {
+ if (!is_row_list)
+ {
+ if (args[i]->type() == Item::PARAM_ITEM)
+ return false;
+ }
+ else
+ {
+ Item_row *row_list= (Item_row *)(args[i]);
+ for (uint j=0; j < row_list->cols(); j++)
+ {
+ if (row_list->element_index(j)->type() == Item::PARAM_ITEM)
+ return false;
+ }
+ }
+ }
+
return true;
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index e30da347f8b..a1d4ae4a12f 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -2289,6 +2289,11 @@ multi_update::initialize_tables(JOIN *join)
if (unlikely((thd->variables.option_bits & OPTION_SAFE_UPDATES) &&
error_if_full_join(join)))
DBUG_RETURN(1);
+ if (join->implicit_grouping)
+ {
+ my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0));
+ DBUG_RETURN(1);
+ }
main_table=join->join_tab->table;
table_to_update= 0;
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 8571d893a8e..1578915aa3d 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -96,7 +96,8 @@ static void make_unique_view_field_name(THD *thd, Item *target,
itc.rewind();
}
- target->orig_name= target->name.str;
+ if (!target->orig_name)
+ target->orig_name= target->name.str;
target->set_name(thd, buff, name_len, system_charset_info);
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a5493f94ef6..f775e1aaf5a 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2010, 2021, MariaDB
+ Copyright (c) 2010, 2022, MariaDB
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
@@ -2940,9 +2940,29 @@ sp_suid:
;
call:
- CALL_SYM sp_name
+ CALL_SYM ident
{
- if (unlikely(Lex->call_statement_start(thd, $2)))
+ if (unlikely(Lex->call_statement_start(thd, &$2)))
+ MYSQL_YYABORT;
+ }
+ opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
+ | CALL_SYM ident '.' ident
+ {
+ if (unlikely(Lex->call_statement_start(thd, &$2, &$4)))
+ MYSQL_YYABORT;
+ }
+ opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
+ | CALL_SYM ident '.' ident '.' ident
+ {
+ if (unlikely(Lex->call_statement_start(thd, &$2, &$4, &$6)))
MYSQL_YYABORT;
}
opt_sp_cparam_list
@@ -10699,6 +10719,11 @@ function_call_generic:
if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5))))
MYSQL_YYABORT;
}
+ | ident_cli '.' ident_cli '.' ident_cli '(' opt_expr_list ')'
+ {
+ if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, &$5, $7))))
+ MYSQL_YYABORT;
+ }
;
fulltext_options:
@@ -18241,6 +18266,10 @@ sp_statement:
MYSQL_YYABORT;
}
opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
| ident_cli_directly_assignable '.' ident
{
Lex_ident_sys tmp(thd, &$1);
@@ -18249,6 +18278,21 @@ sp_statement:
MYSQL_YYABORT;
}
opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
+ | ident_cli_directly_assignable '.' ident '.' ident
+ {
+ Lex_ident_sys tmp(thd, &$1);
+ if (unlikely(Lex->call_statement_start(thd, &tmp, &$3, &$5)))
+ MYSQL_YYABORT;
+ }
+ opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
;
sp_if_then_statements:
diff --git a/sql/table.cc b/sql/table.cc
index 561b7fb9ff4..a9e75b066f5 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
- Copyright (c) 2008, 2021, MariaDB
+ Copyright (c) 2008, 2022, MariaDB
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
@@ -1741,6 +1741,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
Field_data_type_info_array field_data_type_info_array;
MEM_ROOT *old_root= thd->mem_root;
Virtual_column_info **table_check_constraints;
+ bool *interval_unescaped= NULL;
extra2_fields extra2;
DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
@@ -2181,6 +2182,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
goto err;
+ if (interval_count)
+ {
+ if (!(interval_unescaped= (bool*) my_alloca(interval_count * sizeof(bool))))
+ goto err;
+ bzero(interval_unescaped, interval_count * sizeof(bool));
+ }
+
field_ptr= share->field;
table_check_constraints= share->check_constraints;
read_length=(uint) (share->fields * field_pack_length +
@@ -2532,11 +2540,17 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (share->mysql_version < 100200)
attr.pack_flag&= ~FIELDFLAG_LONG_DECIMAL;
- if (interval_nr && attr.charset->mbminlen > 1)
+ if (interval_nr && attr.charset->mbminlen > 1 &&
+ !interval_unescaped[interval_nr - 1])
{
- /* Unescape UCS2 intervals from HEX notation */
+ /*
+ Unescape UCS2/UTF16/UTF32 intervals from HEX notation.
+ Note, ENUM/SET columns with equal value list share a single
+ copy of TYPELIB. Unescape every TYPELIB only once.
+ */
TYPELIB *interval= share->intervals + interval_nr - 1;
unhex_type2(interval);
+ interval_unescaped[interval_nr - 1]= true;
}
#ifndef TO_BE_DELETED_ON_PRODUCTION
@@ -3256,6 +3270,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
share->error= OPEN_FRM_OK;
thd->status_var.opened_shares++;
thd->mem_root= old_root;
+ my_afree(interval_unescaped);
DBUG_RETURN(0);
err:
@@ -3283,6 +3298,7 @@ err:
open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
thd->mem_root= old_root;
+ my_afree(interval_unescaped);
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
}
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 51c4eeb4a4c..904fda10599 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -953,7 +953,16 @@ static uint get_interval_id(uint *int_count,List<Create_field> &create_fields,
while ((field=it++) != last_field)
{
- if (field->interval_id && field->interval->count == interval->count)
+ /*
+ ENUM/SET columns with equal value lists share a single
+ copy of the underlying TYPELIB.
+ Fields with different mbminlen can't reuse TYPELIBs, because:
+ - mbminlen==1 are written to FRM as is
+ - mbminlen>1 are written to FRM in hex-encoded format
+ */
+ if (field->interval_id &&
+ field->interval->count == interval->count &&
+ field->charset->mbminlen == last_field->charset->mbminlen)
{
const char **a,**b;
for (a=field->interval->type_names, b=interval->type_names ;
diff --git a/sql/wsrep_client_service.cc b/sql/wsrep_client_service.cc
index dc4b1d22818..b7107178717 100644
--- a/sql/wsrep_client_service.cc
+++ b/sql/wsrep_client_service.cc
@@ -342,6 +342,7 @@ int Wsrep_client_service::bf_rollback()
m_thd->global_read_lock.unlock_global_read_lock(m_thd);
}
m_thd->release_transactional_locks();
+ mysql_ull_cleanup(m_thd);
m_thd->mdl_context.release_explicit_locks();
DBUG_RETURN(ret);
diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc
index 1f6537a1351..db6ba43edec 100644
--- a/sql/wsrep_high_priority_service.cc
+++ b/sql/wsrep_high_priority_service.cc
@@ -380,6 +380,7 @@ int Wsrep_high_priority_service::rollback(const wsrep::ws_handle& ws_handle,
}
int ret= (trans_rollback_stmt(m_thd) || trans_rollback(m_thd));
m_thd->release_transactional_locks();
+ mysql_ull_cleanup(m_thd);
m_thd->mdl_context.release_explicit_locks();
free_root(m_thd->mem_root, MYF(MY_KEEP_PREALLOC));
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 7b546f7cab2..4c74d22c325 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1276,6 +1276,73 @@ wsrep_sync_wait_upto (THD* thd,
return ret;
}
+bool wsrep_is_show_query(enum enum_sql_command command)
+{
+ DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
+ return (sql_command_flags[command] & CF_STATUS_COMMAND) != 0;
+}
+
+static bool wsrep_is_diagnostic_query(enum enum_sql_command command)
+{
+ assert(command >= 0 && command <= SQLCOM_END);
+ return (sql_command_flags[command] & CF_DIAGNOSTIC_STMT) != 0;
+}
+
+static enum enum_wsrep_sync_wait
+wsrep_sync_wait_mask_for_command(enum enum_sql_command command)
+{
+ switch (command)
+ {
+ case SQLCOM_SELECT:
+ case SQLCOM_CHECKSUM:
+ return WSREP_SYNC_WAIT_BEFORE_READ;
+ case SQLCOM_DELETE:
+ case SQLCOM_DELETE_MULTI:
+ case SQLCOM_UPDATE:
+ case SQLCOM_UPDATE_MULTI:
+ return WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE;
+ case SQLCOM_REPLACE:
+ case SQLCOM_INSERT:
+ case SQLCOM_REPLACE_SELECT:
+ case SQLCOM_INSERT_SELECT:
+ return WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE;
+ default:
+ if (wsrep_is_diagnostic_query(command))
+ {
+ return WSREP_SYNC_WAIT_NONE;
+ }
+ if (wsrep_is_show_query(command))
+ {
+ switch (command)
+ {
+ case SQLCOM_SHOW_PROFILE:
+ case SQLCOM_SHOW_PROFILES:
+ case SQLCOM_SHOW_SLAVE_HOSTS:
+ case SQLCOM_SHOW_RELAYLOG_EVENTS:
+ case SQLCOM_SHOW_SLAVE_STAT:
+ case SQLCOM_SHOW_BINLOG_STAT:
+ case SQLCOM_SHOW_ENGINE_STATUS:
+ case SQLCOM_SHOW_ENGINE_MUTEX:
+ case SQLCOM_SHOW_ENGINE_LOGS:
+ case SQLCOM_SHOW_PROCESSLIST:
+ case SQLCOM_SHOW_PRIVILEGES:
+ return WSREP_SYNC_WAIT_NONE;
+ default:
+ return WSREP_SYNC_WAIT_BEFORE_SHOW;
+ }
+ }
+ }
+ return WSREP_SYNC_WAIT_NONE;
+}
+
+bool wsrep_sync_wait(THD* thd, enum enum_sql_command command)
+{
+ bool res = false;
+ if (WSREP_CLIENT(thd) && thd->variables.wsrep_sync_wait)
+ res = wsrep_sync_wait(thd, wsrep_sync_wait_mask_for_command(command));
+ return res;
+}
+
void wsrep_keys_free(wsrep_key_arr_t* key_arr)
{
for (size_t i= 0; i < key_arr->keys_len; ++i)
@@ -2421,6 +2488,12 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
if (!wsrep_thd_is_local(thd))
return 0;
+ if (thd->wsrep_parallel_slave_wait_for_prior_commit())
+ {
+ WSREP_WARN("TOI: wait_for_prior_commit() returned error.");
+ return -1;
+ }
+
int ret= 0;
mysql_mutex_lock(&thd->LOCK_thd_data);
@@ -2949,11 +3022,6 @@ extern bool wsrep_thd_ignore_table(THD *thd)
return thd->wsrep_ignore_table;
}
-bool wsrep_is_show_query(enum enum_sql_command command)
-{
- DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
- return (sql_command_flags[command] & CF_STATUS_COMMAND) != 0;
-}
bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
TABLE_LIST* src_table,
HA_CREATE_INFO *create_info)
@@ -3224,6 +3292,15 @@ enum wsrep::streaming_context::fragment_unit wsrep_fragment_unit(ulong unit)
}
}
+bool THD::wsrep_parallel_slave_wait_for_prior_commit()
+{
+ if (rgi_slave && rgi_slave->is_parallel_exec && wait_for_prior_commit())
+ {
+ return 1;
+ }
+ return 0;
+}
+
/***** callbacks for wsrep service ************/
my_bool get_wsrep_recovery()
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 79ec6463ce3..c1f6c9fda7d 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -212,6 +212,7 @@ extern bool wsrep_start_replication(const char *wsrep_cluster_address);
extern void wsrep_shutdown_replication();
extern bool wsrep_must_sync_wait (THD* thd, uint mask= WSREP_SYNC_WAIT_BEFORE_READ);
extern bool wsrep_sync_wait (THD* thd, uint mask= WSREP_SYNC_WAIT_BEFORE_READ);
+extern bool wsrep_sync_wait (THD* thd, enum enum_sql_command command);
extern enum wsrep::provider::status
wsrep_sync_wait_upto (THD* thd, wsrep_gtid_t* upto, int timeout);
extern int wsrep_check_opts();
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 2d6d8bc4165..e08ece56877 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -1,4 +1,4 @@
-/* Copyright 2008-2020 Codership Oy <http://www.codership.com>
+/* Copyright 2008-2022 Codership Oy <http://www.codership.com>
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
@@ -33,6 +33,7 @@
#include <cstdio>
#include <cstdlib>
+#include "debug_sync.h"
#include <my_service_manager.h>
@@ -1508,6 +1509,33 @@ static int run_sql_command(THD *thd, const char *query)
return 0;
}
+static void sst_disallow_writes (THD* thd, bool yes)
+{
+ char query_str[64]= { 0, };
+ ssize_t const query_max= sizeof(query_str) - 1;
+ CHARSET_INFO *current_charset;
+
+ current_charset= thd->variables.character_set_client;
+
+ if (!is_supported_parser_charset(current_charset))
+ {
+ /* Do not use non-supported parser character sets */
+ WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
+ thd->variables.character_set_client= &my_charset_latin1;
+ WSREP_WARN("For SST temporally setting character set to : %s",
+ my_charset_latin1.csname);
+ }
+
+ snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",
+ yes ? 1 : 0);
+
+ if (run_sql_command(thd, query_str))
+ {
+ WSREP_ERROR("Failed to disallow InnoDB writes");
+ }
+ thd->variables.character_set_client= current_charset;
+}
+
static int sst_flush_tables(THD* thd)
{
@@ -1569,6 +1597,11 @@ static int sst_flush_tables(THD* thd)
else
{
WSREP_INFO("Tables flushed.");
+
+ /* disable further disk IO */
+ sst_disallow_writes(thd, true);
+ WSREP_INFO("Disabled further disk IO.");
+
/*
Tables have been flushed. Create a file with cluster state ID and
wsrep_gtid_domain_id.
@@ -1578,6 +1611,9 @@ static int sst_flush_tables(THD* thd)
(long long)wsrep_locked_seqno, wsrep_gtid_server.domain_id);
err= sst_create_file(flush_success, content);
+ if (err)
+ WSREP_INFO("Creating file for flush_success failed %d",err);
+
const char base_name[]= "tables_flushed";
ssize_t const full_len= strlen(mysql_real_data_home) + strlen(base_name)+2;
char *real_name= (char*) malloc(full_len);
@@ -1617,34 +1653,6 @@ static int sst_flush_tables(THD* thd)
return err;
}
-
-static void sst_disallow_writes (THD* thd, bool yes)
-{
- char query_str[64]= { 0, };
- ssize_t const query_max= sizeof(query_str) - 1;
- CHARSET_INFO *current_charset;
-
- current_charset= thd->variables.character_set_client;
-
- if (!is_supported_parser_charset(current_charset))
- {
- /* Do not use non-supported parser character sets */
- WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
- thd->variables.character_set_client= &my_charset_latin1;
- WSREP_WARN("For SST temporally setting character set to : %s",
- my_charset_latin1.csname);
- }
-
- snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",
- yes ? 1 : 0);
-
- if (run_sql_command(thd, query_str))
- {
- WSREP_ERROR("Failed to disallow InnoDB writes");
- }
- thd->variables.character_set_client= current_charset;
-}
-
static void* sst_donor_thread (void* a)
{
sst_thread_arg* arg= (sst_thread_arg*)a;
@@ -1692,8 +1700,7 @@ wait_signal:
err= sst_flush_tables (thd.ptr);
if (!err)
{
- sst_disallow_writes (thd.ptr, true);
- /*
+ /*
Lets also keep statements that modify binary logs (like RESET LOGS,
RESET MASTER) from proceeding until the files have been transferred
to the joiner node.
@@ -1704,6 +1711,18 @@ wait_signal:
}
locked= true;
+
+ WSREP_INFO("Donor state reached");
+
+ DBUG_EXECUTE_IF("sync.wsrep_donor_state",
+ {
+ const char act[]=
+ "now "
+ "SIGNAL sync.wsrep_donor_state_reached "
+ "WAIT_FOR signal.wsrep_donor_state";
+ assert(!debug_sync_set_action(thd.ptr,
+ STRING_WITH_LEN(act)));
+ };);
goto wait_signal;
}
}