From dd62a285b88958dae9b9f3e49fdd0c55f6eced72 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Mon, 20 Nov 2023 16:22:07 +0100 Subject: [PATCH 1/5] MDEV-31611: mariadb-setpermission - Can't use string as an ARRAY ref while strict refs in use Reviewer: <> --- scripts/mysql_setpermission.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/mysql_setpermission.sh b/scripts/mysql_setpermission.sh index b3c9c27ca88..aa165a5e742 100644 --- a/scripts/mysql_setpermission.sh +++ b/scripts/mysql_setpermission.sh @@ -68,7 +68,7 @@ usage() if ($opt_help); # the help function if ($opt_host =~ s/:(\d+)$//) { - $opt_port = $1; + $opt_port = $1; } if ($opt_host eq '') @@ -98,7 +98,7 @@ my $prefix= 'mysql'; if (eval {DBI->install_driver("MariaDB")}) { $dsn ="DBI:MariaDB:;"; $prefix= 'mariadb'; -} +} else { $dsn = "DBI:mysql:;"; } @@ -226,11 +226,11 @@ sub setpwd { $pass = "PASSWORD(". $dbh->quote($pass) . ")"; } - my $uh= "$user@$host"; + my $uh= $user."@".$host; my $sth = $dbh->prepare("set password for $uh =$pass") || die $dbh->errstr; $sth->execute || die $dbh->errstr; $sth->finish; - print "The password is set for user $user.\n\n"; + print "The password is set for user $uh.\n\n"; } From f436b4a523df603ca3f245e7b523e30bbe06f12b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 27 Nov 2023 09:56:21 +0400 Subject: [PATCH 2/5] MDEV-32879 Server crash in my_decimal::operator= or unexpected ER_DUP_ENTRY upon comparison with INET6 and similar types During the 10.5->10.6 merge please use the 10.6 code on conflicts. This is the 10.5 version of the patch (a backport of the 10.6 version). Unlike 10.6 version, it makes changes in plugin/type_inet/sql_type_inet.* rather than in sql/sql_type_fixedbin.h Item_bool_rowready_func2, Item_func_between, Item_func_in did not check if a not-NULL argument of an arbitrary data type can produce a NULL value on conversion to INET6. This caused a crash on DBUG_ASSERT() in conversion failures, because the function returned SQL NULL for something that has Item::maybe_null() equal to false. Adding setting NULL-ability in such cases. Details: - Removing the code in Item_func::setup_args_and_comparator() performing character set aggregation with optional narrowing. This aggregation is done inside Arg_comparator::set_cmp_func_string(). So this code was redundant - Removing Item_func::setup_args_and_comparator() as it git simplified to just to two lines: convert_const_compared_to_int_field(thd); return cmp->set_cmp_func(thd, this, &args[0], &args[1], true); Using these lines directly in: - Item_bool_rowready_func2::fix_length_and_dec() - Item_func_nullif::fix_length_and_dec() - Adding a new virtual method: - Type_handler::Item_bool_rowready_func2_fix_length_and_dec(). - Adding tests detecting if the data type conversion can return SQL NULL into the following methods of Type_handler_inet6: - Item_bool_rowready_func2_fix_length_and_dec - Item_func_between_fix_length_and_dec - Item_func_in_fix_comparator_compatible_types --- .../mysql-test/type_inet/type_inet6.result | 75 +++++++++++++++++++ .../mysql-test/type_inet/type_inet6.test | 26 +++++++ plugin/type_inet/sql_type_inet.h | 33 ++++++++ sql/item.cc | 26 ++++++- sql/item.h | 11 ++- sql/item_cmpfunc.cc | 65 ++++++++-------- sql/item_cmpfunc.h | 35 +++++++-- sql/item_func.h | 10 --- sql/item_sum.cc | 9 ++- sql/sql_select.cc | 10 +-- sql/sql_type.cc | 8 ++ sql/sql_type.h | 11 ++- 12 files changed, 255 insertions(+), 64 deletions(-) diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.result b/plugin/type_inet/mysql-test/type_inet/type_inet6.result index 9c43725c733..7484a10962c 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.result +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.result @@ -2255,3 +2255,78 @@ a Warnings: Warning 1292 Incorrect inet6 value: '' DROP TABLE t1; +# +# MDEV-32879 Server crash in my_decimal::operator= or unexpected ER_DUP_ENTRY upon comparison with INET6 and similar types +# +CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f, GROUP_CONCAT(c) FROM t1 GROUP BY f; +f GROUP_CONCAT(c) +NULL 2000-01-01 00:00:00.000000,1900-01-01 00:00:00.000000 +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f, COUNT(c) FROM t1 GROUP BY f; +f COUNT(c) +NULL 2 +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f FROM t1 ORDER BY f; +f +NULL +NULL +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL); +INSERT INTO t1 VALUES ('','::'),('','::'); +SELECT 1.00 + (b = a) AS f FROM t1 ORDER BY f; +f +NULL +NULL +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +SELECT 1.00 + (b BETWEEN a AND '') AS f FROM t1 ORDER BY f; +f +NULL +NULL +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +SELECT 1.00 + (b IN (a,'')) AS f FROM t1 ORDER BY f; +f +NULL +NULL +Warnings: +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +Warning 1292 Incorrect inet6 value: '' +DROP TABLE t1; diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.test b/plugin/type_inet/mysql-test/type_inet/type_inet6.test index b0dffb098f2..abe9071962f 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.test +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.test @@ -1660,3 +1660,29 @@ CREATE OR REPLACE TABLE t1 (a INET6); INSERT INTO t1 VALUES ('::'); SELECT * FROM t1 WHERE a IN ('','::1'); DROP TABLE t1; + +--echo # +--echo # MDEV-32879 Server crash in my_decimal::operator= or unexpected ER_DUP_ENTRY upon comparison with INET6 and similar types +--echo # + +CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f, GROUP_CONCAT(c) FROM t1 GROUP BY f; +DROP TABLE t1; + +CREATE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f, COUNT(c) FROM t1 GROUP BY f; +DROP TABLE t1; + +CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL, c DATETIME(6) NOT NULL); +INSERT INTO t1 VALUES ('','::','2000-01-01'),('','::','1900-01-01'); +SELECT c + (b = a) AS f FROM t1 ORDER BY f; +DROP TABLE t1; + +CREATE OR REPLACE TABLE t1 (a CHAR(36) NOT NULL, b INET6 NOT NULL); +INSERT INTO t1 VALUES ('','::'),('','::'); +SELECT 1.00 + (b = a) AS f FROM t1 ORDER BY f; +SELECT 1.00 + (b BETWEEN a AND '') AS f FROM t1 ORDER BY f; +SELECT 1.00 + (b IN (a,'')) AS f FROM t1 ORDER BY f; +DROP TABLE t1; diff --git a/plugin/type_inet/sql_type_inet.h b/plugin/type_inet/sql_type_inet.h index 80d8544e6c9..a83dddb4c26 100644 --- a/plugin/type_inet/sql_type_inet.h +++ b/plugin/type_inet/sql_type_inet.h @@ -188,6 +188,21 @@ public: */ static bool fix_fields_maybe_null_on_conversion_to_inet6(Item *item); + /* + Check at fix_fields() time if any of the items can return a nullable + value on conversion to Fbt. + */ + static bool fix_fields_maybe_null_on_conversion_to_inet6(Item **items, + uint count) + { + for (uint i= 0; i < count; i++) + { + if (fix_fields_maybe_null_on_conversion_to_inet6(items[i])) + return true; + } + return false; + } + public: Inet6(Item *item, bool *error, bool warn= true) @@ -714,6 +729,16 @@ public: Inet6_null nb(b); return !na.is_null() && !nb.is_null() && !na.cmp(nb); } + bool Item_bool_rowready_func2_fix_length_and_dec(THD *thd, + Item_bool_rowready_func2 *func) const override + { + if (Type_handler::Item_bool_rowready_func2_fix_length_and_dec(thd, func)) + return true; + if (!func->maybe_null && + Inet6::fix_fields_maybe_null_on_conversion_to_inet6(func->arguments(), 2)) + func->maybe_null= true; + return false; + } bool Item_hybrid_func_fix_attributes(THD *thd, const char *name, Type_handler_hybrid_field_type *h, @@ -902,6 +927,10 @@ public: bool Item_func_between_fix_length_and_dec(Item_func_between *func) const override { + if (!func->maybe_null && + Inet6::fix_fields_maybe_null_on_conversion_to_inet6(func->arguments(), 3)) + func->maybe_null= true; + return false; } longlong Item_func_between_val_int(Item_func_between *func) const override @@ -918,6 +947,10 @@ public: Item_func_in *func) const override { + if (!func->maybe_null && + Inet6::fix_fields_maybe_null_on_conversion_to_inet6(func->arguments(), + func->argument_count())) + func->maybe_null= true; if (func->compatible_types_scalar_bisection_possible()) { return func->value_list_convert_const_to_int(thd) || diff --git a/sql/item.cc b/sql/item.cc index 1853f7b560f..44965a1feb9 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2497,7 +2497,8 @@ bool DTCollation::aggregate(const DTCollation &dt, uint flags) /******************************/ static -void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +void my_coll_agg_error(const DTCollation &c1, const DTCollation &c2, + const char *fname) { my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), c1.collation->name,c1.derivation_name(), @@ -2579,10 +2580,17 @@ bool Type_std_attributes::agg_item_collations(DTCollation &c, const char *fname, } +/* + @param single_err When nargs==1, use *single_err as the second aggregated + collation when producing error message. +*/ + bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, const char *fname, Item **args, uint nargs, - uint flags, int item_sep) + uint flags, int item_sep, + const Single_coll_err + *single_err) { THD *thd= current_thd; if (thd->lex->is_ps_or_view_context_analysis()) @@ -2620,7 +2628,19 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, args[0]= safe_args[0]; args[item_sep]= safe_args[1]; } - my_coll_agg_error(args, nargs, fname, item_sep); + if (nargs == 1 && single_err) + { + /* + Use *single_err to produce an error message mentioning two + collations. + */ + if (single_err->first) + my_coll_agg_error(args[0]->collation, single_err->coll, fname); + else + my_coll_agg_error(single_err->coll, args[0]->collation, fname); + } + else + my_coll_agg_error(args, nargs, fname, item_sep); return TRUE; } diff --git a/sql/item.h b/sql/item.h index e7125cccd14..16679776053 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5237,10 +5237,17 @@ public: func_name()); return true; } + /* + If necessary, convert both *a and *b to the collation in tmp: + */ + Single_coll_err error_for_a= {(*b)->collation, true}; + Single_coll_err error_for_b= {(*a)->collation, false}; if (agg_item_set_converter(tmp, func_name(), - a, 1, MY_COLL_CMP_CONV, 1) || + a, 1, MY_COLL_CMP_CONV, 1, + /*just for error message*/ &error_for_a) || agg_item_set_converter(tmp, func_name(), - b, 1, MY_COLL_CMP_CONV, 1)) + b, 1, MY_COLL_CMP_CONV, 1, + /*just for error message*/ &error_for_b)) return true; *cs= tmp.collation; return false; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4a2de58e748..324aceafd41 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -413,26 +413,6 @@ void Item_func::convert_const_compared_to_int_field(THD *thd) } -bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp) -{ - DBUG_ASSERT(arg_count >= 2); // Item_func_nullif has arg_count == 3 - - if (args[0]->cmp_type() == STRING_RESULT && - args[1]->cmp_type() == STRING_RESULT) - { - DTCollation tmp; - if (agg_arg_charsets_for_comparison(tmp, args, 2)) - return true; - cmp->m_compare_collation= tmp.collation; - } - // Convert constants when compared to int/year field - DBUG_ASSERT(functype() != LIKE_FUNC); - convert_const_compared_to_int_field(thd); - - return cmp->set_cmp_func(this, &args[0], &args[1], true); -} - - /* Comparison operators remove arguments' dependency on PAD_CHAR_TO_FULL_LENGTH in case of PAD SPACE comparison collations: trailing spaces do not affect @@ -452,6 +432,7 @@ Item_bool_rowready_func2::value_depends_on_sql_mode() const bool Item_bool_rowready_func2::fix_length_and_dec() { + THD *thd= current_thd; max_length= 1; // Function returns 0 or 1 /* @@ -460,7 +441,16 @@ bool Item_bool_rowready_func2::fix_length_and_dec() */ if (!args[0] || !args[1]) return FALSE; - return setup_args_and_comparator(current_thd, &cmp); + convert_const_compared_to_int_field(thd); + Type_handler_hybrid_field_type tmp; + if (tmp.aggregate_for_comparison(func_name(), args, 2, false) || + tmp.type_handler()->Item_bool_rowready_func2_fix_length_and_dec(thd, + this)) + { + DBUG_ASSERT(thd->is_error()); + return true; + } + return false; } @@ -477,27 +467,22 @@ bool Item_bool_rowready_func2::fix_length_and_dec() items, holding the cached converted value of the original (constant) item. */ -int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg, +int Arg_comparator::set_cmp_func(THD *thd, Item_func_or_sum *owner_arg, + const Type_handler *compare_handler, Item **a1, Item **a2) { owner= owner_arg; set_null= set_null && owner_arg; a= a1; b= a2; - Item *tmp_args[2]= {*a1, *a2}; - Type_handler_hybrid_field_type tmp; - if (tmp.aggregate_for_comparison(owner_arg->func_name(), tmp_args, 2, false)) - { - DBUG_ASSERT(current_thd->is_error()); - return 1; - } - m_compare_handler= tmp.type_handler(); + m_compare_handler= compare_handler; return m_compare_handler->set_comparator_func(this); } bool Arg_comparator::set_cmp_func_for_row_arguments() { + THD *thd= current_thd; uint n= (*a)->cols(); if (n != (*b)->cols()) { @@ -514,8 +499,8 @@ bool Arg_comparator::set_cmp_func_for_row_arguments() my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols()); return true; } - if (comparators[i].set_cmp_func(owner, (*a)->addr(i), - (*b)->addr(i), set_null)) + if (comparators[i].set_cmp_func(thd, owner, (*a)->addr(i), + (*b)->addr(i), set_null)) return true; } return false; @@ -541,7 +526,16 @@ bool Arg_comparator::set_cmp_func_string() { /* We must set cmp_collation here as we may be called from for an automatic - generated item, like in natural join + generated item, like in natural join. + Allow reinterpted superset as subset. + Use charset narrowing only for equalities, as that would allow + to construct ref access. + Non-equality comparisons with constants work without charset narrowing, + the constant gets converted. + Non-equality comparisons with non-constants would need narrowing to + enable range optimizer to handle e.g. + t1.mb3key_col <= const_table.mb4_col + But this doesn't look important. */ if (owner->agg_arg_charsets_for_comparison(&m_compare_collation, a, b)) return true; @@ -2748,8 +2742,9 @@ Item_func_nullif::fix_length_and_dec() fix_char_length(args[2]->max_char_length()); maybe_null=1; m_arg0= args[0]; - if (setup_args_and_comparator(thd, &cmp)) - return TRUE; + convert_const_compared_to_int_field(thd); + if (cmp.set_cmp_func(thd, this, &args[0], &args[1], true/*set_null*/)) + return true; /* A special code for EXECUTE..PREPARE. diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 7cbc1236a03..3929b4c7d30 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -56,7 +56,9 @@ class Arg_comparator: public Sql_alloc Item *a_cache, *b_cache; // Cached values of a and b items // when one of arguments is NULL. - int set_cmp_func(Item_func_or_sum *owner_arg, Item **a1, Item **a2); + int set_cmp_func(THD *thd, Item_func_or_sum *owner_arg, + const Type_handler *compare_handler, + Item **a1, Item **a2); int compare_not_null_values(longlong val1, longlong val2) { @@ -93,12 +95,25 @@ public: bool set_cmp_func_real(); bool set_cmp_func_decimal(); - inline int set_cmp_func(Item_func_or_sum *owner_arg, - Item **a1, Item **a2, bool set_null_arg) + inline int set_cmp_func(THD *thd, Item_func_or_sum *owner_arg, + const Type_handler *compare_handler, + Item **a1, Item **a2, bool set_null_arg) { set_null= set_null_arg; - return set_cmp_func(owner_arg, a1, a2); + return set_cmp_func(thd, owner_arg, compare_handler, a1, a2); } + int set_cmp_func(THD *thd, Item_func_or_sum *owner_arg, + Item **a1, Item **a2, bool set_null_arg) + { + Item *tmp_args[2]= { *a1, *a2 }; + Type_handler_hybrid_field_type tmp; + if (tmp.aggregate_for_comparison(owner_arg->func_name(), + tmp_args, 2, false)) + return 1; + return set_cmp_func(thd, owner_arg, tmp.type_handler(), + a1, a2, set_null_arg); + } + inline int compare() { return (this->*func)(); } int compare_string(); // compare args[0] & args[1] @@ -533,9 +548,17 @@ public: return this; } bool fix_length_and_dec(); - int set_cmp_func() + bool fix_length_and_dec_generic(THD *thd, + const Type_handler *compare_handler) { - return cmp.set_cmp_func(this, tmp_arg, tmp_arg + 1, true); + DBUG_ASSERT(args == tmp_arg); + return cmp.set_cmp_func(thd, this, compare_handler, + tmp_arg, tmp_arg + 1, true/*set_null*/); + } + int set_cmp_func(THD *thd) + { + DBUG_ASSERT(args == tmp_arg); + return cmp.set_cmp_func(thd, this, tmp_arg, tmp_arg + 1, true/*set_null*/); } CHARSET_INFO *compare_collation() const { return cmp.compare_collation(); } const Type_handler *compare_type_handler() const diff --git a/sql/item_func.h b/sql/item_func.h index bd04af926b0..ef020fa9054 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -395,16 +395,6 @@ public: } } void convert_const_compared_to_int_field(THD *thd); - /** - Prepare arguments and setup a comparator. - Used in Item_func_xxx with two arguments and a comparator, - e.g. Item_bool_func2 and Item_func_nullif. - args[0] or args[1] can be modified: - - converted to character set and collation of the operation - - or replaced to an Item_int_with_ref - */ - bool setup_args_and_comparator(THD *thd, Arg_comparator *cmp); - bool with_sum_func() const { return m_with_sum_func; } With_sum_func_cache* get_with_sum_func_cache() { return this; } Item_func *get_item_func() { return this; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 46942c0c785..584fd21ca4a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1277,9 +1277,14 @@ void Item_sum_min_max::setup_hybrid(THD *thd, Item *item, Item *value_arg) /* Don't cache value, as it will change */ if (!item->const_item()) arg_cache->set_used_tables(RAND_TABLE_BIT); - cmp= new Arg_comparator(); + DBUG_ASSERT(item->type_handler_for_comparison() == + value->type_handler_for_comparison()); + DBUG_ASSERT(item->type_handler_for_comparison() == + arg_cache->type_handler_for_comparison()); + cmp= new (thd->mem_root) Arg_comparator(); if (cmp) - cmp->set_cmp_func(this, (Item**)&arg_cache, (Item**)&value, FALSE); + cmp->set_cmp_func(thd, this, item->type_handler_for_comparison(), + (Item**)&arg_cache, (Item**)&value, FALSE); DBUG_VOID_RETURN; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 62766cdb9cf..21132651b07 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15405,7 +15405,7 @@ static bool check_row_equality(THD *thd, const Arg_comparator *comparators, { Item_func_eq *eq_item; if (!(eq_item= new (thd->mem_root) Item_func_eq(thd, left_item, right_item)) || - eq_item->set_cmp_func()) + eq_item->set_cmp_func(thd)) return FALSE; eq_item->quick_fix_field(); eq_list->push_back(eq_item, thd->mem_root); @@ -16155,7 +16155,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels, Don't produce equality if const is equal to item_const. */ Item_func_eq *func= new (thd->mem_root) Item_func_eq(thd, item_const, upper_const); - func->set_cmp_func(); + func->set_cmp_func(thd); func->quick_fix_field(); if (func->val_int()) item= 0; @@ -16203,7 +16203,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels, field_item->remove_item_direct_ref(), head_item->remove_item_direct_ref()); - if (!eq_item || eq_item->set_cmp_func()) + if (!eq_item || eq_item->set_cmp_func(thd)) return 0; eq_item->quick_fix_field(); } @@ -16621,7 +16621,7 @@ change_cond_ref_to_const(THD *thd, I_List *save_list, So make sure to use set_cmp_func() only for non-LIKE operators. */ if (functype != Item_func::LIKE_FUNC) - ((Item_bool_rowready_func2*) func)->set_cmp_func(); + ((Item_bool_rowready_func2*) func)->set_cmp_func(thd); } } else if (can_change_cond_ref_to_const(func, left_item, right_item, @@ -16646,7 +16646,7 @@ change_cond_ref_to_const(THD *thd, I_List *save_list, save_list->push_back(tmp2); } if (functype != Item_func::LIKE_FUNC) - ((Item_bool_rowready_func2*) func)->set_cmp_func(); + ((Item_bool_rowready_func2*) func)->set_cmp_func(thd); } } } diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 6bdc96ac401..e7058f6b4ed 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -5675,6 +5675,14 @@ Type_handler_string_result::Item_func_hybrid_field_type_get_date( /***************************************************************************/ +bool Type_handler::Item_bool_rowready_func2_fix_length_and_dec(THD *thd, + Item_bool_rowready_func2 *func) const +{ + return func->fix_length_and_dec_generic(thd, this); +} + +/***************************************************************************/ + bool Type_handler_numeric:: Item_func_between_fix_length_and_dec(Item_func_between *func) const { diff --git a/sql/sql_type.h b/sql/sql_type.h index aa89c8850af..ee3eb454ead 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -55,6 +55,7 @@ class Item_hybrid_func; class Item_func_min_max; class Item_func_hybrid_field_type; class Item_bool_func2; +class Item_bool_rowready_func2; class Item_func_between; class Item_func_in; class Item_func_round; @@ -3233,9 +3234,15 @@ public: bool agg_item_collations(DTCollation &c, const char *name, Item **items, uint nitems, uint flags, int item_sep); + struct Single_coll_err + { + const DTCollation& coll; + bool first; + }; bool agg_item_set_converter(const DTCollation &coll, const char *fname, Item **args, uint nargs, - uint flags, int item_sep); + uint flags, int item_sep, + const Single_coll_err *single_item_err= NULL); /* Collect arguments' character sets together. @@ -4232,6 +4239,8 @@ public: } virtual bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr, Item *a, Item *b) const= 0; + virtual bool Item_bool_rowready_func2_fix_length_and_dec(THD *thd, + Item_bool_rowready_func2 *func) const; virtual bool Item_hybrid_func_fix_attributes(THD *thd, const char *name, Type_handler_hybrid_field_type *, From 387b92df97e70680641ad0bcaed83b44373f13c5 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 28 Nov 2023 15:31:02 +0200 Subject: [PATCH 3/5] Remove deprication from mariadbd --debug --debug is supported by allmost all our other binaries and we should keep it also in the server to keep option names similar. --- mysql-test/suite/innodb/r/innodb-blob.result | 6 ------ mysql-test/suite/innodb/r/innodb-index-debug.result | 2 -- mysql-test/suite/innodb/r/innodb-table-online.result | 6 ------ mysql-test/suite/innodb/r/page_reorganize.result | 2 -- .../suite/innodb_fts/r/ft_result_cache_limit.result | 2 -- mysql-test/suite/innodb_gis/r/check_rtree.result | 2 -- mysql-test/suite/innodb_gis/r/rollback.result | 2 -- mysql-test/suite/innodb_gis/r/rtree_compress.result | 2 -- mysql-test/suite/innodb_gis/r/rtree_create_inplace.result | 2 -- mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result | 8 -------- mysql-test/suite/sys_vars/r/debug_basic.result | 2 -- mysql-test/suite/sys_vars/r/sysvars_debug.result | 2 +- sql/sys_vars.cc | 5 ++--- 13 files changed, 3 insertions(+), 40 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-blob.result b/mysql-test/suite/innodb/r/innodb-blob.result index fdfbfe3e683..bbb071ccb3e 100644 --- a/mysql-test/suite/innodb/r/innodb-blob.result +++ b/mysql-test/suite/innodb/r/innodb-blob.result @@ -20,8 +20,6 @@ a RIGHT(b,20) 2 bbbbbbbbbbbbbbbbbbbb connection default; SET DEBUG='+d,row_ins_extern_checkpoint'; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead SET DEBUG_SYNC='before_row_ins_extern_latch SIGNAL rec_not_blob WAIT_FOR crash'; ROLLBACK; BEGIN; @@ -88,8 +86,6 @@ BEGIN; INSERT INTO t2 VALUES (347); connection default; SET DEBUG='+d,row_upd_extern_checkpoint'; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead SET DEBUG_SYNC='before_row_upd_extern SIGNAL have_latch WAIT_FOR crash'; UPDATE t3 SET c=REPEAT('i',3000) WHERE a=2; connection con2; @@ -126,8 +122,6 @@ BEGIN; INSERT INTO t2 VALUES (33101); connection default; SET DEBUG='+d,row_upd_extern_checkpoint'; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead SET DEBUG_SYNC='after_row_upd_extern SIGNAL have_latch WAIT_FOR crash'; UPDATE t3 SET c=REPEAT('j',3000) WHERE a=2; connection con2; diff --git a/mysql-test/suite/innodb/r/innodb-index-debug.result b/mysql-test/suite/innodb/r/innodb-index-debug.result index bcd41392adb..8db3757dc95 100644 --- a/mysql-test/suite/innodb/r/innodb-index-debug.result +++ b/mysql-test/suite/innodb/r/innodb-index-debug.result @@ -88,8 +88,6 @@ ALTER TABLE t1 FORCE, ADD COLUMN k4 int; connection default; SET DEBUG_SYNC= 'now WAIT_FOR opened'; SET debug = '+d,row_log_tmpfile_fail'; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead INSERT INTO t1 select NULL,'aaa','bbb' from t480; INSERT INTO t1 select NULL,'aaaa','bbbb' from t480; SET DEBUG_SYNC= 'now SIGNAL flushed'; diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result index 8078daad633..8f71ea83b9c 100644 --- a/mysql-test/suite/innodb/r/innodb-table-online.result +++ b/mysql-test/suite/innodb/r/innodb-table-online.result @@ -40,16 +40,10 @@ SET DEBUG_DBUG = '+d,innodb_OOM_prepare_inplace_alter'; ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE; ERROR HY000: Out of memory. SET SESSION DEBUG = @saved_debug_dbug; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead SET SESSION DEBUG = '+d,innodb_OOM_inplace_alter'; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE; ERROR HY000: Out of memory. SET SESSION DEBUG = @saved_debug_dbug; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE; connection default; SHOW CREATE TABLE t1; diff --git a/mysql-test/suite/innodb/r/page_reorganize.result b/mysql-test/suite/innodb/r/page_reorganize.result index 20e1600bd0d..fe85926e2b8 100644 --- a/mysql-test/suite/innodb/r/page_reorganize.result +++ b/mysql-test/suite/innodb/r/page_reorganize.result @@ -16,8 +16,6 @@ SET @save_dbug = @@debug_dbug; SET DEBUG_DBUG = '+d,do_page_reorganize,do_lock_reverse_page_reorganize'; insert into t1(f2) values (repeat('+', 100)); SET DEBUG = @save_dbug; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead commit; connection con1; f1 diff --git a/mysql-test/suite/innodb_fts/r/ft_result_cache_limit.result b/mysql-test/suite/innodb_fts/r/ft_result_cache_limit.result index 2dbdd5a04bc..74d60410d58 100644 --- a/mysql-test/suite/innodb_fts/r/ft_result_cache_limit.result +++ b/mysql-test/suite/innodb_fts/r/ft_result_cache_limit.result @@ -20,8 +20,6 @@ END// CALL populate_t1; SET autocommit=1; SET SESSION debug="+d,fts_instrument_result_cache_limit"; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead ALTER TABLE t1 ADD FULLTEXT INDEX `text_content_idx` (`text_content`); SELECT FTS_DOC_ID, text_content FROM t1 diff --git a/mysql-test/suite/innodb_gis/r/check_rtree.result b/mysql-test/suite/innodb_gis/r/check_rtree.result index fe60a628fde..0d7b25b6b72 100644 --- a/mysql-test/suite/innodb_gis/r/check_rtree.result +++ b/mysql-test/suite/innodb_gis/r/check_rtree.result @@ -1,7 +1,5 @@ create table t1 (i int, g geometry not null, spatial index (g))engine=innodb; SET SESSION debug="+d,rtree_test_check_count"; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead insert into t1 values (1, POINT(1,1)); insert into t1 values (1, POINT(1.5,1.5)); insert into t1 values (1, POINT(3,3)); diff --git a/mysql-test/suite/innodb_gis/r/rollback.result b/mysql-test/suite/innodb_gis/r/rollback.result index 8688690b66a..9e0db79667e 100644 --- a/mysql-test/suite/innodb_gis/r/rollback.result +++ b/mysql-test/suite/innodb_gis/r/rollback.result @@ -408,8 +408,6 @@ update t1 set a=point(5,5), b=point(5,5), c=5 where i < 3; ERROR 23000: Duplicate entry '5' for key 'c' rollback; set session debug="+d,row_mysql_crash_if_error"; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead update t1 set a=point(5,5), b=point(5,5), c=5 where i < 3; ERROR HY000: Lost connection to MySQL server during query insert into t1 values(5, point(5,5), point(5,5), 5); diff --git a/mysql-test/suite/innodb_gis/r/rtree_compress.result b/mysql-test/suite/innodb_gis/r/rtree_compress.result index a88f8b9fa9b..360cf8ab5ef 100644 --- a/mysql-test/suite/innodb_gis/r/rtree_compress.result +++ b/mysql-test/suite/innodb_gis/r/rtree_compress.result @@ -42,8 +42,6 @@ count(*) 0 SET @saved_dbug = @@SESSION.debug_dbug; SET DEBUG='+d,page_copy_rec_list_start_compress_fail'; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead delete from t1; select count(*) from t1 where MBRWithin(t1.c2, @g1); count(*) diff --git a/mysql-test/suite/innodb_gis/r/rtree_create_inplace.result b/mysql-test/suite/innodb_gis/r/rtree_create_inplace.result index a8898f5c98f..5279eea8aa8 100644 --- a/mysql-test/suite/innodb_gis/r/rtree_create_inplace.result +++ b/mysql-test/suite/innodb_gis/r/rtree_create_inplace.result @@ -31,7 +31,5 @@ COUNT(*) 0 ALTER TABLE t1 DROP INDEX idx, ADD SPATIAL INDEX idx3(c2); SET SESSION debug="+d,row_merge_instrument_log_check_flush"; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead ALTER TABLE t1 DROP INDEX idx3, ADD SPATIAL INDEX idx4(c2), ADD SPATIAL INDEX idx5(c3); DROP TABLE t1; diff --git a/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result b/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result index 9607e8a7998..94ec9ceae86 100644 --- a/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result +++ b/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result @@ -266,16 +266,12 @@ Variable_name Value Rpl_semi_sync_master_clients 1 # Test failure of select error . SET GLOBAL debug = 'd,rpl_semisync_simulate_select_error'; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead INSERT INTO t1 VALUES(3); connection slave; connection con1; # Test failure of pthread_create SET GLOBAL rpl_semi_sync_master_enabled = 0; SET GLOBAL debug = 'd,rpl_semisync_simulate_create_thread_failure'; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead SET GLOBAL rpl_semi_sync_master_enabled= ON; # Test failure of pthread_join SET GLOBAL rpl_semi_sync_master_enabled= OFF; @@ -283,8 +279,6 @@ SET GLOBAL rpl_semi_sync_master_enabled= OFF; # Failure on registering semisync slave # SET GLOBAL debug= 'd,rpl_semisync_simulate_add_slave_failure'; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead SET GLOBAL rpl_semi_sync_master_enabled= ON; connection slave; STOP SLAVE IO_THREAD; @@ -293,8 +287,6 @@ START SLAVE IO_THREAD; include/wait_for_slave_io_to_start.inc connection con1; SET GLOBAL debug=''; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead connection slave; START SLAVE IO_THREAD; include/wait_for_slave_io_to_start.inc diff --git a/mysql-test/suite/sys_vars/r/debug_basic.result b/mysql-test/suite/sys_vars/r/debug_basic.result index a97ad65b40f..5a77446d036 100644 --- a/mysql-test/suite/sys_vars/r/debug_basic.result +++ b/mysql-test/suite/sys_vars/r/debug_basic.result @@ -1,6 +1,4 @@ set session debug="L"; -Warnings: -Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead select @@global.debug="1"; @@global.debug="1" 0 diff --git a/mysql-test/suite/sys_vars/r/sysvars_debug.result b/mysql-test/suite/sys_vars/r/sysvars_debug.result index 0d77b0211a1..c7357790e6b 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_debug.result +++ b/mysql-test/suite/sys_vars/r/sysvars_debug.result @@ -38,7 +38,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE VARIABLE_SCOPE SESSION VARIABLE_TYPE VARCHAR -VARIABLE_COMMENT Built-in DBUG debugger +VARIABLE_COMMENT Built-in DBUG debugger. Alias for --debug NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 081c489de53..cd5e87bc54c 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1002,11 +1002,10 @@ static Sys_var_charptr_fscs Sys_datadir( static Sys_var_dbug Sys_dbug( "debug", "Built-in DBUG debugger", sys_var::SESSION, CMD_LINE(OPT_ARG, '#'), DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG, - ON_CHECK(check_has_super), ON_UPDATE(0), - DEPRECATED("'@@debug_dbug'")); // since 5.5.37 + ON_CHECK(check_has_super)); static Sys_var_dbug Sys_debug_dbug( - "debug_dbug", "Built-in DBUG debugger", sys_var::SESSION, + "debug_dbug", "Built-in DBUG debugger. Alias for --debug", sys_var::SESSION, CMD_LINE(OPT_ARG, '#'), DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super)); #endif From 968061fd9c7a1c501badb5bc82a9b7c3c44b6f6f Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Mon, 27 Nov 2023 21:03:21 +0300 Subject: [PATCH 4/5] MDEV-28682 gcol.gcol_purge contaminates further execution of innodb.gap_locks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ha_innobase::extra() invokes check_trx_exists() unconditionally even for not supported operations. check_trx_exists() creates and registers trx_t object if THD does not contain pointer to it. If ha_innobase::extra() does not support some operation, it just invokes check_trx_exists() and quites. If check_trx_exists() creates and registers new trx_t object for such operation, it will never be freed and deregistered. For example, if ha_innobase::extra() is invoked from purge thread with operation = HA_EXTRA_IS_ATTACHED_CHILDREN, like it goes in gcol.gcol_purge test, trx_t object will be registered, but not deregisreted, and this causes innodb.gap_lock failure, as "SHOW ENGINE INNODB STATUS" shows information about unexpected transaction at the end of trx_sys.trx_list. The fix is not to invoke check_trx_exists() for unsupported operations in ha_innobase::extra(). Reviewed by: Marko Mäkelä --- storage/innobase/handler/ha_innodb.cc | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 58626c4667c..d955b63c817 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -15412,29 +15412,33 @@ ha_innobase::extra( enum ha_extra_function operation) /*!< in: HA_EXTRA_FLUSH or some other flag */ { - check_trx_exists(ha_thd()); - /* Warning: since it is not sure that MySQL calls external_lock before calling this function, the trx field in m_prebuilt can be obsolete! */ + trx_t *trx; switch (operation) { case HA_EXTRA_FLUSH: + (void)check_trx_exists(ha_thd()); if (m_prebuilt->blob_heap) { row_mysql_prebuilt_free_blob_heap(m_prebuilt); } break; case HA_EXTRA_RESET_STATE: + trx = check_trx_exists(ha_thd()); reset_template(); - thd_to_trx(ha_thd())->duplicates = 0; + trx->duplicates = 0; break; case HA_EXTRA_NO_KEYREAD: + (void)check_trx_exists(ha_thd()); m_prebuilt->read_just_key = 0; break; case HA_EXTRA_KEYREAD: + (void)check_trx_exists(ha_thd()); m_prebuilt->read_just_key = 1; break; case HA_EXTRA_KEYREAD_PRESERVE_FIELDS: + (void)check_trx_exists(ha_thd()); m_prebuilt->keep_other_fields_on_keyread = 1; break; @@ -15445,18 +15449,23 @@ ha_innobase::extra( either, because the calling threads may change. CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */ case HA_EXTRA_INSERT_WITH_UPDATE: - thd_to_trx(ha_thd())->duplicates |= TRX_DUP_IGNORE; + trx = check_trx_exists(ha_thd()); + trx->duplicates |= TRX_DUP_IGNORE; break; case HA_EXTRA_NO_IGNORE_DUP_KEY: - thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_IGNORE; + trx = check_trx_exists(ha_thd()); + trx->duplicates &= ~TRX_DUP_IGNORE; break; case HA_EXTRA_WRITE_CAN_REPLACE: - thd_to_trx(ha_thd())->duplicates |= TRX_DUP_REPLACE; + trx = check_trx_exists(ha_thd()); + trx->duplicates |= TRX_DUP_REPLACE; break; case HA_EXTRA_WRITE_CANNOT_REPLACE: - thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_REPLACE; + trx = check_trx_exists(ha_thd()); + trx->duplicates &= ~TRX_DUP_REPLACE; break; case HA_EXTRA_BEGIN_ALTER_COPY: + (void)check_trx_exists(ha_thd()); m_prebuilt->table->skip_alter_undo = 1; if (m_prebuilt->table->is_temporary() || !m_prebuilt->table->versioned_by_id()) { @@ -15470,6 +15479,7 @@ ha_innobase::extra( .first->second.set_versioned(0); break; case HA_EXTRA_END_ALTER_COPY: + (void)check_trx_exists(ha_thd()); m_prebuilt->table->skip_alter_undo = 0; break; default:/* Do nothing */ From 89a5a8d234832ef9ed5ee814e4db42c636fcde1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 30 Nov 2023 09:43:36 +0200 Subject: [PATCH 5/5] =?UTF-8?q?MDEV-32269=20InnoDB=20after=20ALTER=20TABLE?= =?UTF-8?q?=E2=80=A6IMPORT=20TABLESPACE=20may=20not=20be=20crash=20safe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mtr_t::commit(): If IMPORT TABLESPACE is first-time-dirtying blocks, acquire both log_sys.mutex and log_sys.flush_order_mutex to assign a valid m_commit_lsn so that the block will be inserted into the correct position of buf_pool.flush_list. This fixes occasional debug assertion failures when running the regression test suite. Reviewed by: Vladislav Lesin --- storage/innobase/mtr/mtr0mtr.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index b138dd13073..dd9036f9e08 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -453,10 +453,16 @@ void mtr_t::commit() { ut_ad(m_log_mode == MTR_LOG_NO_REDO); ut_ad(m_log.size() == 0); - m_commit_lsn= log_sys.get_lsn(); - lsns= { m_commit_lsn, PAGE_FLUSH_NO }; if (UNIV_UNLIKELY(m_made_dirty)) /* This should be IMPORT TABLESPACE */ + { + mysql_mutex_lock(&log_sys.mutex); + m_commit_lsn= log_sys.get_lsn(); mysql_mutex_lock(&log_sys.flush_order_mutex); + mysql_mutex_unlock(&log_sys.mutex); + } + else + m_commit_lsn= log_sys.get_lsn(); + lsns= { m_commit_lsn, PAGE_FLUSH_NO }; } if (m_freed_pages)