From 54ed3939f7fc8008aac72999b6c5fc5dae9c0467 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 22 Dec 2023 23:09:27 -0800 Subject: [PATCH 01/18] MDEV-31657 Crash on query using CTE with the same name as a base table If a query contained a CTE whose name coincided with the name of one of the base tables used in the specification of the CTE and the query had at least two references to this CTE in the specifications of other CTEs then processing of the query led to unlimited recursion that ultimately caused a crash of the server. Any secondary non-recursive reference to a CTE requires creation of a copy of the CTE specification. All the references to CTEs in this copy must be resolved. If the specification contains a reference to a base table whose name coincides with the name of then CTE then it should be ensured that this reference in no way can be resolved against the name of the CTE. --- mysql-test/main/cte_nonrecursive.result | 45 ++++++++++++++++++++++++ mysql-test/main/cte_nonrecursive.test | 46 +++++++++++++++++++++++++ sql/sql_acl.cc | 5 --- sql/sql_cte.cc | 34 ++++++++++++------ sql/sql_cte.h | 6 ++-- sql/sql_lex.h | 6 ++-- sql/sql_view.cc | 3 +- 7 files changed, 124 insertions(+), 21 deletions(-) diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result index e86c101686c..f499b7a5321 100644 --- a/mysql-test/main/cte_nonrecursive.result +++ b/mysql-test/main/cte_nonrecursive.result @@ -2624,4 +2624,49 @@ a 1 1 DROP TABLE t1; +# +# MDEV-31657: CTE with the same name as base table used twice +# in another CTE +# +create table t (a int); +insert into t values (3), (7), (1); +with +t as (select * from t), +cte as (select t1.a as t1a, t2.a as t2a from t as t1, t as t2 where t1.a=t2.a) +select * from cte; +t1a t2a +3 3 +7 7 +1 1 +create table s (a int); +insert into s values (1), (4), (7); +with +t as (select * from t), +s as (select a-1 as a from s), +cte as (select t.a as ta, s.a as sa from t, s where t.a=s.a +union +select t.a+1, s.a+1 from t, s where t.a=s.a+1) +select * from cte; +ta sa +3 3 +2 1 +8 7 +with +t as (select * from t), +cte as (select t.a as ta, s.a as sa from t, s where t.a=s.a +union +select t.a+1, s.a+1 from t, s where t.a=s.a), +s as (select a+10 as a from s) +select * from cte; +ta sa +1 1 +7 7 +2 2 +8 8 +drop table t,s; +with +t as (select * from t), +cte as (select t1.a as t1a, t2.a as t2a from t as t1, t as t2 where t1.a=t2.a) +select * from cte; +ERROR 42S02: Table 'test.t' doesn't exist # End of 10.4 tests diff --git a/mysql-test/main/cte_nonrecursive.test b/mysql-test/main/cte_nonrecursive.test index a666ed3a25f..0d342edf97d 100644 --- a/mysql-test/main/cte_nonrecursive.test +++ b/mysql-test/main/cte_nonrecursive.test @@ -1967,4 +1967,50 @@ SELECT * FROM t1; DROP TABLE t1; +--echo # +--echo # MDEV-31657: CTE with the same name as base table used twice +--echo # in another CTE +--echo # + +create table t (a int); +insert into t values (3), (7), (1); + +let $q1= +with +t as (select * from t), +cte as (select t1.a as t1a, t2.a as t2a from t as t1, t as t2 where t1.a=t2.a) +select * from cte; + +eval $q1; + +create table s (a int); +insert into s values (1), (4), (7); + +let $q2= +with +t as (select * from t), +s as (select a-1 as a from s), +cte as (select t.a as ta, s.a as sa from t, s where t.a=s.a + union + select t.a+1, s.a+1 from t, s where t.a=s.a+1) +select * from cte; + +eval $q2; + +let $q3= +with +t as (select * from t), +cte as (select t.a as ta, s.a as sa from t, s where t.a=s.a + union + select t.a+1, s.a+1 from t, s where t.a=s.a), +s as (select a+10 as a from s) +select * from cte; + +eval $q3; + +drop table t,s; + +--ERROR ER_NO_SUCH_TABLE +eval $q1; + --echo # End of 10.4 tests diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 82f8101e929..6a6a6b3984d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8137,11 +8137,6 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, INSERT_ACL : SELECT_ACL); } - if (tl->with || !tl->db.str || - (tl->select_lex && - (tl->with= tl->select_lex->find_table_def_in_with_clauses(tl)))) - continue; - const ACL_internal_table_access *access= get_cached_table_access(&t_ref->grant.m_internal, t_ref->get_db_name(), diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index 0e422b30216..ce735ba26d1 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -105,6 +105,7 @@ bool LEX::check_dependencies_in_with_clauses() @param tables Points to the beginning of the sub-chain @param tables_last Points to the address with the sub-chain barrier + @param excl_spec Ignore the definition with this spec @details The method resolves tables references to CTE from the chain of @@ -146,7 +147,8 @@ bool LEX::check_dependencies_in_with_clauses() */ bool LEX::resolve_references_to_cte(TABLE_LIST *tables, - TABLE_LIST **tables_last) + TABLE_LIST **tables_last, + st_select_lex_unit *excl_spec) { With_element *with_elem= 0; @@ -155,7 +157,8 @@ bool LEX::resolve_references_to_cte(TABLE_LIST *tables, if (tbl->derived) continue; if (!tbl->db.str && !tbl->with) - tbl->with= tbl->select_lex->find_table_def_in_with_clauses(tbl); + tbl->with= tbl->select_lex->find_table_def_in_with_clauses(tbl, + excl_spec); if (!tbl->with) // no CTE matches table reference tbl { if (only_cte_resolution) @@ -243,7 +246,7 @@ LEX::check_cte_dependencies_and_resolve_references() return true; if (!with_cte_resolution) return false; - if (resolve_references_to_cte(query_tables, query_tables_last)) + if (resolve_references_to_cte(query_tables, query_tables_last, NULL)) return true; return false; } @@ -387,6 +390,7 @@ bool With_element::check_dependencies_in_spec() @param table The reference to the table that is looked for @param barrier The barrier with element for the search + @param excl_spec Ignore the definition with this spec @details The function looks through the elements of this with clause trying to find @@ -400,12 +404,15 @@ bool With_element::check_dependencies_in_spec() */ With_element *With_clause::find_table_def(TABLE_LIST *table, - With_element *barrier) + With_element *barrier, + st_select_lex_unit *excl_spec) { for (With_element *with_elem= with_list.first; with_elem != barrier; with_elem= with_elem->next) { + if (excl_spec && with_elem->spec == excl_spec) + continue; if (my_strcasecmp(system_charset_info, with_elem->get_name_str(), table->table_name.str) == 0 && !table->is_fqtn) @@ -465,7 +472,7 @@ With_element *find_table_def_in_with_clauses(TABLE_LIST *tbl, top_unit->with_element && top_unit->with_element->get_owner() == with_clause) barrier= top_unit->with_element; - found= with_clause->find_table_def(tbl, barrier); + found= with_clause->find_table_def(tbl, barrier, NULL); if (found) break; } @@ -520,10 +527,11 @@ void With_element::check_dependencies_in_select(st_select_lex *sl, { With_clause *with_clause= sl->master_unit()->with_clause; if (with_clause) - tbl->with= with_clause->find_table_def(tbl, NULL); + tbl->with= with_clause->find_table_def(tbl, NULL, NULL); if (!tbl->with) tbl->with= owner->find_table_def(tbl, - owner->with_recursive ? NULL : this); + owner->with_recursive ? NULL : this, + NULL); } if (!tbl->with) tbl->with= find_table_def_in_with_clauses(tbl, ctxt); @@ -1098,7 +1106,8 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex, */ lex->only_cte_resolution= old_lex->only_cte_resolution; if (lex->resolve_references_to_cte(lex->query_tables, - lex->query_tables_last)) + lex->query_tables_last, + spec)) { res= NULL; goto err; @@ -1264,6 +1273,7 @@ bool With_element::is_anchor(st_select_lex *sel) Search for the definition of the given table referred in this select node @param table reference to the table whose definition is searched for + @param excl_spec ignore the definition with this spec @details The method looks for the definition of the table whose reference is occurred @@ -1276,7 +1286,8 @@ bool With_element::is_anchor(st_select_lex *sel) NULL - otherwise */ -With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table) +With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table, + st_select_lex_unit *excl_spec) { With_element *found= NULL; With_clause *containing_with_clause= NULL; @@ -1293,7 +1304,7 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table) With_clause *attached_with_clause= sl->get_with_clause(); if (attached_with_clause && attached_with_clause != containing_with_clause && - (found= attached_with_clause->find_table_def(table, NULL))) + (found= attached_with_clause->find_table_def(table, NULL, excl_spec))) break; master_unit= sl->master_unit(); outer_sl= master_unit->outer_select(); @@ -1303,7 +1314,8 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table) containing_with_clause= with_elem->get_owner(); With_element *barrier= containing_with_clause->with_recursive ? NULL : with_elem; - if ((found= containing_with_clause->find_table_def(table, barrier))) + if ((found= containing_with_clause->find_table_def(table, barrier, + excl_spec))) break; if (outer_sl && !outer_sl->get_with_element()) break; diff --git a/sql/sql_cte.h b/sql/sql_cte.h index 4bc3ed69582..4d56672e3cc 100644 --- a/sql/sql_cte.h +++ b/sql/sql_cte.h @@ -322,7 +322,8 @@ public: friend bool LEX::resolve_references_to_cte(TABLE_LIST *tables, - TABLE_LIST **tables_last); + TABLE_LIST **tables_last, + st_select_lex_unit *excl_spec); }; const uint max_number_of_elements_in_with_clause= sizeof(table_map)*8; @@ -422,7 +423,8 @@ public: void move_anchors_ahead(); - With_element *find_table_def(TABLE_LIST *table, With_element *barrier); + With_element *find_table_def(TABLE_LIST *table, With_element *barrier, + st_select_lex_unit *excl_spec); With_element *find_table_def_in_with_clauses(TABLE_LIST *table); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 0f2e096fdc6..2305616d5b3 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1531,7 +1531,8 @@ public: master_unit()->cloned_from->with_element : master_unit()->with_element; } - With_element *find_table_def_in_with_clauses(TABLE_LIST *table); + With_element *find_table_def_in_with_clauses(TABLE_LIST *table, + st_select_lex_unit * excl_spec); bool check_unrestricted_recursive(bool only_standard_compliant); bool check_subqueries_with_recursive_references(); void collect_grouping_fields_for_derived(THD *thd, ORDER *grouping_list); @@ -4708,7 +4709,8 @@ public: bool check_dependencies_in_with_clauses(); bool check_cte_dependencies_and_resolve_references(); bool resolve_references_to_cte(TABLE_LIST *tables, - TABLE_LIST **tables_last); + TABLE_LIST **tables_last, + st_select_lex_unit *excl_spec); }; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 9f9a9716982..0dca5f7c226 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -295,7 +295,8 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local) { if (!tbl->with && tbl->select_lex) - tbl->with= tbl->select_lex->find_table_def_in_with_clauses(tbl); + tbl->with= tbl->select_lex->find_table_def_in_with_clauses(tbl, + NULL); /* Ensure that we have some privileges on this table, more strict check will be done on column level after preparation, From 613d0194979849fb5b3dd752f13b14672a2409e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 4 Jan 2024 12:50:05 +0200 Subject: [PATCH 02/18] MDEV-33160 show_status_array() calls various functions via incompatible pointer In commit b4ff64568c88ab3ce559e7bd39853d9cbf86704a the signature of mysql_show_var_func was changed, but not all functions of that type were adjusted. When the server is configured with `cmake -DWITH_ASAN=ON` and compiled with clang, runtime errors would be flagged for invoking functions through an incompatible function pointer. Reviewed by: Michael 'Monty' Widenius --- sql/mysqld.cc | 144 +++++++++++++++++------------------- sql/sql_acl.cc | 8 +- sql/table_cache.cc | 4 +- sql/table_cache.h | 4 +- sql/threadpool.h | 3 - storage/sphinx/ha_sphinx.cc | 19 +++-- storage/sphinx/ha_sphinx.h | 6 -- storage/spider/spd_param.cc | 18 +++-- 8 files changed, 102 insertions(+), 104 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a1a8a862a8e..5713045056d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7180,8 +7180,8 @@ struct my_option my_long_options[]= MYSQL_TO_BE_IMPLEMENTED_OPTION("validate-user-plugins") // NO_EMBEDDED_ACCESS_CHECKS }; -static int show_queries(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_queries(THD *thd, SHOW_VAR *var, void *, + system_status_var *, enum_var_type) { var->type= SHOW_LONGLONG; var->value= &thd->query_id; @@ -7189,16 +7189,16 @@ static int show_queries(THD *thd, SHOW_VAR *var, char *buff, } -static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_net_compression(THD *thd, SHOW_VAR *var, void *, + system_status_var *, enum_var_type) { var->type= SHOW_MY_BOOL; var->value= &thd->net.compress; return 0; } -static int show_starttime(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_starttime(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_LONG; var->value= buff; @@ -7207,8 +7207,8 @@ static int show_starttime(THD *thd, SHOW_VAR *var, char *buff, } #ifdef ENABLED_PROFILING -static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_flushstatustime(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_LONG; var->value= buff; @@ -7218,32 +7218,28 @@ static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff, #endif #ifdef HAVE_REPLICATION -static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_rpl_status(THD *, SHOW_VAR *var, void *, system_status_var *, + enum_var_type) { var->type= SHOW_CHAR; var->value= const_cast(rpl_status_type[(int)rpl_status]); return 0; } -static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_slave_running(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { - Master_info *mi= NULL; - bool UNINIT_VAR(tmp); - - var->type= SHOW_MY_BOOL; - var->value= buff; - - if ((mi= get_master_info(&thd->variables.default_master_connection, - Sql_condition::WARN_LEVEL_NOTE))) + if (Master_info *mi= + get_master_info(&thd->variables.default_master_connection, + Sql_condition::WARN_LEVEL_NOTE)) { - tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_READING && - mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN); + *((my_bool*) buff)= + (mi->slave_running == MYSQL_SLAVE_RUN_READING && + mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN); mi->release(); + var->type= SHOW_MY_BOOL; + var->value= buff; } - if (mi) - *((my_bool *)buff)= tmp; else var->type= SHOW_UNDEF; return 0; @@ -7253,7 +7249,8 @@ static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff, /* How many masters this slave is connected to */ -static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff) +static int show_slaves_running(THD *, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_LONGLONG; var->value= buff; @@ -7264,19 +7261,17 @@ static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff) } -static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { - Master_info *mi; - - var->type= SHOW_LONGLONG; - var->value= buff; - - if ((mi= get_master_info(&thd->variables.default_master_connection, - Sql_condition::WARN_LEVEL_NOTE))) + if (Master_info *mi= + get_master_info(&thd->variables.default_master_connection, + Sql_condition::WARN_LEVEL_NOTE)) { *((longlong *)buff)= mi->received_heartbeats; mi->release(); + var->type= SHOW_LONGLONG; + var->value= buff; } else var->type= SHOW_UNDEF; @@ -7284,19 +7279,17 @@ static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff, } -static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_heartbeat_period(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { - Master_info *mi; - - var->type= SHOW_CHAR; - var->value= buff; - - if ((mi= get_master_info(&thd->variables.default_master_connection, - Sql_condition::WARN_LEVEL_NOTE))) + if (Master_info *mi= + get_master_info(&thd->variables.default_master_connection, + Sql_condition::WARN_LEVEL_NOTE)) { - sprintf(buff, "%.3f", mi->heartbeat_period); + sprintf(static_cast(buff), "%.3f", mi->heartbeat_period); mi->release(); + var->type= SHOW_CHAR; + var->value= buff; } else var->type= SHOW_UNDEF; @@ -7306,8 +7299,8 @@ static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff, #endif /* HAVE_REPLICATION */ -static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_open_tables(THD *, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_LONG; var->value= buff; @@ -7315,8 +7308,8 @@ static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff, return 0; } -static int show_prepared_stmt_count(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_prepared_stmt_count(THD *, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_LONG; var->value= buff; @@ -7326,8 +7319,8 @@ static int show_prepared_stmt_count(THD *thd, SHOW_VAR *var, char *buff, return 0; } -static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_table_definitions(THD *, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_LONG; var->value= buff; @@ -7336,8 +7329,8 @@ static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff, } -static int show_flush_commands(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_flush_commands(THD *, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_LONGLONG; var->value= buff; @@ -7356,8 +7349,8 @@ static int show_flush_commands(THD *thd, SHOW_VAR *var, char *buff, inside an Event. */ -static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_ssl_get_version(THD *thd, SHOW_VAR *var, void *, + system_status_var *, enum_var_type) { var->type= SHOW_CHAR; if( thd->vio_ok() && thd->net.vio->ssl_arg ) @@ -7367,8 +7360,8 @@ static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff, return 0; } -static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_LONG; var->value= buff; @@ -7379,8 +7372,8 @@ static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff, return 0; } -static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_LONG; var->value= buff; @@ -7395,8 +7388,8 @@ static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff, return 0; } -static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_LONG; var->value= buff; @@ -7408,8 +7401,8 @@ static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff, return 0; } -static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_CHAR; if( thd->vio_ok() && thd->net.vio->ssl_arg ) @@ -7419,9 +7412,10 @@ static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff, return 0; } -static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, void *buf, + system_status_var *, enum_var_type) { + char *buff= static_cast(buf); var->type= SHOW_CHAR; var->value= buff; if (thd->vio_ok() && thd->net.vio->ssl_arg) @@ -7506,8 +7500,8 @@ end: */ static int -show_ssl_get_server_not_before(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +show_ssl_get_server_not_before(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_CHAR; if(thd->vio_ok() && thd->net.vio->ssl_arg) @@ -7516,7 +7510,7 @@ show_ssl_get_server_not_before(THD *thd, SHOW_VAR *var, char *buff, X509 *cert= SSL_get_certificate(ssl); const ASN1_TIME *not_before= X509_get0_notBefore(cert); - var->value= my_asn1_time_to_string(not_before, buff, + var->value= my_asn1_time_to_string(not_before, static_cast(buff), SHOW_VAR_FUNC_BUFF_SIZE); if (!var->value) return 1; @@ -7540,8 +7534,8 @@ show_ssl_get_server_not_before(THD *thd, SHOW_VAR *var, char *buff, */ static int -show_ssl_get_server_not_after(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +show_ssl_get_server_not_after(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_CHAR; if(thd->vio_ok() && thd->net.vio->ssl_arg) @@ -7550,7 +7544,7 @@ show_ssl_get_server_not_after(THD *thd, SHOW_VAR *var, char *buff, X509 *cert= SSL_get_certificate(ssl); const ASN1_TIME *not_after= X509_get0_notAfter(cert); - var->value= my_asn1_time_to_string(not_after, buff, + var->value= my_asn1_time_to_string(not_after, static_cast(buff), SHOW_VAR_FUNC_BUFF_SIZE); if (!var->value) return 1; @@ -7604,7 +7598,7 @@ static int show_default_keycache(THD *thd, SHOW_VAR *var, void *buff, } -static int show_memory_used(THD *thd, SHOW_VAR *var, char *buff, +static int show_memory_used(THD *thd, SHOW_VAR *var, void *buff, struct system_status_var *status_var, enum enum_var_type scope) { @@ -7660,8 +7654,8 @@ static int debug_status_func(THD *thd, SHOW_VAR *var, void *buff, #endif #ifdef HAVE_POOL_OF_THREADS -int show_threadpool_idle_threads(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +int show_threadpool_idle_threads(THD *, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_INT; var->value= buff; @@ -7670,8 +7664,8 @@ int show_threadpool_idle_threads(THD *thd, SHOW_VAR *var, char *buff, } -static int show_threadpool_threads(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_threadpool_threads(THD *, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_INT; var->value= buff; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 6a6a6b3984d..1949a0c02b6 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -11869,8 +11869,8 @@ static my_bool count_column_grants(void *grant_table, This must be performed under the mutex in order to make sure the iteration does not fail. */ -static int show_column_grants(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_column_grants(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum enum_var_type scope) { var->type= SHOW_ULONG; var->value= buff; @@ -11886,8 +11886,8 @@ static int show_column_grants(THD *thd, SHOW_VAR *var, char *buff, return 0; } -static int show_database_grants(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +static int show_database_grants(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum enum_var_type scope) { var->type= SHOW_UINT; var->value= buff; diff --git a/sql/table_cache.cc b/sql/table_cache.cc index 9b28e7b7b0f..ca7c25ae552 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -1345,8 +1345,8 @@ int tdc_iterate(THD *thd, my_hash_walk_action action, void *argument, } -int show_tc_active_instances(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope) +int show_tc_active_instances(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum enum_var_type scope) { var->type= SHOW_UINT; var->value= buff; diff --git a/sql/table_cache.h b/sql/table_cache.h index 3be7b5fe413..ee738eb8ba6 100644 --- a/sql/table_cache.h +++ b/sql/table_cache.h @@ -97,8 +97,8 @@ extern int tdc_iterate(THD *thd, my_hash_walk_action action, void *argument, bool no_dups= false); extern uint tc_records(void); -int show_tc_active_instances(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope); +int show_tc_active_instances(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum enum_var_type scope); extern void tc_purge(bool mark_flushed= false); extern void tc_add_table(THD *thd, TABLE *table); extern void tc_release_table(TABLE *table); diff --git a/sql/threadpool.h b/sql/threadpool.h index ea6c93b4a65..e4321327163 100644 --- a/sql/threadpool.h +++ b/sql/threadpool.h @@ -64,9 +64,6 @@ extern int tp_get_thread_count(); /* Activate threadpool scheduler */ extern void tp_scheduler(void); -extern int show_threadpool_idle_threads(THD *thd, SHOW_VAR *var, char *buff, - enum enum_var_type scope); - enum TP_PRIORITY { TP_PRIORITY_HIGH, TP_PRIORITY_LOW, diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc index f2bc24c47d4..4549e8dccb6 100644 --- a/storage/sphinx/ha_sphinx.cc +++ b/storage/sphinx/ha_sphinx.cc @@ -3548,7 +3548,8 @@ CSphSEStats * sphinx_get_stats ( THD * thd, SHOW_VAR * out ) return 0; } -int sphinx_showfunc_total ( THD * thd, SHOW_VAR * out, char * ) +static int sphinx_showfunc_total ( THD * thd, SHOW_VAR * out, void *, + system_status_var *, enum_var_type ) { CSphSEStats * pStats = sphinx_get_stats ( thd, out ); if ( pStats ) @@ -3559,7 +3560,8 @@ int sphinx_showfunc_total ( THD * thd, SHOW_VAR * out, char * ) return 0; } -int sphinx_showfunc_total_found ( THD * thd, SHOW_VAR * out, char * ) +static int sphinx_showfunc_total_found ( THD * thd, SHOW_VAR * out, void *, + system_status_var *, enum_var_type ) { CSphSEStats * pStats = sphinx_get_stats ( thd, out ); if ( pStats ) @@ -3570,7 +3572,8 @@ int sphinx_showfunc_total_found ( THD * thd, SHOW_VAR * out, char * ) return 0; } -int sphinx_showfunc_time ( THD * thd, SHOW_VAR * out, char * ) +static int sphinx_showfunc_time ( THD * thd, SHOW_VAR * out, void *, + system_status_var *, enum_var_type ) { CSphSEStats * pStats = sphinx_get_stats ( thd, out ); if ( pStats ) @@ -3581,7 +3584,8 @@ int sphinx_showfunc_time ( THD * thd, SHOW_VAR * out, char * ) return 0; } -int sphinx_showfunc_word_count ( THD * thd, SHOW_VAR * out, char * ) +static int sphinx_showfunc_word_count ( THD * thd, SHOW_VAR * out, void *, + system_status_var *, enum_var_type ) { CSphSEStats * pStats = sphinx_get_stats ( thd, out ); if ( pStats ) @@ -3592,9 +3596,11 @@ int sphinx_showfunc_word_count ( THD * thd, SHOW_VAR * out, char * ) return 0; } -int sphinx_showfunc_words ( THD * thd, SHOW_VAR * out, char * sBuffer ) +static int sphinx_showfunc_words ( THD * thd, SHOW_VAR * out, void * buf, + system_status_var *, enum_var_type ) { #if MYSQL_VERSION_ID>50100 + char *sBuffer = static_cast(buf); if ( sphinx_hton_ptr ) { CSphTLS * pTls = (CSphTLS *) *thd_ha_data ( thd, sphinx_hton_ptr ); @@ -3649,7 +3655,8 @@ int sphinx_showfunc_words ( THD * thd, SHOW_VAR * out, char * sBuffer ) return 0; } -int sphinx_showfunc_error ( THD * thd, SHOW_VAR * out, char * ) +static int sphinx_showfunc_error ( THD * thd, SHOW_VAR * out, void *, + system_status_var *, enum_var_type ) { CSphSEStats * pStats = sphinx_get_stats ( thd, out ); out->type = SHOW_CHAR; diff --git a/storage/sphinx/ha_sphinx.h b/storage/sphinx/ha_sphinx.h index decd88bad5a..ddc1567328f 100644 --- a/storage/sphinx/ha_sphinx.h +++ b/storage/sphinx/ha_sphinx.h @@ -164,12 +164,6 @@ private: bool sphinx_show_status ( THD * thd ); #endif -int sphinx_showfunc_total_found ( THD *, SHOW_VAR *, char * ); -int sphinx_showfunc_total ( THD *, SHOW_VAR *, char * ); -int sphinx_showfunc_time ( THD *, SHOW_VAR *, char * ); -int sphinx_showfunc_word_count ( THD *, SHOW_VAR *, char * ); -int sphinx_showfunc_words ( THD *, SHOW_VAR *, char * ); - // // $Id: ha_sphinx.h 4818 2014-09-24 08:53:38Z tomat $ // diff --git a/storage/spider/spd_param.cc b/storage/spider/spd_param.cc index 5eaf9518048..5c86af68c0a 100644 --- a/storage/spider/spd_param.cc +++ b/storage/spider/spd_param.cc @@ -115,7 +115,8 @@ extern volatile ulonglong spider_mon_table_cache_version_req; } #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS -static int spider_direct_update(THD *thd, SHOW_VAR *var, char *buff) +static int spider_direct_update(THD *thd, SHOW_VAR *var, void *, + system_status_var *, enum_var_type) { int error_num = 0; SPIDER_TRX *trx; @@ -126,7 +127,8 @@ static int spider_direct_update(THD *thd, SHOW_VAR *var, char *buff) DBUG_RETURN(error_num); } -static int spider_direct_delete(THD *thd, SHOW_VAR *var, char *buff) +static int spider_direct_delete(THD *thd, SHOW_VAR *var, void *, + system_status_var *, enum_var_type) { int error_num = 0; SPIDER_TRX *trx; @@ -138,7 +140,8 @@ static int spider_direct_delete(THD *thd, SHOW_VAR *var, char *buff) } #endif -static int spider_direct_order_limit(THD *thd, SHOW_VAR *var, char *buff) +static int spider_direct_order_limit(THD *thd, SHOW_VAR *var, void *, + system_status_var *, enum_var_type) { int error_num = 0; SPIDER_TRX *trx; @@ -149,7 +152,8 @@ static int spider_direct_order_limit(THD *thd, SHOW_VAR *var, char *buff) DBUG_RETURN(error_num); } -static int spider_direct_aggregate(THD *thd, SHOW_VAR *var, char *buff) +static int spider_direct_aggregate(THD *thd, SHOW_VAR *var, void *, + system_status_var *, enum_var_type) { int error_num = 0; SPIDER_TRX *trx; @@ -160,7 +164,8 @@ static int spider_direct_aggregate(THD *thd, SHOW_VAR *var, char *buff) DBUG_RETURN(error_num); } -static int spider_parallel_search(THD *thd, SHOW_VAR *var, char *buff) +static int spider_parallel_search(THD *thd, SHOW_VAR *var, void *, + system_status_var *, enum_var_type) { int error_num = 0; SPIDER_TRX *trx; @@ -172,7 +177,8 @@ static int spider_parallel_search(THD *thd, SHOW_VAR *var, char *buff) } #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) -static int spider_hs_result_free(THD *thd, SHOW_VAR *var, char *buff) +static int spider_hs_result_free(THD *thd, SHOW_VAR *var, void *, + system_status_var *, enum_var_type) { int error_num = 0; SPIDER_TRX *trx; From ac0ce4451958a5c95c9b2ede242586c600836f81 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 3 Jan 2024 12:04:50 +0100 Subject: [PATCH 03/18] ./mtr --skip-not-found should skip combinations too With the result like encryption.innochecksum 'debug' [ skipped ] combination not found instead of *** ERROR: Could not run encryption.innochecksum with 'debug' combination(s) --- mysql-test/lib/mtr_cases.pm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index a4473a07e81..666ac74791e 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -892,6 +892,12 @@ sub collect_one_test_case { } my @no_combs = grep { $test_combs{$_} == 1 } keys %test_combs; if (@no_combs) { + if ($::opt_skip_not_found) { + push @{$tinfo->{combinations}}, @no_combs; + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "combination not found"; + return $tinfo; + } mtr_error("Could not run $name with '".( join(',', sort @no_combs))."' combination(s)"); } From 8172d07785245ad129dfaa9fecca4da206fd3e07 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 3 Jan 2024 18:36:36 +0100 Subject: [PATCH 04/18] MDEV-33090 plugin/auth_pam/testing/pam_mariadb_mtr.c doesn't compile on Solaris Fix by Rainer Orth --- plugin/auth_pam/testing/pam_mariadb_mtr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/auth_pam/testing/pam_mariadb_mtr.c b/plugin/auth_pam/testing/pam_mariadb_mtr.c index d4c79f31330..dc2bc150dc9 100644 --- a/plugin/auth_pam/testing/pam_mariadb_mtr.c +++ b/plugin/auth_pam/testing/pam_mariadb_mtr.c @@ -10,8 +10,8 @@ #include #include -#include #include +#include #define N 3 From f7573e7a837af75768b518936f99c4df634e1b79 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 3 Jan 2024 18:55:16 +0100 Subject: [PATCH 05/18] MDEV-33093 plugin/disks/information_schema_disks.cc doesn't compile on Solaris Fix by Rainer Orth --- plugin/disks/information_schema_disks.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugin/disks/information_schema_disks.cc b/plugin/disks/information_schema_disks.cc index 01c6c0e173f..1be8fce37fa 100644 --- a/plugin/disks/information_schema_disks.cc +++ b/plugin/disks/information_schema_disks.cc @@ -19,10 +19,14 @@ #include #if defined(HAVE_GETMNTENT) #include +#elif defined(HAVE_SYS_MNTENT) +#include #elif !defined(HAVE_GETMNTINFO_TAKES_statvfs) /* getmntinfo (the not NetBSD variants) */ #include +#if defined(HAVE_SYS_UCRED) #include +#endif #include #endif #if defined(HAVE_GETMNTENT_IN_SYS_MNTAB) From ca276a0f3fcb45ff0abc011e334c700e0c5d4315 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 5 Jan 2024 09:35:57 +1100 Subject: [PATCH 06/18] MDEV-33169 Reset sequence used fields after check in alter sequence The bitmap is temporarily flipped to ~0 for the sake of checking all fields. It needs to be restored because it will be reused in second and subsequent ps execution. --- mysql-test/suite/sql_sequence/alter.result | 49 ++++++++++++++++++++++ mysql-test/suite/sql_sequence/alter.test | 35 ++++++++++++++++ sql/sql_sequence.cc | 2 + 3 files changed, 86 insertions(+) diff --git a/mysql-test/suite/sql_sequence/alter.result b/mysql-test/suite/sql_sequence/alter.result index 68d42e52784..d4e930ebb92 100644 --- a/mysql-test/suite/sql_sequence/alter.result +++ b/mysql-test/suite/sql_sequence/alter.result @@ -252,3 +252,52 @@ SELECT NEXTVAL(s); NEXTVAL(s) 1 DROP SEQUENCE s; +# +# MDEV-33169 Alter sequence 2nd ps fails while alter sequence 2nd time (no ps) succeeds +# +create sequence s; +show create sequence s; +Table Create Table +s CREATE SEQUENCE `s` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=MyISAM +alter sequence s maxvalue 123; +show create sequence s; +Table Create Table +s CREATE SEQUENCE `s` start with 1 minvalue 1 maxvalue 123 increment by 1 cache 1000 nocycle ENGINE=MyISAM +alter sequence s maxvalue 123; +show create sequence s; +Table Create Table +s CREATE SEQUENCE `s` start with 1 minvalue 1 maxvalue 123 increment by 1 cache 1000 nocycle ENGINE=MyISAM +drop sequence s; +create sequence s; +show create sequence s; +Table Create Table +s CREATE SEQUENCE `s` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=MyISAM +prepare stmt from 'alter sequence s maxvalue 123'; +execute stmt; +show create sequence s; +Table Create Table +s CREATE SEQUENCE `s` start with 1 minvalue 1 maxvalue 123 increment by 1 cache 1000 nocycle ENGINE=MyISAM +execute stmt; +show create sequence s; +Table Create Table +s CREATE SEQUENCE `s` start with 1 minvalue 1 maxvalue 123 increment by 1 cache 1000 nocycle ENGINE=MyISAM +deallocate prepare stmt; +drop sequence s; +create sequence s; +show create sequence s; +Table Create Table +s CREATE SEQUENCE `s` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=MyISAM +create procedure p() alter sequence s maxvalue 123; +call p; +show create sequence s; +Table Create Table +s CREATE SEQUENCE `s` start with 1 minvalue 1 maxvalue 123 increment by 1 cache 1000 nocycle ENGINE=MyISAM +call p; +show create sequence s; +Table Create Table +s CREATE SEQUENCE `s` start with 1 minvalue 1 maxvalue 123 increment by 1 cache 1000 nocycle ENGINE=MyISAM +drop procedure p; +drop sequence s; +# +# End of 10.4 tests +# diff --git a/mysql-test/suite/sql_sequence/alter.test b/mysql-test/suite/sql_sequence/alter.test index a771c9bba2f..015aba22af6 100644 --- a/mysql-test/suite/sql_sequence/alter.test +++ b/mysql-test/suite/sql_sequence/alter.test @@ -167,3 +167,38 @@ ALTER TABLE s ORDER BY cache_size; SELECT NEXTVAL(s); DROP SEQUENCE s; --enable_ps2_protocol + +--echo # +--echo # MDEV-33169 Alter sequence 2nd ps fails while alter sequence 2nd time (no ps) succeeds +--echo # +create sequence s; +show create sequence s; +alter sequence s maxvalue 123; +show create sequence s; +alter sequence s maxvalue 123; +show create sequence s; +drop sequence s; + +create sequence s; +show create sequence s; +prepare stmt from 'alter sequence s maxvalue 123'; +execute stmt; +show create sequence s; +execute stmt; +show create sequence s; +deallocate prepare stmt; +drop sequence s; + +create sequence s; +show create sequence s; +create procedure p() alter sequence s maxvalue 123; +call p; +show create sequence s; +call p; +show create sequence s; +drop procedure p; +drop sequence s; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc index ab77eabfa28..405b2d5b003 100644 --- a/sql/sql_sequence.cc +++ b/sql/sql_sequence.cc @@ -924,6 +924,7 @@ bool Sql_cmd_alter_sequence::execute(THD *thd) TABLE_LIST *first_table= lex->query_tables; TABLE *table; sequence_definition *new_seq= lex->create_info.seq_create_info; + uint saved_used_fields= new_seq->used_fields; SEQUENCE *seq; No_such_table_error_handler no_such_table_handler; DBUG_ENTER("Sql_cmd_alter_sequence::execute"); @@ -1043,5 +1044,6 @@ bool Sql_cmd_alter_sequence::execute(THD *thd) my_ok(thd); end: + new_seq->used_fields= saved_used_fields; DBUG_RETURN(error); } From 9322ef03e339ee8fcea25231c73c2f63d56c0d49 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 13 Nov 2023 11:18:16 +0400 Subject: [PATCH 07/18] MDEV-32645 CAST(AS UNSIGNED) fails with --view-protocol Item_float::neg() did not preserve the "presentation" from "this". So CAST(-1e0 AS UNSIGNED) -- cast from double to unsigned changes its meaning to: CAST(-1 AS UNSIGNED) -- cast signed to undigned Fixing Item_float::neg() to construct the new value for Item_float::presentation as follows: - if the old value starts with minus, then the minus is truncated: '-2e0' -> '2e0' - otherwise, minus sign followed by its old value: '1e0' -> '-1e0' --- mysql-test/main/cast.test | 3 --- mysql-test/main/type_float.result | 37 +++++++++++++++++++++++++++++++ mysql-test/main/type_float.test | 26 ++++++++++++++++++++++ sql/item.cc | 20 ++++++++++++++++- 4 files changed, 82 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/cast.test b/mysql-test/main/cast.test index ce4b1f6a574..5a0f87beb69 100644 --- a/mysql-test/main/cast.test +++ b/mysql-test/main/cast.test @@ -768,14 +768,11 @@ INSERT INTO t1 VALUES (-1.0); SELECT * FROM t1; DROP TABLE t1; -#enable after MDEV-32645 is fixed ---disable_view_protocol SELECT CAST(-1e0 AS UNSIGNED); CREATE TABLE t1 (a BIGINT UNSIGNED); INSERT INTO t1 VALUES (-1e0); SELECT * FROM t1; DROP TABLE t1; ---enable_view_protocol SELECT CAST(-1e308 AS UNSIGNED); CREATE TABLE t1 (a BIGINT UNSIGNED); diff --git a/mysql-test/main/type_float.result b/mysql-test/main/type_float.result index 500f906642d..fa850cf9b34 100644 --- a/mysql-test/main/type_float.result +++ b/mysql-test/main/type_float.result @@ -1167,5 +1167,42 @@ d 50 fdbl 123.456.789,12345678000000000000000000000000000000 fdec 123.456.789,12345678900000000000000000000000000000 # +# MDEV-32645 CAST(AS UNSIGNED) fails with --view-protocol +# +SELECT +CAST(-1e0 AS UNSIGNED), +CAST(--2e0 AS UNSIGNED), +CAST(---3e0 AS UNSIGNED), +CAST(----4e0 AS UNSIGNED); +CAST(-1e0 AS UNSIGNED) CAST(--2e0 AS UNSIGNED) CAST(---3e0 AS UNSIGNED) CAST(----4e0 AS UNSIGNED) +0 2 0 4 +Warnings: +Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '-3' to UNSIGNED BIGINT. Value truncated +EXPLAIN EXTENDED SELECT +CAST(-1e0 AS UNSIGNED), +CAST(--2e0 AS UNSIGNED), +CAST(---3e0 AS UNSIGNED), +CAST(----4e0 AS UNSIGNED); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select cast(-1e0 as unsigned) AS `CAST(-1e0 AS UNSIGNED)`,cast(2e0 as unsigned) AS `CAST(--2e0 AS UNSIGNED)`,cast(-3e0 as unsigned) AS `CAST(---3e0 AS UNSIGNED)`,cast(4e0 as unsigned) AS `CAST(----4e0 AS UNSIGNED)` +CREATE VIEW v1 AS SELECT +CAST(-1e0 AS UNSIGNED), +CAST(--2e0 AS UNSIGNED), +CAST(---3e0 AS UNSIGNED), +CAST(----4e0 AS UNSIGNED); +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(-1e0 as unsigned) AS `CAST(-1e0 AS UNSIGNED)`,cast(2e0 as unsigned) AS `CAST(--2e0 AS UNSIGNED)`,cast(-3e0 as unsigned) AS `CAST(---3e0 AS UNSIGNED)`,cast(4e0 as unsigned) AS `CAST(----4e0 AS UNSIGNED)` latin1 latin1_swedish_ci +SELECT * FROM v1; +CAST(-1e0 AS UNSIGNED) CAST(--2e0 AS UNSIGNED) CAST(---3e0 AS UNSIGNED) CAST(----4e0 AS UNSIGNED) +0 2 0 4 +Warnings: +Note 1916 Got overflow when converting '-1' to UNSIGNED BIGINT. Value truncated +Note 1916 Got overflow when converting '-3' to UNSIGNED BIGINT. Value truncated +DROP VIEW v1; +# # End of 10.4 tests # diff --git a/mysql-test/main/type_float.test b/mysql-test/main/type_float.test index f1041080e26..f1d74f2f8d7 100644 --- a/mysql-test/main/type_float.test +++ b/mysql-test/main/type_float.test @@ -713,6 +713,32 @@ $$ DELIMITER ;$$ --horizontal_results +--echo # +--echo # MDEV-32645 CAST(AS UNSIGNED) fails with --view-protocol +--echo # + +SELECT + CAST(-1e0 AS UNSIGNED), + CAST(--2e0 AS UNSIGNED), + CAST(---3e0 AS UNSIGNED), + CAST(----4e0 AS UNSIGNED); + +EXPLAIN EXTENDED SELECT + CAST(-1e0 AS UNSIGNED), + CAST(--2e0 AS UNSIGNED), + CAST(---3e0 AS UNSIGNED), + CAST(----4e0 AS UNSIGNED); + +CREATE VIEW v1 AS SELECT + CAST(-1e0 AS UNSIGNED), + CAST(--2e0 AS UNSIGNED), + CAST(---3e0 AS UNSIGNED), + CAST(----4e0 AS UNSIGNED); + +SHOW CREATE VIEW v1; +SELECT * FROM v1; +DROP VIEW v1; + --echo # --echo # End of 10.4 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 21190b38e1a..6d30d63bc11 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6896,7 +6896,25 @@ Item *Item_float::neg(THD *thd) else if (value < 0 && max_length) max_length--; value= -value; - presentation= 0; + if (presentation) + { + if (*presentation == '-') + { + // Strip double minus: -(-1) -> '1' instead of '--1' + presentation++; + } + else + { + size_t presentation_length= strlen(presentation); + if (char *tmp= (char*) thd->alloc(presentation_length + 2)) + { + tmp[0]= '-'; + // Copy with the trailing '\0' + memcpy(tmp + 1, presentation, presentation_length + 1); + presentation= tmp; + } + } + } name= null_clex_str; return this; } From c6e1ffd1a07fc451e7211b0d00edbace78137276 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 31 Dec 2023 23:30:48 +0100 Subject: [PATCH 08/18] MDEV-33148 A connection can control RAND() in following connection initialize THD::rand in THD::init() not in THD::THD(), because the former is also called when a THD is reused - in COM_CHANGE_USER and in taking a THD from the cache. Also use current cycle timer for more unpreditability --- sql/sql_class.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b4893581e1a..179e2a1a9a5 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -684,7 +684,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) wsrep_wfc() #endif /*WITH_WSREP */ { - ulong tmp; bzero(&variables, sizeof(variables)); /* @@ -834,14 +833,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) tablespace_op=FALSE; - /* - Initialize the random generator. We call my_rnd() without a lock as - it's not really critical if two threads modifies the structure at the - same time. We ensure that we have an unique number foreach thread - by adding the address of the stack. - */ - tmp= (ulong) (my_rnd(&sql_rand) * 0xffffffff); - my_rnd_init(&rand, tmp + (ulong)((size_t) &rand), tmp + (ulong) ::global_query_id); substitute_null_with_insert_id = FALSE; lock_info.mysql_thd= (void *)this; @@ -1297,6 +1288,17 @@ void THD::init() /* Set to handle counting of aborted connections */ userstat_running= opt_userstat_running; last_global_update_time= current_connect_time= time(NULL); + + /* + Initialize the random generator. We call my_rnd() without a lock as + it's not really critical if two threads modify the structure at the + same time. We ensure that we have a unique number for each thread + by adding the address of this THD. + */ + ulong tmp= (ulong) (my_rnd(&sql_rand) * 0xffffffff); + my_rnd_init(&rand, tmp + (ulong)(intptr) this, + (ulong)(my_timer_cycles() + global_query_id)); + #if defined(ENABLED_DEBUG_SYNC) /* Initialize the Debug Sync Facility. See debug_sync.cc. */ debug_sync_init_thread(this); From 2310f659f528a189bb9c2a8e70a63e7ee7702780 Mon Sep 17 00:00:00 2001 From: Rainer Orth Date: Wed, 10 Jan 2024 10:11:43 +1100 Subject: [PATCH 09/18] MDEV-8941 Compile on Solaris (SPARC) fails with errors in filamvct.cpp There are a large number of uses of `strerror` in the codebase, the local declaration in `storage/connect/tabvct.cpp` is the only one. Given that none is needed elsewhere, I conclude that this instance can simply be removed. --- storage/connect/tabvct.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp index 9cf5f41d1fe..f5710688d3c 100644 --- a/storage/connect/tabvct.cpp +++ b/storage/connect/tabvct.cpp @@ -71,11 +71,6 @@ #include "tabvct.h" #include "valblk.h" -#if defined(UNIX) -//add dummy strerror (NGC) -char *strerror(int num); -#endif // UNIX - /***********************************************************************/ /* External function. */ /***********************************************************************/ From eabc74aaef472cb415f4ead502559ca1c27efbc8 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Wed, 10 Jan 2024 16:36:39 +1100 Subject: [PATCH 10/18] MDEV-33008 Fix spider table discovery A new column was introduced to the show index output in 10.6 in f691d9865becfd242ba44cc632034433336af1e7 Thus we update the check of the number of columns to be at least 13, rather than exactly 13. Also backport an err number and format from 10.5 for better error messages when the column number is wrong. --- .../spider/bugfix/r/mdev_33008.result | 25 +++++++++++++++++++ .../spider/bugfix/t/mdev_33008.test | 24 ++++++++++++++++++ storage/spider/spd_db_mysql.cc | 9 ++++--- storage/spider/spd_err.h | 2 ++ 4 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_33008.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_33008.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_33008.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_33008.result new file mode 100644 index 00000000000..3bcb4bb038a --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_33008.result @@ -0,0 +1,25 @@ +for master_1 +for child2 +for child3 +set spider_same_server_link=on; +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t2 ( +`id` int(11) NOT NULL AUTO_INCREMENT, +`code` varchar(10) DEFAULT NULL, +PRIMARY KEY (`id`) +); +create table t1 ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` varchar(10) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=SPIDER DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"' +drop table t1, t2; +drop server srv; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33008.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_33008.test new file mode 100644 index 00000000000..48d9a4f01ec --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33008.test @@ -0,0 +1,24 @@ +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +set spider_same_server_link=on; +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t2 ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` varchar(10) DEFAULT NULL, + PRIMARY KEY (`id`) +); +create table t1 ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +show create table t1; +drop table t1, t2; + +drop server srv; +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index e689c9d93f0..d2e9dc1f0ee 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -1566,10 +1566,13 @@ int spider_db_mbase_result::fetch_index_for_discover_table_structure( } DBUG_RETURN(0); } - if (num_fields() != 13) + if (num_fields() < 13) { - DBUG_PRINT("info",("spider num_fields != 13")); - my_printf_error(ER_SPIDER_UNKNOWN_NUM, ER_SPIDER_UNKNOWN_STR, MYF(0)); + DBUG_PRINT("info",("spider num_fields < 13")); + my_printf_error(ER_SPIDER_CANT_NUM, ER_SPIDER_CANT_STR1, MYF(0), + "fetch index for table structure discovery because of " + "wrong number of columns in SHOW INDEX FROM output: ", + num_fields()); DBUG_RETURN(ER_SPIDER_UNKNOWN_NUM); } bool first = TRUE; diff --git a/storage/spider/spd_err.h b/storage/spider/spd_err.h index 9889fcfa7fb..d8f11e18f26 100644 --- a/storage/spider/spd_err.h +++ b/storage/spider/spd_err.h @@ -127,6 +127,8 @@ #define ER_SPIDER_SAME_SERVER_LINK_NUM 12720 #define ER_SPIDER_SAME_SERVER_LINK_STR1 "Host:%s and Socket:%s aim self server. Please change spider_same_server_link parameter if this link is required." #define ER_SPIDER_SAME_SERVER_LINK_STR2 "Host:%s and Port:%ld aim self server. Please change spider_same_server_link parameter if this link is required." +#define ER_SPIDER_CANT_NUM 12721 +#define ER_SPIDER_CANT_STR1 "Can't %s%d" #define ER_SPIDER_COND_SKIP_NUM 12801 #define ER_SPIDER_UNKNOWN_NUM 12500 From bc3d416a17c9d35382f2db6387e51619e80c59da Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Wed, 10 Jan 2024 16:37:36 +1100 Subject: [PATCH 11/18] MDEV-29718 Fix spider detection of same data node server When the host is not specified, it defaults to localhost. --- storage/spider/mysql-test/spider/bugfix/r/mdev_26151.result | 4 ++++ .../mysql-test/spider/bugfix/r/mdev_28739_simple.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_28856.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_28998.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_29163.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_29456.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_29963.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_30014.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_31338.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_31524.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_31996.result | 1 + storage/spider/mysql-test/spider/bugfix/r/mdev_32986.result | 1 + .../spider/bugfix/r/spider_join_with_non_spider.result | 1 + storage/spider/mysql-test/spider/bugfix/r/subquery.result | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_26151.test | 5 +++++ .../spider/mysql-test/spider/bugfix/t/mdev_28739_simple.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_28856.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_28998.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_29163.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_29456.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_29963.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_30014.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_30392.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_31338.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_31524.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_31996.test | 1 + storage/spider/mysql-test/spider/bugfix/t/mdev_32986.test | 1 + .../spider/bugfix/t/spider_join_with_non_spider.test | 1 + storage/spider/mysql-test/spider/bugfix/t/subquery.test | 1 + storage/spider/spd_db_mysql.cc | 4 ++-- 33 files changed, 41 insertions(+), 2 deletions(-) diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_26151.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26151.result index b0a430e0e21..326b84a030e 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_26151.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26151.result @@ -6,6 +6,9 @@ for child2 for child3 set @old_spider_bgs_mode= @@spider_bgs_mode; set session spider_bgs_mode=1; +set spider_same_server_link=1; +set @old_spider_same_server_link=@@global.spider_same_server_link; +set global spider_same_server_link=1; CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table td (a int, PRIMARY KEY (a)); create table ts (a int, PRIMARY KEY (a)) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv_mdev_26151",TABLE "td", casual_read "3"'; @@ -26,6 +29,7 @@ min(a) drop table td, ts; drop server srv_mdev_26151; set session spider_bgs_mode=@old_spider_bgs_mode; +set global spider_same_server_link=@old_spider_same_server_link; for master_1 for child2 for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28739_simple.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28739_simple.result index db232f8a6d3..1c337c3d2dd 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_28739_simple.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28739_simple.result @@ -5,6 +5,7 @@ for master_1 for child2 for child3 set global query_cache_type= on; +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t2 (c int); diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28856.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28856.result index fae3cc6b6ce..7e4fd3cd084 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_28856.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28856.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); # testing monitoring_* diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28998.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28998.result index edac80d9761..e92fb199575 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_28998.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28998.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2); diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29163.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29163.result index af4bef1efa9..f58ab605e11 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_29163.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29163.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t1 (a INT); CREATE TABLE t2 (b INT); diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29456.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29456.result index 4d9095830d1..365c3d6373a 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_29456.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29456.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t1 (c int); diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29963.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29963.result index 17390346a99..604515964f3 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_29963.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29963.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t (a INT) ENGINE=Spider; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_30014.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_30014.result index e1dca495047..ee53009e3f2 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_30014.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30014.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t1 (c int); diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result index 58873d2c6e5..cefa5248d44 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30392.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2); diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_31338.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_31338.result index 62b06336ff6..f156cf38a15 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_31338.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_31338.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t (c BLOB) ENGINE=InnoDB; CREATE TABLE ts (c BLOB) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_31524.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_31524.result index 645fc62862d..b3a4c752565 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_31524.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_31524.result @@ -5,6 +5,7 @@ for master_1 for child2 for child3 SET @old_spider_read_only_mode = @@session.spider_read_only_mode; +set spider_same_server_link=1; CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); set session spider_read_only_mode = default; create table t2 (c int); diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result index 94b76de7df4..5197abd3fb6 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_31645.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t1 ( a bigint(20) NOT NULL, b bigint(20) DEFAULT 0, PRIMARY KEY (a)); CREATE TABLE t2 ( a bigint(20) NOT NULL, b bigint(20) DEFAULT 0, PRIMARY KEY (a)) ENGINE=SPIDER COMMENT='srv "srv", WRAPPER "mysql", TABLE "t1"'; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_31996.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_31996.result index 04d7e884676..cbc91432dbc 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_31996.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_31996.result @@ -1,6 +1,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); set session spider_delete_all_rows_type=0; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_32986.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_32986.result index bdc580d421a..c3bdef9870d 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_32986.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_32986.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t2 (c varchar(16)); diff --git a/storage/spider/mysql-test/spider/bugfix/r/spider_join_with_non_spider.result b/storage/spider/mysql-test/spider/bugfix/r/spider_join_with_non_spider.result index b9c1c5c9de5..420ca657a33 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/spider_join_with_non_spider.result +++ b/storage/spider/mysql-test/spider/bugfix/r/spider_join_with_non_spider.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t1 (c int); create table t2 (d int); diff --git a/storage/spider/mysql-test/spider/bugfix/r/subquery.result b/storage/spider/mysql-test/spider/bugfix/r/subquery.result index c6ea45e2dc0..280f57155bd 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/subquery.result +++ b/storage/spider/mysql-test/spider/bugfix/r/subquery.result @@ -4,6 +4,7 @@ for master_1 for child2 for child3 +set spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t1 (c1 int); create table t2 (c2 int); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26151.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_26151.test index f9e157d33e6..dcf1438fb80 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_26151.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26151.test @@ -14,6 +14,10 @@ --let $srv=srv_mdev_26151 set @old_spider_bgs_mode= @@spider_bgs_mode; set session spider_bgs_mode=1; +set spider_same_server_link=1; +set @old_spider_same_server_link=@@global.spider_same_server_link; +set global spider_same_server_link=1; + evalp CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); # casual_read != 0 && casual_read != 1 @@ -42,6 +46,7 @@ drop table td, ts; eval drop server $srv; set session spider_bgs_mode=@old_spider_bgs_mode; +set global spider_same_server_link=@old_spider_same_server_link; --disable_query_log --disable_result_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28739_simple.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28739_simple.test index 7a011520bb6..feff85df6b3 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_28739_simple.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28739_simple.test @@ -12,6 +12,7 @@ #set @@global.debug_dbug="d:t:i:o,mysqld.trace"; set global query_cache_type= on; +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t2 (c int); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28856.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28856.test index 4f23168ec1b..a1642f7a9cd 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_28856.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28856.test @@ -9,6 +9,7 @@ # This test covers some table params under consideration for inclusion # in the engine-defined options to be implemented in MDEV-28856. +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28998.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28998.test index e1735706341..66e3a15addb 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_28998.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28998.test @@ -12,6 +12,7 @@ if (`select not(count(*)) from information_schema.system_variables where variabl --source ../../t/test_init.inc --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t1 (a INT); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29163.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29163.test index ac116fd0e4f..2e56583d831 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_29163.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29163.test @@ -6,6 +6,7 @@ --source ../../t/test_init.inc --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t1 (a INT); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29456.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29456.test index 16291f82075..89d53227c6c 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_29456.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29456.test @@ -8,6 +8,7 @@ --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29963.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29963.test index ab7a4ded07c..93b38c7963c 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_29963.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29963.test @@ -7,6 +7,7 @@ --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_30014.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_30014.test index 4dc3dafab24..9c59adc80dd 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_30014.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30014.test @@ -7,6 +7,7 @@ --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_30392.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_30392.test index 03417013b07..36e06f3f3c4 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_30392.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30392.test @@ -6,6 +6,7 @@ --source ../../t/test_init.inc --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t1 (a INT); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_31338.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_31338.test index e628c3b921d..a3698c97717 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_31338.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_31338.test @@ -9,6 +9,7 @@ --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t (c BLOB) ENGINE=InnoDB; CREATE TABLE ts (c BLOB) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"'; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_31524.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_31524.test index 64cbf4154aa..a5942fad2b3 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_31524.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_31524.test @@ -10,6 +10,7 @@ --let $srv=srv_mdev_31524 SET @old_spider_read_only_mode = @@session.spider_read_only_mode; +set spider_same_server_link=1; evalp CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); # when the user does not set var nor the table option, the default diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test index bec9dd6c316..4dfe3b57e50 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_31645.test @@ -6,6 +6,7 @@ --source ../../t/test_init.inc --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE TABLE t1 ( a bigint(20) NOT NULL, b bigint(20) DEFAULT 0, PRIMARY KEY (a)); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_31996.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_31996.test index 3e823790c82..93b004a06eb 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_31996.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_31996.test @@ -4,6 +4,7 @@ --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_32986.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_32986.test index 94081d24ad8..144387452f7 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_32986.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_32986.test @@ -6,6 +6,7 @@ --source ../../t/test_init.inc --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); diff --git a/storage/spider/mysql-test/spider/bugfix/t/spider_join_with_non_spider.test b/storage/spider/mysql-test/spider/bugfix/t/spider_join_with_non_spider.test index 7b5d38014ed..294b469a8a5 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/spider_join_with_non_spider.test +++ b/storage/spider/mysql-test/spider/bugfix/t/spider_join_with_non_spider.test @@ -8,6 +8,7 @@ --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t1 (c int); create table t2 (d int); diff --git a/storage/spider/mysql-test/spider/bugfix/t/subquery.test b/storage/spider/mysql-test/spider/bugfix/t/subquery.test index 7a50719603d..70238a524a6 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/subquery.test +++ b/storage/spider/mysql-test/spider/bugfix/t/subquery.test @@ -6,6 +6,7 @@ --source ../../t/test_init.inc --enable_result_log --enable_query_log +set spider_same_server_link=1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t1 (c1 int); create table t2 (c2 int); diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index d2e9dc1f0ee..fe83c652260 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -1985,7 +1985,7 @@ int spider_db_mbase::connect( if (!spider_param_same_server_link(thd)) { - if (!strcmp(tgt_host, my_localhost)) + if (!strcmp(tgt_host, my_localhost) || !tgt_host || !tgt_host[0]) { if (!strcmp(tgt_socket, *spd_mysqld_unix_port)) { @@ -1995,7 +1995,7 @@ int spider_db_mbase::connect( DBUG_RETURN(ER_SPIDER_SAME_SERVER_LINK_NUM); } } else if (!strcmp(tgt_host, "127.0.0.1") || - !strcmp(tgt_host, glob_hostname)) + !strcmp(tgt_host, glob_hostname) || !tgt_host || !tgt_host[0]) { if (tgt_port == (long) *spd_mysqld_port) { From c4ebf87f862ad6ab610e553a94dfa385a94a116c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 13 Dec 2023 21:02:44 +0100 Subject: [PATCH 12/18] MDEV-32984 Update federated table and column privileges mark auto-inc columns for read/write on INSERT, but only for read on UPDATE --- mysql-test/suite/federated/update.result | 36 ++++++++++++++++++++++++ mysql-test/suite/federated/update.test | 32 +++++++++++++++++++++ sql/log_event_server.cc | 2 +- sql/table.cc | 9 +++--- sql/table.h | 2 +- 5 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 mysql-test/suite/federated/update.result create mode 100644 mysql-test/suite/federated/update.test diff --git a/mysql-test/suite/federated/update.result b/mysql-test/suite/federated/update.result new file mode 100644 index 00000000000..1905f80ed71 --- /dev/null +++ b/mysql-test/suite/federated/update.result @@ -0,0 +1,36 @@ +connect master,127.0.0.1,root,,test,$MASTER_MYPORT,; +connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,; +connection master; +CREATE DATABASE federated; +connection slave; +CREATE DATABASE federated; +# +# MDEV-32984 Update federated table and column privileges +# +connection slave; +create database db1; +create user my@localhost identified by '1qaz2wsx'; +create table db1.t1 ( +f1 int auto_increment primary key, +f2 varchar(50), +f3 varchar(50), +unique (f2) +); +grant insert, select (f1, f2, f3), update (f3) on db1.t1 to my@localhost; +connection master; +create table tt1 engine=federated connection='mysql://my:1qaz2wsx@localhost:$SLAVE_MYPORT/db1/t1'; +insert into tt1 (f2,f3) values ('test','123'); +select * from tt1; +f1 f2 f3 +1 test 123 +update tt1 set f3='123456' where f2='test'; +drop table tt1; +connection slave; +drop database db1; +drop user my@localhost; +connection master; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; +connection slave; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; diff --git a/mysql-test/suite/federated/update.test b/mysql-test/suite/federated/update.test new file mode 100644 index 00000000000..5a0414f1e1a --- /dev/null +++ b/mysql-test/suite/federated/update.test @@ -0,0 +1,32 @@ +source include/federated.inc; +source have_federatedx.inc; + +--echo # +--echo # MDEV-32984 Update federated table and column privileges +--echo # +connection slave; +create database db1; +create user my@localhost identified by '1qaz2wsx'; +create table db1.t1 ( + f1 int auto_increment primary key, + f2 varchar(50), + f3 varchar(50), + unique (f2) +); +grant insert, select (f1, f2, f3), update (f3) on db1.t1 to my@localhost; + +connection master; +evalp create table tt1 engine=federated connection='mysql://my:1qaz2wsx@localhost:$SLAVE_MYPORT/db1/t1'; +insert into tt1 (f2,f3) values ('test','123'); +select * from tt1; +update tt1 set f3='123456' where f2='test'; + +drop table tt1; + +connection slave; +drop database db1; +drop user my@localhost; + +source include/federated_cleanup.inc; + + diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index f7a8a1db574..13a981d4381 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -7103,7 +7103,7 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability indexed and it cannot have a DEFAULT value). */ m_table->auto_increment_field_not_null= FALSE; - m_table->mark_auto_increment_column(); + m_table->mark_auto_increment_column(true); } return error; diff --git a/sql/table.cc b/sql/table.cc index 5ed8022da22..a5e33052d3f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -7320,7 +7320,7 @@ inline void TABLE::mark_index_columns_for_read(uint index) always set and sometimes read. */ -void TABLE::mark_auto_increment_column() +void TABLE::mark_auto_increment_column(bool is_insert) { DBUG_ASSERT(found_next_number_field); /* @@ -7328,7 +7328,8 @@ void TABLE::mark_auto_increment_column() store() to check overflow of auto_increment values */ bitmap_set_bit(read_set, found_next_number_field->field_index); - bitmap_set_bit(write_set, found_next_number_field->field_index); + if (is_insert) + bitmap_set_bit(write_set, found_next_number_field->field_index); if (s->next_number_keypart) mark_index_columns_for_read(s->next_number_index); file->column_bitmaps_signal(); @@ -7453,7 +7454,7 @@ void TABLE::mark_columns_needed_for_update() else { if (found_next_number_field) - mark_auto_increment_column(); + mark_auto_increment_column(false); } if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) @@ -7527,7 +7528,7 @@ void TABLE::mark_columns_needed_for_insert() triggers->mark_fields_used(TRG_EVENT_INSERT); } if (found_next_number_field) - mark_auto_increment_column(); + mark_auto_increment_column(true); if (default_field) mark_default_fields_for_write(TRUE); /* Mark virtual columns for insert */ diff --git a/sql/table.h b/sql/table.h index 45095a8d137..9d659bb71ed 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1585,7 +1585,7 @@ public: void mark_index_columns_no_reset(uint index, MY_BITMAP *bitmap); void mark_index_columns_for_read(uint index); void restore_column_maps_after_keyread(MY_BITMAP *backup); - void mark_auto_increment_column(void); + void mark_auto_increment_column(bool insert_fl); void mark_columns_needed_for_update(void); void mark_columns_needed_for_delete(void); void mark_columns_needed_for_insert(void); From 761d5c8987f1770767591ea3bf43f4048ffba8c1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 10 Jan 2024 00:56:19 +0100 Subject: [PATCH 13/18] MDEV-33092 Undefined reference to concurrency on Solaris remove thr_setconcurrency() followup for 8bbcaab160c Fix by Rainer Orth --- cmake/os/WindowsCache.cmake | 1 - config.h.cmake | 1 - configure.cmake | 1 - include/my_pthread.h | 6 ------ libmysqld/lib_sql.cc | 2 -- mysys/thr_alarm.c | 1 - mysys/thr_lock.c | 3 --- mysys/thr_timer.c | 1 - sql/mysqld.cc | 2 -- storage/maria/unittest/ma_pagecache_consist.c | 4 ---- storage/maria/unittest/ma_pagecache_rwconsist.c | 4 ---- storage/maria/unittest/ma_pagecache_rwconsist2.c | 4 ---- storage/maria/unittest/ma_pagecache_single.c | 4 ---- storage/maria/unittest/ma_test_loghandler_multithread-t.c | 4 ---- 14 files changed, 38 deletions(-) diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake index 4a3b3383393..628b1728747 100644 --- a/cmake/os/WindowsCache.cmake +++ b/cmake/os/WindowsCache.cmake @@ -243,7 +243,6 @@ SET(HAVE_TERMCAP_H CACHE INTERNAL "") SET(HAVE_TERMIOS_H CACHE INTERNAL "") SET(HAVE_TERMIO_H CACHE INTERNAL "") SET(HAVE_TERM_H CACHE INTERNAL "") -SET(HAVE_THR_SETCONCURRENCY CACHE INTERNAL "") SET(HAVE_THR_YIELD CACHE INTERNAL "") SET(HAVE_TIME 1 CACHE INTERNAL "") SET(HAVE_TIMES CACHE INTERNAL "") diff --git a/config.h.cmake b/config.h.cmake index a8154bb18d1..652b95a1ed2 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -231,7 +231,6 @@ #cmakedefine HAVE_STRTOUL 1 #cmakedefine HAVE_STRTOULL 1 #cmakedefine HAVE_TELL 1 -#cmakedefine HAVE_THR_SETCONCURRENCY 1 #cmakedefine HAVE_THR_YIELD 1 #cmakedefine HAVE_TIME 1 #cmakedefine HAVE_TIMES 1 diff --git a/configure.cmake b/configure.cmake index c7266cdef81..fcfce85edb9 100644 --- a/configure.cmake +++ b/configure.cmake @@ -417,7 +417,6 @@ CHECK_FUNCTION_EXISTS (strtoul HAVE_STRTOUL) CHECK_FUNCTION_EXISTS (strtoull HAVE_STRTOULL) CHECK_FUNCTION_EXISTS (strcasecmp HAVE_STRCASECMP) CHECK_FUNCTION_EXISTS (tell HAVE_TELL) -CHECK_FUNCTION_EXISTS (thr_setconcurrency HAVE_THR_SETCONCURRENCY) CHECK_FUNCTION_EXISTS (thr_yield HAVE_THR_YIELD) CHECK_FUNCTION_EXISTS (vasprintf HAVE_VASPRINTF) CHECK_FUNCTION_EXISTS (vsnprintf HAVE_VSNPRINTF) diff --git a/include/my_pthread.h b/include/my_pthread.h index a95e6f77b13..10cc2301ea6 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -148,9 +148,6 @@ int pthread_cancel(pthread_t thread); #ifndef _REENTRANT #define _REENTRANT #endif -#ifdef HAVE_THR_SETCONCURRENCY -#include /* Probably solaris */ -#endif #ifdef HAVE_SCHED_H #include #endif @@ -619,9 +616,6 @@ extern int my_rw_trywrlock(my_rw_lock_t *); #define GETHOSTBYADDR_BUFF_SIZE 2048 -#ifndef HAVE_THR_SETCONCURRENCY -#define thr_setconcurrency(A) pthread_dummy(0) -#endif #if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize) #define pthread_attr_setstacksize(A,B) pthread_dummy(0) #endif diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 8f772ac8122..41eee607d23 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -635,8 +635,6 @@ int init_embedded_server(int argc, char **argv, char **groups) udf_init(); #endif - (void) thr_setconcurrency(concurrency); // 10 by default - if (flush_time && flush_time != ~(ulong) 0L) start_handle_manager(); diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 90429f72823..d2b542ee9b6 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -786,7 +786,6 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) mysql_mutex_unlock(&LOCK_thread_count); DBUG_PRINT("info",("signal thread created")); - thr_setconcurrency(3); pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); printf("Main thread: %s\n",my_thread_name()); for (i=0 ; i < 2 ; i++) diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 168ec035e79..c9bc3a2d9fb 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -1783,9 +1783,6 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) error,errno); exit(1); } -#endif -#ifdef HAVE_THR_SETCONCURRENCY - (void) thr_setconcurrency(2); #endif for (i=0 ; i < array_elements(lock_counts) ; i++) { diff --git a/mysys/thr_timer.c b/mysys/thr_timer.c index f87c1f75555..d3627fea983 100644 --- a/mysys/thr_timer.c +++ b/mysys/thr_timer.c @@ -533,7 +533,6 @@ static void run_test() mysql_mutex_init(0, &LOCK_thread_count, MY_MUTEX_INIT_FAST); mysql_cond_init(0, &COND_thread_count, NULL); - thr_setconcurrency(3); pthread_attr_init(&thr_attr); pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); printf("Main thread: %s\n",my_thread_name()); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b698928c5f7..05545a1f4fb 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5490,8 +5490,6 @@ int mysqld_main(int argc, char **argv) SYSVAR_AUTOSIZE(my_thread_stack_size, new_thread_stack_size); } - (void) thr_setconcurrency(concurrency); // 10 by default - select_thread=pthread_self(); select_thread_in_use=1; diff --git a/storage/maria/unittest/ma_pagecache_consist.c b/storage/maria/unittest/ma_pagecache_consist.c index 29fa29ca035..4a9056e66c2 100644 --- a/storage/maria/unittest/ma_pagecache_consist.c +++ b/storage/maria/unittest/ma_pagecache_consist.c @@ -403,10 +403,6 @@ int main(int argc __attribute__((unused)), exit(1); } -#ifdef HAVE_THR_SETCONCURRENCY - thr_setconcurrency(2); -#endif - if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, TEST_PAGE_SIZE, 0, 0)) == 0) { diff --git a/storage/maria/unittest/ma_pagecache_rwconsist.c b/storage/maria/unittest/ma_pagecache_rwconsist.c index a3303eb65a4..c4a2148175d 100644 --- a/storage/maria/unittest/ma_pagecache_rwconsist.c +++ b/storage/maria/unittest/ma_pagecache_rwconsist.c @@ -272,10 +272,6 @@ int main(int argc __attribute__((unused)), exit(1); } -#ifdef HAVE_THR_SETCONCURRENCY - thr_setconcurrency(2); -#endif - if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, TEST_PAGE_SIZE, 0, 0)) == 0) { diff --git a/storage/maria/unittest/ma_pagecache_rwconsist2.c b/storage/maria/unittest/ma_pagecache_rwconsist2.c index 2a0f76b478f..e1a80ac495b 100644 --- a/storage/maria/unittest/ma_pagecache_rwconsist2.c +++ b/storage/maria/unittest/ma_pagecache_rwconsist2.c @@ -268,10 +268,6 @@ int main(int argc __attribute__((unused)), exit(1); } -#ifdef HAVE_THR_SETCONCURRENCY - thr_setconcurrency(2); -#endif - if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, TEST_PAGE_SIZE, 0, 0)) == 0) { diff --git a/storage/maria/unittest/ma_pagecache_single.c b/storage/maria/unittest/ma_pagecache_single.c index b0a259c85a4..a8aecc10a42 100644 --- a/storage/maria/unittest/ma_pagecache_single.c +++ b/storage/maria/unittest/ma_pagecache_single.c @@ -795,10 +795,6 @@ int main(int argc __attribute__((unused)), exit(1); } -#ifdef HAVE_THR_SETCONCURRENCY - thr_setconcurrency(2); -#endif - if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, TEST_PAGE_SIZE, 0, MYF(MY_WME))) == 0) { diff --git a/storage/maria/unittest/ma_test_loghandler_multithread-t.c b/storage/maria/unittest/ma_test_loghandler_multithread-t.c index cb4d2bc70ba..e07f8d56e32 100644 --- a/storage/maria/unittest/ma_test_loghandler_multithread-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multithread-t.c @@ -331,10 +331,6 @@ int main(int argc __attribute__((unused)), exit(1); } -#ifdef HAVE_THR_SETCONCURRENCY - thr_setconcurrency(2); -#endif - if (ma_control_file_open(TRUE, TRUE, TRUE)) { fprintf(stderr, "Can't init control file (%d)\n", errno); From 7801c6d22dce546e9661be909dd0302000933f0b Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 15 Dec 2023 17:37:28 +1100 Subject: [PATCH 14/18] MDEV-29002 Spider: remove SPIDER_CONN::loop_check_meraged_last The field is assigned but unused, and it causes heap-use-after-free. --- .../spider/bugfix/r/mdev_29002.result | 34 +++++++++++++++++++ .../spider/bugfix/t/mdev_29002.test | 32 +++++++++++++++++ storage/spider/spd_conn.cc | 6 ---- storage/spider/spd_include.h | 1 - 4 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_29002.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_29002.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29002.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29002.result new file mode 100644 index 00000000000..894f51c5e36 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29002.result @@ -0,0 +1,34 @@ +for master_1 +for child2 +for child3 +SET spider_same_server_link= on; +CREATE SERVER s FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE t (a INT); +CREATE TABLE t1_spider (a INT) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 's', table 't'"; +CREATE TABLE t2_spider (a INT) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 's', table 't'"; +SELECT * FROM t1_spider, t2_spider; +a a +SELECT table_name, index_name, cardinality FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name IN ('t1_spider','t2_spider'); +table_name index_name cardinality +RENAME TABLE t1_spider TO t3_spider; +SELECT * FROM t3_spider; +a +DROP TABLE t3_spider, t2_spider, t; +drop server s; +CREATE TABLE t1 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",HOST "srv",TABLE "t"'; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",HOST "srv",TABLE "t"'; +CREATE TABLE t3 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",HOST "srv",TABLE "t"'; +SHOW TABLE STATUS; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary +t1 SPIDER 10 NULL 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL Unable to connect to foreign data source: srv 0 +t2 SPIDER 10 NULL 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL Unable to connect to foreign data source: srv 0 +t3 SPIDER 10 NULL 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL Unable to connect to foreign data source: srv 0 +Warnings: +Warning 1429 Unable to connect to foreign data source: srv +Warning 1429 Unable to connect to foreign data source: srv +Warning 1429 Unable to connect to foreign data source: srv +drop table t1, t2, t3; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29002.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29002.test new file mode 100644 index 00000000000..51620a5a23c --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29002.test @@ -0,0 +1,32 @@ +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +SET spider_same_server_link= on; +evalp CREATE SERVER s FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); + +CREATE TABLE t (a INT); +CREATE TABLE t1_spider (a INT) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 's', table 't'"; +CREATE TABLE t2_spider (a INT) ENGINE=SPIDER COMMENT = "wrapper 'mysql', srv 's', table 't'"; +SELECT * FROM t1_spider, t2_spider; +SELECT table_name, index_name, cardinality FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name IN ('t1_spider','t2_spider'); +RENAME TABLE t1_spider TO t3_spider; +SELECT * FROM t3_spider; + +DROP TABLE t3_spider, t2_spider, t; +drop server s; + +# case by roel +CREATE TABLE t1 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",HOST "srv",TABLE "t"'; +CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",HOST "srv",TABLE "t"'; +CREATE TABLE t3 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",HOST "srv",TABLE "t"'; +SHOW TABLE STATUS; +drop table t1, t2, t3; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index 5ca3bb06fec..9897e495c83 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -1783,13 +1783,7 @@ int spider_conn_queue_and_merge_loop_check( lcptr->flag = SPIDER_LOP_CHK_MERAGED; lcptr->next = NULL; if (!conn->loop_check_meraged_first) - { conn->loop_check_meraged_first = lcptr; - conn->loop_check_meraged_last = lcptr; - } else { - conn->loop_check_meraged_last->next = lcptr; - conn->loop_check_meraged_last = lcptr; - } } DBUG_RETURN(0); diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index 59c3a181780..8bf44d094b2 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -940,7 +940,6 @@ typedef struct st_spider_conn SPIDER_CONN_LOOP_CHECK *loop_check_ignored_first; SPIDER_CONN_LOOP_CHECK *loop_check_ignored_last; SPIDER_CONN_LOOP_CHECK *loop_check_meraged_first; - SPIDER_CONN_LOOP_CHECK *loop_check_meraged_last; } SPIDER_CONN; typedef struct st_spider_lgtm_tblhnd_share From 9e9e0b99ade0e6ccd34abc3bc3abaf7bbd5ecf4e Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Tue, 19 Dec 2023 12:18:13 +1100 Subject: [PATCH 15/18] MDEV-30170 ha_spider::delete_table() should report table not exist All Spider tables are recorded in the system table mysql.spider_tables. Deleting a spider table removes the corresponding rows from the system table, among other things. This patch makes it so that if spider could not find any record in the system table to delete for a given table, it should correctly report that no such Spider table exists. --- storage/spider/ha_spider.cc | 9 +++++++- .../spider/bugfix/r/mdev_30170.result | 7 ++++++ .../spider/bugfix/t/mdev_30170.test | 8 +++++++ storage/spider/spd_sys_table.cc | 22 ++++++++++++++++++- 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_30170.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_30170.test diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 08d3fc40f05..5011f86c044 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -11371,7 +11371,10 @@ int ha_spider::create( if ( thd->lex->create_info.or_replace() && (error_num = spider_delete_tables( - table_tables, tmp_share.table_name, &dummy)) + table_tables, tmp_share.table_name, &dummy)) && + /* In this context, no key found in mysql.spider_tables means + the Spider table does not exist */ + error_num != HA_ERR_KEY_NOT_FOUND ) { goto error; } @@ -11842,6 +11845,10 @@ int ha_spider::delete_table( (error_num = spider_delete_tables( table_tables, name, &old_link_count)) ) { + /* In this context, no key found in mysql.spider_tables means + the Spider table does not exist */ + if (error_num == HA_ERR_KEY_NOT_FOUND) + error_num= HA_ERR_NO_SUCH_TABLE; goto error; } spider_close_sys_table(current_thd, table_tables, diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_30170.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_30170.result new file mode 100644 index 00000000000..2183447bfa3 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30170.result @@ -0,0 +1,7 @@ +install soname 'ha_spider'; +DROP TABLE non_existing_table; +ERROR 42S02: Unknown table 'test.non_existing_table' +create or replace table non_existing_table (c int) engine=Spider; +drop table non_existing_table; +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_30170.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_30170.test new file mode 100644 index 00000000000..690268432d3 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30170.test @@ -0,0 +1,8 @@ +install soname 'ha_spider'; +--error ER_BAD_TABLE_ERROR +DROP TABLE non_existing_table; +# Test that create or replace a non existing spider table work +create or replace table non_existing_table (c int) engine=Spider; +drop table non_existing_table; +--disable_query_log +--source ../../include/clean_up_spider.inc diff --git a/storage/spider/spd_sys_table.cc b/storage/spider/spd_sys_table.cc index b3a45b73af7..a8549d5467d 100644 --- a/storage/spider/spd_sys_table.cc +++ b/storage/spider/spd_sys_table.cc @@ -1865,6 +1865,16 @@ int spider_delete_xa_member( DBUG_RETURN(0); } +/** + Delete a Spider table from mysql.spider_tables. + + @param table The table mysql.spider_tables + @param name The name of the Spider table to delete + @param old_link_count The number of links in the deleted table + + @retval 0 Success + @retval nonzero Failure +*/ int spider_delete_tables( TABLE *table, const char *name, @@ -1880,10 +1890,20 @@ int spider_delete_tables( { spider_store_tables_link_idx(table, roop_count); if ((error_num = spider_check_sys_table(table, table_key))) - break; + { + /* There's a problem with finding the first record for the + spider table, likely because it does not exist. Fail */ + if (roop_count == 0) + DBUG_RETURN(error_num); + /* At least one row has been deleted for the Spider table. + Success */ + else + break; + } else { if ((error_num = spider_delete_sys_table_row(table))) { + /* There's a problem deleting the row. Fail */ DBUG_RETURN(error_num); } } From 931df937e9382248ab082e4b3abd8ed149d48cd4 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Tue, 16 Jan 2024 17:17:50 +1100 Subject: [PATCH 16/18] MDEV-32559 failing spider signal_ddl_recovery_done callback should result in spider deinit Since 0930eb86cb00edb2ae285c3250ca51bae126e5e5, system table creation needed for spider init is delayed to the signal_ddl_recovery_done callback. Since it is part of the init, failure should result in spider deinit. We also remove the call to spider_init_system_tables() from spider_db_init(), as it was removed in the commit mentioned above and accidentally restored in a merge. --- include/mysql/plugin.h | 16 ++++++++++++++-- sql/handler.cc | 3 ++- sql/handler.h | 2 +- sql/mysqld.cc | 8 ++++++++ storage/innobase/handler/ha_innodb.cc | 3 ++- .../spider/bugfix/r/signal_ddl_fail.result | 8 ++++++++ .../spider/bugfix/t/signal_ddl_fail.opt | 2 ++ .../spider/bugfix/t/signal_ddl_fail.test | 10 ++++++++++ storage/spider/spd_table.cc | 19 +++---------------- 9 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/signal_ddl_fail.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/signal_ddl_fail.opt create mode 100644 storage/spider/mysql-test/spider/bugfix/t/signal_ddl_fail.test diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 89ecf2b34c1..8a7a5e14223 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -531,7 +531,13 @@ struct st_mysql_plugin const char *author; /* plugin author (for I_S.PLUGINS) */ const char *descr; /* general descriptive text (for I_S.PLUGINS) */ int license; /* the plugin license (PLUGIN_LICENSE_XXX) */ - int (*init)(void *); /* the function to invoke when plugin is loaded */ + /* + The function to invoke when plugin is loaded. Plugin + initialisation done here should defer any ALTER TABLE queries to + after the ddl recovery is done, in the signal_ddl_recovery_done() + callback called by ha_signal_ddl_recovery_done(). + */ + int (*init)(void *); int (*deinit)(void *);/* the function to invoke when plugin is unloaded */ unsigned int version; /* plugin version (for I_S.PLUGINS) */ struct st_mysql_show_var *status_vars; @@ -555,7 +561,13 @@ struct st_maria_plugin const char *author; /* plugin author (for SHOW PLUGINS) */ const char *descr; /* general descriptive text (for SHOW PLUGINS ) */ int license; /* the plugin license (PLUGIN_LICENSE_XXX) */ - int (*init)(void *); /* the function to invoke when plugin is loaded */ + /* + The function to invoke when plugin is loaded. Plugin + initialisation done here should defer any ALTER TABLE queries to + after the ddl recovery is done, in the signal_ddl_recovery_done() + callback called by ha_signal_ddl_recovery_done(). + */ + int (*init)(void *); int (*deinit)(void *);/* the function to invoke when plugin is unloaded */ unsigned int version; /* plugin version (for SHOW PLUGINS) */ struct st_mysql_show_var *status_vars; diff --git a/sql/handler.cc b/sql/handler.cc index 58a2eb3e43a..86fc697ec0c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -968,7 +968,8 @@ static my_bool signal_ddl_recovery_done(THD *, plugin_ref plugin, void *) { handlerton *hton= plugin_hton(plugin); if (hton->signal_ddl_recovery_done) - (hton->signal_ddl_recovery_done)(hton); + if ((hton->signal_ddl_recovery_done)(hton)) + plugin_ref_to_int(plugin)->state= PLUGIN_IS_DELETED; return 0; } diff --git a/sql/handler.h b/sql/handler.h index 0296d30213f..2d01979ab48 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1565,7 +1565,7 @@ struct handlerton const LEX_CUSTRING *version, ulonglong create_id); /* Called for all storage handlers after ddl recovery is done */ - void (*signal_ddl_recovery_done)(handlerton *hton); + int (*signal_ddl_recovery_done)(handlerton *hton); /* Optional clauses in the CREATE/ALTER TABLE diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 952802541b9..8b7888dfb79 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5118,6 +5118,14 @@ static int init_server_components() tc_log= 0; // ha_initialize_handlerton() needs that + /* + Plugins may not be completed because system table DDLs are only + run after the ddl recovery done. Therefore between the + plugin_init() call and the ha_signal_ddl_recovery_done() call + below only things related to preparation for recovery should be + done and nothing else, and definitely not anything assuming that + all plugins have been initialised. + */ if (plugin_init(&remaining_argc, remaining_argv, (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) | (opt_abort ? PLUGIN_INIT_SKIP_INITIALIZATION : 0))) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index e3b18599c99..af556d65695 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2155,7 +2155,7 @@ all_fail: ut_d(purge_sys.resume_FTS()); } -static void innodb_ddl_recovery_done(handlerton*) +static int innodb_ddl_recovery_done(handlerton*) { ut_ad(!ddl_recovery_done); ut_d(ddl_recovery_done= true); @@ -2166,6 +2166,7 @@ static void innodb_ddl_recovery_done(handlerton*) drop_garbage_tables_after_restore(); srv_init_purge_tasks(); } + return 0; } /********************************************************************//** diff --git a/storage/spider/mysql-test/spider/bugfix/r/signal_ddl_fail.result b/storage/spider/mysql-test/spider/bugfix/r/signal_ddl_fail.result new file mode 100644 index 00000000000..c86e600b2c1 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/signal_ddl_fail.result @@ -0,0 +1,8 @@ +# +# MDEV-32559 Move alter table statements in spider init queries to be executed in the signal_ddl_recovery_done callback +# +select * from mysql.plugin; +name dl +# +# end of test signal_ddl_fail +# diff --git a/storage/spider/mysql-test/spider/bugfix/t/signal_ddl_fail.opt b/storage/spider/mysql-test/spider/bugfix/t/signal_ddl_fail.opt new file mode 100644 index 00000000000..d883df7bed2 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/signal_ddl_fail.opt @@ -0,0 +1,2 @@ +--plugin-load-add=ha_spider +--debug-dbug=d,fail_spider_ddl_recovery_done diff --git a/storage/spider/mysql-test/spider/bugfix/t/signal_ddl_fail.test b/storage/spider/mysql-test/spider/bugfix/t/signal_ddl_fail.test new file mode 100644 index 00000000000..f13eae3a062 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/signal_ddl_fail.test @@ -0,0 +1,10 @@ +--source include/have_debug.inc +--echo # +--echo # MDEV-32559 Move alter table statements in spider init queries to be executed in the signal_ddl_recovery_done callback +--echo # +# This test tests that failure in ddl_recovery callback causes the +# plugin to be deinitialized. +select * from mysql.plugin; +--echo # +--echo # end of test signal_ddl_fail +--echo # diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index 65a00f5da34..5dc489daca3 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -7127,9 +7127,10 @@ bool spider_init_system_tables() Spider is typically loaded before ddl_recovery, but DDL statements cannot be executed before ddl_recovery, so we delay system table creation. */ -static void spider_after_ddl_recovery(handlerton *) +static int spider_after_ddl_recovery(handlerton *) { - spider_init_system_tables(); + DBUG_EXECUTE_IF("fail_spider_ddl_recovery_done", return 1;); + return spider_init_system_tables(); } int spider_db_init( @@ -7151,16 +7152,6 @@ int spider_db_init( #ifdef HTON_CAN_READ_CONNECT_STRING_IN_PARTITION spider_hton->flags |= HTON_CAN_READ_CONNECT_STRING_IN_PARTITION; #endif - /* spider_hton->db_type = DB_TYPE_SPIDER; */ - /* - spider_hton->savepoint_offset; - spider_hton->savepoint_set = spider_savepoint_set; - spider_hton->savepoint_rollback = spider_savepoint_rollback; - spider_hton->savepoint_release = spider_savepoint_release; - spider_hton->create_cursor_read_view = spider_create_cursor_read_view; - spider_hton->set_cursor_read_view = spider_set_cursor_read_view; - spider_hton->close_cursor_read_view = spider_close_cursor_read_view; - */ spider_hton->panic = spider_panic; spider_hton->signal_ddl_recovery_done= spider_after_ddl_recovery; spider_hton->close_connection = spider_close_connection; @@ -7233,10 +7224,6 @@ int spider_db_init( #ifndef WITHOUT_SPIDER_BG_SEARCH if (pthread_attr_init(&spider_pt_attr)) goto error_pt_attr_init; -/* - if (pthread_attr_setdetachstate(&spider_pt_attr, PTHREAD_CREATE_DETACHED)) - goto error_pt_attr_setstate; -*/ #endif #if MYSQL_VERSION_ID < 50500 From f8c88d905b44bffe161158309e9acc25ad3691aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 17 Jan 2024 11:14:24 +0200 Subject: [PATCH 17/18] MDEV-33213 History list is not shrunk unless there is a pause in the workload The parameter innodb_undo_log_truncate=ON enables a multi-phased logic: 1. Any "producers" (new starting transactions) are prohibited from using the rollback segments that reside in the undo tablespace. 2. Any transactions that use any of the rollback segments must be committed or aborted. 3. The purge of committed transaction history must process all the rollback segments. 4. The undo tablespace is truncated and rebuilt. 5. The rollback segments are re-enabled for new transactions. There was one flaw in this logic: The first step was not being invoked as often as it could be, and therefore innodb_undo_log_truncate=ON would have no chance to work during a heavy write workload. Independent of innodb_undo_log_truncate, even after commit 86767bcc0f121db3ad83a74647a642754a0ce57f we are missing some chances to free processed undo log pages. If we prohibited the creation of new transactions in one busy rollback segment at a time, we would be eventually guaranteed to be able to free such pages. purge_sys_t::skipped_rseg: The current candidate rollback segment for shrinking the history independent of innodb_undo_log_truncate. purge_sys_t::iterator::free_history_rseg(): Renamed from trx_purge_truncate_rseg_history(). Implement the logic around purge_sys.m_skipped_rseg. purge_sys_t::truncate_undo_space: Renamed from truncate. purge_sys.truncate_undo_space.last: Changed the type to integer to get rid of some pointer dereferencing and conditional branches. purge_sys_t::truncating_tablespace(), purge_sys_t::undo_truncate_try(): Refactored from trx_purge_truncate_history(). Set purge_sys.truncate_undo_space.current if applicable, or return an already set purge_sys.truncate_undo_space.current. purge_coordinator_state::do_purge(): Invoke purge_sys_t::truncating_tablespace() as part of the normal work loop, to implement innodb_undo_log_truncate=ON as often as possible. trx_purge_truncate_rseg_history(): Remove a redundant parameter. trx_undo_truncate_start(): Replace dead code with a debug assertion. Correctness tested by: Matthias Leich Performance tested by: Axel Schwenke Reviewed by: Debarun Banerjee --- storage/innobase/include/trx0purge.h | 51 +++++- storage/innobase/include/trx0rseg.h | 5 +- storage/innobase/include/trx0sys.h | 5 + storage/innobase/srv/srv0srv.cc | 3 +- storage/innobase/trx/trx0purge.cc | 233 ++++++++++++++++++--------- storage/innobase/trx/trx0undo.cc | 8 +- 6 files changed, 212 insertions(+), 93 deletions(-) diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h index 3ddd2e98fee..a836c134c02 100644 --- a/storage/innobase/include/trx0purge.h +++ b/storage/innobase/include/trx0purge.h @@ -140,6 +140,15 @@ private: bool m_initialized{false}; /** whether purge is enabled; protected by latch and std::atomic */ std::atomic m_enabled{false}; + /** The primary candidate for iterator::free_history() is + rseg=trx_sys.rseg_array[skipped_rseg]. This field may be changed + after invoking rseg.set_skip_allocation() and rseg.clear_skip_allocation() + and while holding the exclusive rseg.latch. + + This may only be 0 if innodb_undo_tablespaces=0, because rollback segment + 0 always resides in the system tablespace and would never be used when + dedicated undo tablespaces are in use. */ + Atomic_relaxed skipped_rseg; public: /** whether purge is active (may hold table handles) */ std::atomic m_active{false}; @@ -197,6 +206,11 @@ public: return undo_no <= other.undo_no; } + /** Remove unnecessary history data from a rollback segment. + @param rseg rollback segment + @return error code */ + inline dberr_t free_history_rseg(trx_rseg_t &rseg) const; + /** Free the undo pages up to this. */ dberr_t free_history() const; @@ -240,14 +254,15 @@ public: by the pq_mutex */ mysql_mutex_t pq_mutex; /*!< Mutex protecting purge_queue */ - /** Undo tablespace file truncation (only accessed by the - srv_purge_coordinator_thread) */ - struct { - /** The undo tablespace that is currently being truncated */ - fil_space_t* current; - /** The undo tablespace that was last truncated */ - fil_space_t* last; - } truncate; + /** innodb_undo_log_truncate=ON state; + only modified by purge_coordinator_callback() */ + struct { + /** The undo tablespace that is currently being truncated */ + Atomic_relaxed current; + /** The number of the undo tablespace that was last truncated, + relative from srv_undo_space_id_start */ + ulint last; + } truncate_undo_space; /** Create the instance */ void create(); @@ -357,6 +372,26 @@ public: typically via purge_sys_t::view_guard. */ return view.sees(id); } + +private: + /** Enable the use of a rollback segment and advance skipped_rseg, + after iterator::free_history_rseg() had invoked + rseg.set_skip_allocation(). */ + inline void rseg_enable(trx_rseg_t &rseg); + + /** Try to start truncating a tablespace. + @param id undo tablespace identifier + @param size the maximum desired undo tablespace size, in pages + @return undo tablespace whose truncation was started + @retval nullptr if truncation is not currently possible */ + inline fil_space_t *undo_truncate_try(ulint id, ulint size); +public: + /** Check if innodb_undo_log_truncate=ON needs to be handled. + This is only to be called by purge_coordinator_callback(). + @return undo tablespace chosen by innodb_undo_log_truncate=ON + @retval nullptr if truncation is not currently possible */ + fil_space_t *truncating_tablespace(); + /** A wrapper around trx_sys_t::clone_oldest_view(). */ template void clone_oldest_view() diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h index 1d95b7d2e7a..f5d9a2199a1 100644 --- a/storage/innobase/include/trx0rseg.h +++ b/storage/innobase/include/trx0rseg.h @@ -73,14 +73,15 @@ private: /** Reference counter to track is_persistent() transactions, with SKIP flag. */ std::atomic ref; - +public: /** Whether undo tablespace truncation is pending */ static constexpr uint32_t SKIP= 1; /** Transaction reference count multiplier */ static constexpr uint32_t REF= 2; + /** @return the reference count and flags */ uint32_t ref_load() const { return ref.load(std::memory_order_relaxed); } - +private: /** Set the SKIP bit */ void ref_set_skip() { diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index c5f8ab012c4..cf1579a3e30 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -1189,6 +1189,11 @@ public: return count; } + /** Disable further allocation of transactions in a rollback segment + that are subject to innodb_undo_log_truncate=ON + @param space undo tablespace that will be truncated */ + inline void undo_truncate_start(fil_space_t &space); + private: static my_bool find_same_or_older_callback(rw_trx_hash_element_t *element, trx_id_t *id) diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 7923b14d69d..b29caf255fc 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1638,7 +1638,8 @@ inline void purge_coordinator_state::do_purge() ulint n_pages_handled= trx_purge(n_threads, history_size); if (!trx_sys.history_exists()) goto no_history; - if (purge_sys.truncate.current || srv_shutdown_state != SRV_SHUTDOWN_NONE) + if (purge_sys.truncating_tablespace() || + srv_shutdown_state != SRV_SHUTDOWN_NONE) { purge_truncation_task.wait(); trx_purge_truncate_history(); diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 230036c8499..30cce66697f 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -169,10 +169,15 @@ void purge_sys_t::create() ut_ad(this == &purge_sys); ut_ad(!m_initialized); ut_ad(!enabled()); + ut_ad(!m_active); + /* If innodb_undo_tablespaces>0, the rollback segment 0 + (which always resides in the system tablespace) will + never be used; @see trx_assign_rseg_low() */ + skipped_rseg= srv_undo_tablespaces > 0; m_paused= 0; query= purge_graph_build(); next_stored= false; - rseg= NULL; + rseg= nullptr; page_no= 0; offset= 0; hdr_page_no= 0; @@ -180,8 +185,8 @@ void purge_sys_t::create() latch.SRW_LOCK_INIT(trx_purge_latch_key); end_latch.init(); mysql_mutex_init(purge_sys_pq_mutex_key, &pq_mutex, nullptr); - truncate.current= NULL; - truncate.last= NULL; + truncate_undo_space.current= nullptr; + truncate_undo_space.last= 0; m_initialized= true; } @@ -387,17 +392,50 @@ static void trx_purge_free_segment(buf_block_t *rseg_hdr, buf_block_t *block, block->page.frame, &mtr)); } +void purge_sys_t::rseg_enable(trx_rseg_t &rseg) +{ + ut_ad(this == &purge_sys); +#ifndef SUX_LOCK_GENERIC + ut_ad(rseg.latch.is_write_locked()); +#endif + uint8_t skipped= skipped_rseg; + ut_ad(skipped < TRX_SYS_N_RSEGS); + if (&rseg == &trx_sys.rseg_array[skipped]) + { + /* If this rollback segment is subject to innodb_undo_log_truncate=ON, + we must not clear the flag. But we will advance purge_sys.skipped_rseg + to be able to choose another candidate for this soft truncation, and + to prevent the following scenario: + + (1) purge_sys_t::iterator::free_history_rseg() had invoked + rseg.set_skip_allocation() + (2) undo log truncation had completed on this rollback segment + (3) SET GLOBAL innodb_undo_log_truncate=OFF + (4) purge_sys_t::iterator::free_history_rseg() would not be able to + invoke rseg.set_skip_allocation() on any other rollback segment + before this rseg has grown enough */ + if (truncate_undo_space.current != rseg.space) + rseg.clear_skip_allocation(); + skipped++; + /* If innodb_undo_tablespaces>0, the rollback segment 0 + (which always resides in the system tablespace) will + never be used; @see trx_assign_rseg_low() */ + if (!(skipped%= TRX_SYS_N_RSEGS) && srv_undo_tablespaces) + skipped++; + skipped_rseg= skipped; + } +} + /** Remove unnecessary history data from a rollback segment. @param rseg rollback segment @param limit truncate anything before this -@param all whether everything can be truncated @return error code */ -static dberr_t -trx_purge_truncate_rseg_history(trx_rseg_t &rseg, - const purge_sys_t::iterator &limit, bool all) +inline dberr_t purge_sys_t::iterator::free_history_rseg(trx_rseg_t &rseg) const { fil_addr_t hdr_addr; mtr_t mtr; + bool freed= false; + uint32_t rseg_ref= 0; mtr.start(); @@ -407,6 +445,8 @@ trx_purge_truncate_rseg_history(trx_rseg_t &rseg, { func_exit: mtr.commit(); + if (freed && (rseg.SKIP & rseg_ref)) + purge_sys.rseg_enable(rseg); return err; } @@ -428,16 +468,40 @@ loop: const trx_id_t undo_trx_no= mach_read_from_8(b->page.frame + hdr_addr.boffset + TRX_UNDO_TRX_NO); - if (undo_trx_no >= limit.trx_no) + if (undo_trx_no >= trx_no) { - if (undo_trx_no == limit.trx_no) - err = trx_undo_truncate_start(&rseg, hdr_addr.page, - hdr_addr.boffset, limit.undo_no); + if (undo_trx_no == trx_no) + err= trx_undo_truncate_start(&rseg, hdr_addr.page, + hdr_addr.boffset, undo_no); goto func_exit; } + else + { + rseg_ref= rseg.ref_load(); + if (rseg_ref >= rseg.REF || !purge_sys.sees(rseg.needs_purge)) + { + /* We cannot clear this entire rseg because trx_assign_rseg_low() + has already chosen it for a future trx_undo_assign(), or + because some recently started transaction needs purging. - if (!all) - goto func_exit; + If this invocation could not reduce rseg.history_size at all + (!freed), we will try to ensure progress and prevent our + starvation by disabling one rollback segment for future + trx_assign_rseg_low() invocations until a future invocation has + made progress and invoked purge_sys_t::rseg_enable(rseg) on that + rollback segment. */ + + if (!(rseg.SKIP & rseg_ref) && !freed && + ut_d(!trx_rseg_n_slots_debug &&) + &rseg == &trx_sys.rseg_array[purge_sys.skipped_rseg]) + /* If rseg.space == purge_sys.truncate_undo_space.current + the following will be a no-op. A possible conflict + with innodb_undo_log_truncate=ON will be handled in + purge_sys_t::rseg_enable(). */ + rseg.set_skip_allocation(); + goto func_exit; + } + } fil_addr_t prev_hdr_addr= flst_get_prev_addr(b->page.frame + hdr_addr.boffset + @@ -500,6 +564,7 @@ loop: mtr.commit(); ut_ad(rseg.history_size > 0); rseg.history_size--; + freed= true; mtr.start(); rseg_hdr->page.lock.x_lock(); ut_ad(rseg_hdr->page.id() == rseg.page_id()); @@ -554,9 +619,7 @@ dberr_t purge_sys_t::iterator::free_history() const ut_ad(rseg.is_persistent()); log_free_check(); rseg.latch.wr_lock(SRW_LOCK_CALL); - dberr_t err= - trx_purge_truncate_rseg_history(rseg, *this, !rseg.is_referenced() && - purge_sys.sees(rseg.needs_purge)); + dberr_t err= free_history_rseg(rseg); rseg.latch.wr_unlock(); if (err) return err; @@ -564,6 +627,62 @@ dberr_t purge_sys_t::iterator::free_history() const return DB_SUCCESS; } +inline void trx_sys_t::undo_truncate_start(fil_space_t &space) +{ + ut_ad(this == &trx_sys); + /* Undo tablespace always are a single file. */ + ut_a(UT_LIST_GET_LEN(space.chain) == 1); + fil_node_t *file= UT_LIST_GET_FIRST(space.chain); + /* The undo tablespace files are never closed. */ + ut_ad(file->is_open()); + sql_print_information("InnoDB: Starting to truncate %s", file->name); + + for (auto &rseg : rseg_array) + if (rseg.space == &space) + { + /* Prevent a race with purge_sys_t::iterator::free_history_rseg() */ + rseg.latch.rd_lock(SRW_LOCK_CALL); + /* Once set, this rseg will not be allocated to subsequent + transactions, but we will wait for existing active + transactions to finish. */ + rseg.set_skip_allocation(); + rseg.latch.rd_unlock(); + } +} + +inline fil_space_t *purge_sys_t::undo_truncate_try(ulint id, ulint size) +{ + ut_ad(srv_is_undo_tablespace(id)); + fil_space_t *space= fil_space_get(id); + if (space && space->get_size() > size) + { + truncate_undo_space.current= space; + trx_sys.undo_truncate_start(*space); + return space; + } + return nullptr; +} + +fil_space_t *purge_sys_t::truncating_tablespace() +{ + ut_ad(this == &purge_sys); + + fil_space_t *space= truncate_undo_space.current; + if (space || srv_undo_tablespaces_active < 2 || !srv_undo_log_truncate) + return space; + + const ulint size= ulint(srv_max_undo_log_size >> srv_page_size_shift); + for (ulint i= truncate_undo_space.last, j= i;; ) + { + if (fil_space_t *s= undo_truncate_try(srv_undo_space_id_start + i, size)) + return s; + ++i; + i%= srv_undo_tablespaces_active; + if (i == j) + return nullptr; + } +} + #if defined __GNUC__ && __GNUC__ == 4 && !defined __clang__ # if defined __arm__ || defined __aarch64__ /* Work around an internal compiler error in GCC 4.8.5 */ @@ -589,55 +708,14 @@ TRANSACTIONAL_TARGET void trx_purge_truncate_history() head.undo_no= 0; } - if (head.free_history() != DB_SUCCESS || srv_undo_tablespaces_active < 2) + if (head.free_history() != DB_SUCCESS) return; - while (srv_undo_log_truncate) + while (fil_space_t *space= purge_sys.truncating_tablespace()) { - if (!purge_sys.truncate.current) - { - const ulint threshold= - ulint(srv_max_undo_log_size >> srv_page_size_shift); - for (ulint i= purge_sys.truncate.last - ? purge_sys.truncate.last->id - srv_undo_space_id_start : 0, - j= i;; ) - { - const auto space_id= srv_undo_space_id_start + i; - ut_ad(srv_is_undo_tablespace(space_id)); - fil_space_t *space= fil_space_get(space_id); - ut_a(UT_LIST_GET_LEN(space->chain) == 1); - - if (space && space->get_size() > threshold) - { - purge_sys.truncate.current= space; - break; - } - - ++i; - i %= srv_undo_tablespaces_active; - if (i == j) - return; - } - } - - fil_space_t &space= *purge_sys.truncate.current; - /* Undo tablespace always are a single file. */ - fil_node_t *file= UT_LIST_GET_FIRST(space.chain); - /* The undo tablespace files are never closed. */ - ut_ad(file->is_open()); - - DBUG_LOG("undo", "marking for truncate: " << file->name); - - for (auto &rseg : trx_sys.rseg_array) - if (rseg.space == &space) - /* Once set, this rseg will not be allocated to subsequent - transactions, but we will wait for existing active - transactions to finish. */ - rseg.set_skip_allocation(); - for (auto &rseg : trx_sys.rseg_array) { - if (rseg.space != &space) + if (rseg.space != space) continue; rseg.latch.rd_lock(SRW_LOCK_CALL); @@ -670,8 +748,9 @@ not_free: rseg.latch.rd_unlock(); } - sql_print_information("InnoDB: Truncating %s", file->name); - trx_purge_cleanse_purge_queue(space); + const char *file_name= UT_LIST_GET_FIRST(space->chain)->name; + sql_print_information("InnoDB: Truncating %s", file_name); + trx_purge_cleanse_purge_queue(*space); /* Lock all modified pages of the tablespace. @@ -688,12 +767,12 @@ not_free: /* Adjust the tablespace metadata. */ mysql_mutex_lock(&fil_system.mutex); - if (space.crypt_data) + if (space->crypt_data) { - space.reacquire(); + space->reacquire(); mysql_mutex_unlock(&fil_system.mutex); - fil_space_crypt_close_tablespace(&space); - space.release(); + fil_space_crypt_close_tablespace(space); + space->release(); } else mysql_mutex_unlock(&fil_system.mutex); @@ -705,17 +784,17 @@ not_free: mtr_t mtr; mtr.start(); - mtr.x_lock_space(&space); + mtr.x_lock_space(space); /* Associate the undo tablespace with mtr. During mtr::commit_shrink(), InnoDB can use the undo tablespace object to clear all freed ranges */ - mtr.set_named_space(&space); - mtr.trim_pages(page_id_t(space.id, size)); - ut_a(fsp_header_init(&space, size, &mtr) == DB_SUCCESS); + mtr.set_named_space(space); + mtr.trim_pages(page_id_t(space->id, size)); + ut_a(fsp_header_init(space, size, &mtr) == DB_SUCCESS); for (auto &rseg : trx_sys.rseg_array) { - if (rseg.space != &space) + if (rseg.space != space) continue; ut_ad(!rseg.is_referenced()); @@ -724,7 +803,7 @@ not_free: possibly before this server had been started up. */ dberr_t err; - buf_block_t *rblock= trx_rseg_header_create(&space, + buf_block_t *rblock= trx_rseg_header_create(space, &rseg - trx_sys.rseg_array, trx_sys.get_max_trx_id(), &mtr, &err); @@ -737,7 +816,7 @@ not_free: rseg.reinit(rblock->page.id().page_no()); } - mtr.commit_shrink(space, size); + mtr.commit_shrink(*space, size); /* No mutex; this is only updated by the purge coordinator. */ export_vars.innodb_undo_truncations++; @@ -759,10 +838,10 @@ not_free: log_buffer_flush_to_disk(); DBUG_SUICIDE();); - sql_print_information("InnoDB: Truncated %s", file->name); - purge_sys.truncate.last= purge_sys.truncate.current; - ut_ad(&space == purge_sys.truncate.current); - purge_sys.truncate.current= nullptr; + sql_print_information("InnoDB: Truncated %s", file_name); + ut_ad(space == purge_sys.truncate_undo_space.current); + purge_sys.truncate_undo_space.current= nullptr; + purge_sys.truncate_undo_space.last= space->id - srv_undo_space_id_start; } } diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index def47686da2..ccc68dfeef7 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -907,15 +907,13 @@ trx_undo_truncate_start( trx_undo_rec_t* last_rec; mtr_t mtr; + ut_ad(rseg->is_persistent()); + if (!limit) { return DB_SUCCESS; } loop: - mtr_start(&mtr); - - if (!rseg->is_persistent()) { - mtr.set_log_mode(MTR_LOG_NO_REDO); - } + mtr.start(); dberr_t err; const buf_block_t* undo_page; From 6a514ef6727c1c1102f57554cdf28aaa775d210a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 17 Jan 2024 12:50:44 +0200 Subject: [PATCH 18/18] MDEV-30940: Try to fix the test --- mysql-test/suite/innodb/r/lock_move_wait_lock_race.result | 3 ++- mysql-test/suite/innodb/t/lock_move_wait_lock_race.test | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/r/lock_move_wait_lock_race.result b/mysql-test/suite/innodb/r/lock_move_wait_lock_race.result index 572fbc9b1d1..c78102d9c3b 100644 --- a/mysql-test/suite/innodb/r/lock_move_wait_lock_race.result +++ b/mysql-test/suite/innodb/r/lock_move_wait_lock_race.result @@ -1,4 +1,5 @@ -CREATE TABLE t (pk int PRIMARY KEY, c varchar(10)) ENGINE=InnoDB; +CREATE TABLE t (pk int PRIMARY KEY, c varchar(10)) +STATS_PERSISTENT=0 ENGINE=InnoDB; INSERT INTO t VALUES (10, "0123456789"); connection default; BEGIN; diff --git a/mysql-test/suite/innodb/t/lock_move_wait_lock_race.test b/mysql-test/suite/innodb/t/lock_move_wait_lock_race.test index 3a04c7127c8..0f88f8d9d0f 100644 --- a/mysql-test/suite/innodb/t/lock_move_wait_lock_race.test +++ b/mysql-test/suite/innodb/t/lock_move_wait_lock_race.test @@ -3,7 +3,8 @@ --source include/have_debug.inc --source include/have_debug_sync.inc -CREATE TABLE t (pk int PRIMARY KEY, c varchar(10)) ENGINE=InnoDB; +CREATE TABLE t (pk int PRIMARY KEY, c varchar(10)) +STATS_PERSISTENT=0 ENGINE=InnoDB; INSERT INTO t VALUES (10, "0123456789"); --connection default