From b695495ea7ad57b2f2b4e7f73c179b7c3d056402 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Mon, 17 Jan 2011 15:44:37 +0800 Subject: [PATCH 01/10] BUG#57953 my_load_defaults return junk argument ----args-separator---- to caller After fix of bug#25192, load_defaults() will add an args separator to distinguish options loaded from configure files from that provided in the command line. One problem of this is that the args separator would be added no matter the application need it or not. Fixed the problem by adding an option: bool my_getopt_use_args_separator; to control whether the separator will be added or not. And also added functions: bool my_getopt_is_args_separator(const char* arg); to check if the argument is the separator or not. --- extra/my_print_defaults.c | 2 +- include/my_sys.h | 3 +- mysys/default.c | 59 +++++++++++++++++++++-------- mysys/my_getopt.c | 4 +- sql-common/client.c | 2 +- sql/mysqld.cc | 2 + storage/ndb/test/run-test/setup.cpp | 4 +- 7 files changed, 54 insertions(+), 22 deletions(-) diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c index 89fd4104c6f..25ec8beb59f 100644 --- a/extra/my_print_defaults.c +++ b/extra/my_print_defaults.c @@ -193,7 +193,7 @@ int main(int argc, char **argv) } for (argument= arguments+1 ; *argument ; argument++) - if (*argument != args_separator) /* skip arguments separator */ + if (!my_getopt_is_args_separator(*argument)) /* skip arguments separator */ puts(*argument); my_free(load_default_groups); free_defaults(arguments); diff --git a/include/my_sys.h b/include/my_sys.h index 96b40415c56..484dc684b03 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -817,7 +817,8 @@ extern void *memdup_root(MEM_ROOT *root,const void *str, size_t len); extern int get_defaults_options(int argc, char **argv, char **defaults, char **extra_defaults, char **group_suffix); -extern const char *args_separator; +extern my_bool my_getopt_use_args_separator; +extern my_bool my_getopt_is_args_separator(const char* arg); extern int my_load_defaults(const char *conf_file, const char **groups, int *argc, char ***argv, const char ***); extern int load_defaults(const char *conf_file, const char **groups, diff --git a/mysys/default.c b/mysys/default.c index 75eb4709e1e..432c3086254 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -61,9 +61,23 @@ check the pointer, use "----args-separator----" here to ease debug if someone misused it. + The args seprator will only be added when + my_getopt_use_args_seprator is set to TRUE before calling + load_defaults(); + See BUG#25192 */ -const char *args_separator= "----args-separator----"; +static const char *args_separator= "----args-separator----"; +inline static void set_args_separator(char** arg) +{ + DBUG_ASSERT(my_getopt_use_args_separator); + *arg= (char*)args_separator; +} +my_bool my_getopt_use_args_separator= FALSE; +my_bool my_getopt_is_args_separator(const char* arg) +{ + return (arg == args_separator); +} const char *my_defaults_file=0; const char *my_defaults_group_suffix=0; const char *my_defaults_extra_file=0; @@ -503,6 +517,7 @@ int my_load_defaults(const char *conf_file, const char **groups, char *ptr,**res; struct handle_option_ctx ctx; const char **dirs; + uint args_sep= my_getopt_use_args_separator ? 1 : 0; DBUG_ENTER("load_defaults"); init_alloc_root(&alloc,512,0); @@ -515,17 +530,28 @@ int my_load_defaults(const char *conf_file, const char **groups, if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults")) { /* remove the --no-defaults argument and return only the other arguments */ - uint i; + uint i, j; if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+ (*argc + 1)*sizeof(char*)))) goto err; res= (char**) (ptr+sizeof(alloc)); res[0]= **argv; /* Copy program name */ - /* set arguments separator */ - res[1]= (char *)args_separator; - for (i=2 ; i < (uint) *argc ; i++) - res[i]=argv[0][i]; - res[i]=0; /* End pointer */ + j= 1; /* Start from 1 for the reset result args */ + if (my_getopt_use_args_separator) + { + /* set arguments separator */ + set_args_separator(&res[1]); + j++; + } + for (i=2 ; i < (uint) *argc ; i++, j++) + res[j]=argv[0][i]; + res[j]=0; /* End pointer */ + /* + Update the argc, if have not added args separator, then we have + to decrease argc because we have removed the "--no-defaults". + */ + if (!my_getopt_use_args_separator) + (*argc)--; *argv=res; *(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */ if (default_directories) @@ -559,7 +585,7 @@ int my_load_defaults(const char *conf_file, const char **groups, or a forced default file */ if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+ - (args.elements + *argc + 1 + 1) *sizeof(char*)))) + (args.elements + *argc + 1 + args_sep) *sizeof(char*)))) goto err; res= (char**) (ptr+sizeof(alloc)); @@ -580,16 +606,19 @@ int my_load_defaults(const char *conf_file, const char **groups, --*argc; ++*argv; /* skip argument */ } - /* set arguments separator for arguments from config file and - command line */ - res[args.elements+1]= (char *)args_separator; + if (my_getopt_use_args_separator) + { + /* set arguments separator for arguments from config file and + command line */ + set_args_separator(&res[args.elements+1]); + } if (*argc) - memcpy((uchar*) (res+1+args.elements+1), (char*) ((*argv)+1), + memcpy((uchar*) (res+1+args.elements+args_sep), (char*) ((*argv)+1), (*argc-1)*sizeof(char*)); - res[args.elements+ *argc+1]=0; /* last null */ + res[args.elements+ *argc+args_sep]=0; /* last null */ - (*argc)+=args.elements+1; + (*argc)+=args.elements+args_sep; *argv= (char**) res; *(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */ delete_dynamic(&args); @@ -599,7 +628,7 @@ int my_load_defaults(const char *conf_file, const char **groups, printf("%s would have been started with the following arguments:\n", **argv); for (i=1 ; i < *argc ; i++) - if ((*argv)[i] != args_separator) /* skip arguments separator */ + if (!my_getopt_is_args_separator((*argv)[i])) /* skip arguments separator */ printf("%s ", (*argv)[i]); puts(""); exit(0); diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index efa7e0bb1b3..6f7ed070ccf 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -176,7 +176,7 @@ int handle_options(int *argc, char ***argv, */ for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++) { - if (*pos == args_separator) + if (my_getopt_is_args_separator(*pos)) { is_cmdline_arg= 0; break; @@ -188,7 +188,7 @@ int handle_options(int *argc, char ***argv, char **first= pos; char *cur_arg= *pos; opt_found= 0; - if (!is_cmdline_arg && (cur_arg == args_separator)) + if (!is_cmdline_arg && (my_getopt_is_args_separator(cur_arg))) { is_cmdline_arg= 1; diff --git a/sql-common/client.c b/sql-common/client.c index 354c04b717b..3b7fc11a537 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1207,7 +1207,7 @@ void mysql_read_default_options(struct st_mysql_options *options, char **option=argv; while (*++option) { - if (option[0] == args_separator) /* skip arguments separator */ + if (my_getopt_is_args_separator(option[0])) /* skip arguments separator */ continue; /* DBUG_PRINT("info",("option: %s",option[0])); */ if (option[0][0] == '-' && option[0][1] == '-') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d670a076ecd..188ed7c6885 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4207,8 +4207,10 @@ int mysqld_main(int argc, char **argv) orig_argc= argc; orig_argv= argv; + my_getopt_use_args_separator= TRUE; if (load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv)) return 1; + my_getopt_use_args_separator= FALSE; defaults_argc= argc; defaults_argv= argv; remaining_argc= argc; diff --git a/storage/ndb/test/run-test/setup.cpp b/storage/ndb/test/run-test/setup.cpp index 60f8285888c..fc30c998865 100644 --- a/storage/ndb/test/run-test/setup.cpp +++ b/storage/ndb/test/run-test/setup.cpp @@ -105,7 +105,7 @@ setup_config(atrt_config& config) */ for (j = 0; j<(size_t)argc; j++) { - if (tmp[j] == args_separator) /* skip arguments separator */ + if (my_getopt_is_args_separator(tmp[j])) /* skip arguments separator */ continue; for (k = 0; proc_args[k].name; k++) { @@ -375,7 +375,7 @@ load_options(int argc, char** argv, int type, atrt_options& opts) * Skip the separator for arguments from config file and command * line */ - if (argv[i] == args_separator) + if (my_getopt_is_args_separator(argv[i])) continue; for (size_t j = 0; f_options[j].name; j++) { From 732359712230a38c6c87eece8d3ba2b34e3298f0 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Tue, 4 Jan 2011 11:23:45 +0100 Subject: [PATCH 02/10] Bug #58991 DEFAULT_CHARSET and DEFAULT_COLLATION does not work with CMake. --- cmake/character_sets.cmake | 14 ++++++++------ config.h.cmake | 9 ++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/cmake/character_sets.cmake b/cmake/character_sets.cmake index d51444ec433..1cf63ed1462 100644 --- a/cmake/character_sets.cmake +++ b/cmake/character_sets.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2009 Sun Microsystems, Inc +# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -13,17 +13,19 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#Charsets and collations +# Charsets and collations IF(NOT DEFAULT_CHARSET) -SET(DEFAULT_CHARSET "latin1") + SET(DEFAULT_CHARSET "latin1") ENDIF() -IF(NOT DEFAULT_COLLATIONS) -SET(DEFAULT_COLLATION "latin1_swedish_ci") +IF(NOT DEFAULT_COLLATION) + SET(DEFAULT_COLLATION "latin1_swedish_ci") ENDIF() SET(CHARSETS ${DEFAULT_CHARSET} latin1 utf8 utf8mb4) -SET(CHARSETS_COMPLEX big5 cp1250 cp932 eucjpms euckr gb2312 gbk latin1 latin2 sjis tis620 ucs2 ujis utf8 utf8mb4 utf16 utf32) +SET(CHARSETS_COMPLEX + big5 cp1250 cp932 eucjpms euckr gb2312 gbk latin1 latin2 + sjis tis620 ucs2 ujis utf8 utf8mb4 utf16 utf32) SET(CHARSETS_AVAILABLE binary armscii8 ascii big5 cp1250 cp1251 cp1256 cp1257 diff --git a/config.h.cmake b/config.h.cmake index 204e1032410..65ebd077da6 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -1,6 +1,5 @@ -/* Copyright (C) 2009, 2011, Oracle and/or its affiliates. All rights - reserved - +/* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. @@ -516,8 +515,8 @@ #cmakedefine CYBOZU 1 /* Character sets and collations */ -#cmakedefine MYSQL_DEFAULT_CHARSET_NAME "latin1" -#cmakedefine MYSQL_DEFAULT_COLLATION_NAME "latin1_swedish_ci" +#cmakedefine MYSQL_DEFAULT_CHARSET_NAME "@MYSQL_DEFAULT_CHARSET_NAME@" +#cmakedefine MYSQL_DEFAULT_COLLATION_NAME "@MYSQL_DEFAULT_COLLATION_NAME@" #cmakedefine USE_MB 1 #cmakedefine USE_MB_IDENT 1 From 1c9515f61689e1e5c6d8622e8843552b3afa3ce1 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 17 Jan 2011 12:30:22 +0300 Subject: [PATCH 03/10] Bug#59149 valgrind warnings with "like .. escape .." function Problem: when processing a query like: SELECT '' LIKE '1' ESCAPE COUNT(1); escape_item->val_str() was never executed and the "escape" class member stayed initialized, which led to valgrind uninitialized memory error. Note, a query with some tables in "FROM" clause returns ER_WRONG_ARGUMENTS in the same situation: SELECT '' LIKE '1' ESCAPE COUNT(1) FROM t1; ERROR 1210 (HY000): Incorrect arguments to ESCAPE Fix: disallowing using aggregate functions in ESCAPE clause, even if there are no tables used. There is no much use of that anyway. --- mysql-test/r/func_like.result | 5 +++++ mysql-test/t/func_like.test | 5 +++++ sql/item_sum.h | 1 + 3 files changed, 11 insertions(+) diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result index 21da211160b..76174982e8e 100644 --- a/mysql-test/r/func_like.result +++ b/mysql-test/r/func_like.result @@ -182,4 +182,9 @@ INSERT INTO t2 VALUES (1), (2), (3); SELECT 1 FROM t2 JOIN t1 ON 1 LIKE a GROUP BY a; 1 DROP TABLE t1, t2; +# +# Bug#59149 valgrind warnings with "like .. escape .." function +# +SELECT '' LIKE '1' ESCAPE COUNT(1); +ERROR HY000: Incorrect arguments to ESCAPE End of 5.1 tests diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test index 1204d04d9a0..f1fe52274b2 100644 --- a/mysql-test/t/func_like.test +++ b/mysql-test/t/func_like.test @@ -126,5 +126,10 @@ INSERT INTO t2 VALUES (1), (2), (3); SELECT 1 FROM t2 JOIN t1 ON 1 LIKE a GROUP BY a; DROP TABLE t1, t2; +--echo # +--echo # Bug#59149 valgrind warnings with "like .. escape .." function +--echo # +--error ER_WRONG_ARGUMENTS +SELECT '' LIKE '1' ESCAPE COUNT(1); --echo End of 5.1 tests diff --git a/sql/item_sum.h b/sql/item_sum.h index de988c196ec..f8819d63bf4 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -339,6 +339,7 @@ public: forced_const= TRUE; } virtual bool const_item() const { return forced_const; } + virtual bool const_during_execution() const { return false; } virtual void print(String *str, enum_query_type query_type); void fix_num_length_and_dec(); From 18e4f23a8809a8dbeee7cf225b958991a476d1b5 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 17 Jan 2011 15:11:33 +0300 Subject: [PATCH 04/10] Bug#58371 Assertion failed: !s.uses_buffer_owned_by(this) with format string function Introduced by the fix for bug#44766. Problem: it's not correct to use args[0]->str_value as a buffer, because args[0] may need this buffer for its own purposes. Fix: adding a new class member tmp_value to use as return value. @ mysql-test/r/ctype_many.result @ mysql-test/t/ctype_many.test Adding tests @ sql/item_strfunc.cc Changing code into traditional style: use "str" as a buffer for the argument and tmp_value for the result value. @ sql/item_strfunc.h Adding tmp_value --- mysql-test/r/ctype_many.result | 15 +++++++++++++++ mysql-test/t/ctype_many.test | 16 ++++++++++++++++ sql/item_strfunc.cc | 12 +++--------- sql/item_strfunc.h | 1 + 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/ctype_many.result b/mysql-test/r/ctype_many.result index 89e05bf4484..dbec746cdae 100644 --- a/mysql-test/r/ctype_many.result +++ b/mysql-test/r/ctype_many.result @@ -1683,3 +1683,18 @@ ARMENIAN CAPIT DA 2 ARMENIAN CAPIT ECH 2 ARMENIAN CAPIT ZA 2 DROP TABLE t1; +# +# Start of 5.1 tests +# +# +# Bug#58371 Assertion failed: !s.uses_buffer_owned_by(this) with format string function +# +SET NAMES latin1; +DO CONVERT(CAST(SUBSTRING_INDEX(FORMAT(1,'1111'), FORMAT('','Zpq'),1) +AS BINARY(0)) USING utf8); +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'Zpq' +Warning 1292 Truncated incorrect BINARY(0) value: '1.' +# +# End of 5.1 tests +# diff --git a/mysql-test/t/ctype_many.test b/mysql-test/t/ctype_many.test index 0903c3dd7fa..84048761228 100644 --- a/mysql-test/t/ctype_many.test +++ b/mysql-test/t/ctype_many.test @@ -211,3 +211,19 @@ SELECT min(comment),count(*) FROM t1 GROUP BY ucs2_f; DROP TABLE t1; # End of 4.1 tests + + +--echo # +--echo # Start of 5.1 tests +--echo # + +--echo # +--echo # Bug#58371 Assertion failed: !s.uses_buffer_owned_by(this) with format string function +--echo # + +SET NAMES latin1; +DO CONVERT(CAST(SUBSTRING_INDEX(FORMAT(1,'1111'), FORMAT('','Zpq'),1) + AS BINARY(0)) USING utf8); +--echo # +--echo # End of 5.1 tests +--echo # diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 204a2dfc663..c637c9c29b8 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2761,22 +2761,16 @@ String *Item_func_conv_charset::val_str(String *str) DBUG_ASSERT(fixed == 1); if (use_cached_value) return null_value ? 0 : &str_value; - /* - Here we don't pass 'str' as a parameter to args[0]->val_str() - as 'str' may point to 'str_value' (e.g. see Item::save_in_field()), - which we use below to convert string. - Use argument's 'str_value' instead. - */ - String *arg= args[0]->val_str(&args[0]->str_value); + String *arg= args[0]->val_str(str); uint dummy_errors; if (!arg) { null_value=1; return 0; } - null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(), + null_value= tmp_value.copy(arg->ptr(), arg->length(), arg->charset(), conv_charset, &dummy_errors); - return null_value ? 0 : check_well_formed_result(&str_value); + return null_value ? 0 : check_well_formed_result(&tmp_value); } void Item_func_conv_charset::fix_length_and_dec() diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 6645a4c637a..408062ddc08 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -713,6 +713,7 @@ public: class Item_func_conv_charset :public Item_str_func { bool use_cached_value; + String tmp_value; public: bool safe; CHARSET_INFO *conv_charset; // keep it public From f6e9720f3c7204b7a755109c5d3f08e3a919bec2 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Mon, 17 Jan 2011 18:51:01 +0000 Subject: [PATCH 05/10] BUG#42879: CHANGE MASTER RELAY_LOG_FILE=path fails on windows Re-enabling the test case on windows since BUG#12190 has fixed the issue. --- mysql-test/suite/rpl/t/rpl_cross_version.test | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mysql-test/suite/rpl/t/rpl_cross_version.test b/mysql-test/suite/rpl/t/rpl_cross_version.test index 7a8cbfd8237..94c9f0432ce 100644 --- a/mysql-test/suite/rpl/t/rpl_cross_version.test +++ b/mysql-test/suite/rpl/t/rpl_cross_version.test @@ -12,11 +12,6 @@ --source include/master-slave.inc -# The test is disabled for windows due to -# Bug #42879 CHANGE MASTER RELAY_LOG_FILE=path fails on windows -# Todo: release it from not_windows ---source include/not_windows.inc - # # Bug#31240 load data infile replication between (4.0 or 4.1) and 5.1 fails # From f25ab9fe22cd7823a65fd186aa0e6d4d2ea9be91 Mon Sep 17 00:00:00 2001 From: Vinay Fisrekar Date: Tue, 18 Jan 2011 09:24:52 +0530 Subject: [PATCH 06/10] BUG#58858 : sys_vars.innodb_max_dirty_pages_pct_func fails sporadically Committing After latest merge. Modified check_pct procedure to check return value of wait condition instead of calling "dirty_pct". Adding Review comments: 1) Added comment for success variable value 2) Procedure check_pct changed For Adding BOOLEAN input and SELECT QUERY Change --- .../sys_vars/r/innodb_max_dirty_pages_pct_func.result | 8 ++++---- .../sys_vars/t/innodb_max_dirty_pages_pct_func.test | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result index baf06092126..55de5adbc33 100644 --- a/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result +++ b/mysql-test/suite/sys_vars/r/innodb_max_dirty_pages_pct_func.result @@ -64,12 +64,12 @@ SET last = pct; END IF; END WHILE; END// -CREATE PROCEDURE check_pct(IN num DECIMAL) +CREATE PROCEDURE check_pct(IN success_on_wait BOOLEAN) BEGIN -IF (dirty_pct() < num) THEN +IF (success_on_wait > 0) THEN SELECT 'BELOW_MAX' AS PCT_VALUE; ELSE -SELECT 'ABOVE_MAX' AS PCT_VALUE; +SELECT 'ABOVE_MAX or TimeOut Of The Test' AS PCT_VALUE; END IF; END// CREATE TABLE t1( @@ -83,7 +83,7 @@ CALL add_until(10); FLUSH TABLES; CALL add_records(500); 'We expect dirty pages pct to be BELOW_MAX after some time depending on performance' -CALL check_pct(10); +CALL check_pct(1); PCT_VALUE BELOW_MAX DROP PROCEDURE add_records; diff --git a/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_func.test b/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_func.test index b577ae5fcc4..c7a9e567e69 100644 --- a/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_func.test +++ b/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_func.test @@ -117,12 +117,12 @@ BEGIN END WHILE; END// -CREATE PROCEDURE check_pct(IN num DECIMAL) +CREATE PROCEDURE check_pct(IN success_on_wait BOOLEAN) BEGIN - IF (dirty_pct() < num) THEN + IF (success_on_wait > 0) THEN SELECT 'BELOW_MAX' AS PCT_VALUE; ELSE - SELECT 'ABOVE_MAX' AS PCT_VALUE; + SELECT 'ABOVE_MAX or TimeOut Of The Test' AS PCT_VALUE; END IF; END// @@ -155,7 +155,8 @@ let $wait_condition= SELECT (dirty_pct() <= @@global.innodb_max_dirty_pages_pct) --source include/wait_condition.inc --echo 'We expect dirty pages pct to be BELOW_MAX after some time depending on performance' -CALL check_pct(10); +# Value For $sucess will be set from include/wait_condition.inc file. It can have values 1 or 0. It will be 1 if dirty_pct() <= @@global.innodb_max_dirty_pages_pct else it will be 0. +eval CALL check_pct($success); DROP PROCEDURE add_records; DROP PROCEDURE add_until; DROP PROCEDURE check_pct; From cf0e22fe757c817d58ff2f403dd9718a51561fd0 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 18 Jan 2011 09:38:41 +0300 Subject: [PATCH 07/10] Bug#44332 my_xml_scan reads behind the end of buffer Problem: the scanner function tested for strings "" without checking input string boundaries, which led to valgrind's "Conditional jump or move depends on uninitialised value(s)" error. Fix: Adding boundary checking. @ mysql-test/r/xml.result @ mysql-test/t/xml.test Adding test @ strings/xml.c Adding a helper function my_xml_parser_prefix_cmp(), with input string boundary check. --- mysql-test/r/xml.result | 11 +++++++++++ mysql-test/t/xml.test | 5 +++++ strings/xml.c | 23 +++++++++++++++++------ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result index 92f84381415..0a71a596505 100644 --- a/mysql-test/r/xml.result +++ b/mysql-test/r/xml.result @@ -1113,4 +1113,15 @@ SELECT UPDATEXML(NULL, (LPAD(0.1111E-15, '2011', 1)), 1); ERROR 22007: Illegal double '111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111' value found during parsing SELECT EXTRACTVALUE('', LPAD(0.1111E-15, '2011', 1)); ERROR 22007: Illegal double '111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111' value found during parsing +# +# Bug #44332 my_xml_scan reads behind the end of buffer +# +SELECT UPDATEXML(CONVERT(_latin1'<' USING utf8),'1','1'); +UPDATEXML(CONVERT(_latin1'<' USING utf8),'1','1') +NULL +Warnings: +Warning 1525 Incorrect XML value: 'parse error at line 1 pos 2: END-OF-INPUT unexpected (ident or '/' wanted)' +SELECT UPDATEXML(CONVERT(_latin1'", 3); p->cur++) - {} - if (!memcmp(p->cur, "-->", 3)) - p->cur+=3; + for (; p->cur < p->end; p->cur++) + { + if (!my_xml_parser_prefix_cmp(p, C_STRING_WITH_LEN("-->"))) + { + p->cur+= 3; + break; + } + } a->end=p->cur; lex=MY_XML_COMMENT; } - else if (!memcmp(p->cur, "cur+= 9; for (; p->cur < p->end - 2 ; p->cur++) From 634b102533d948f669f0291374664ce4e8780d49 Mon Sep 17 00:00:00 2001 From: "John H. Embretsen" Date: Tue, 18 Jan 2011 13:04:17 +0100 Subject: [PATCH 08/10] Post push test fix for show_check.test. Fix for bug#45740 introduced test case using SHOW TABLE STATUS against a Memory table using latin1 character in table name. The test failed on Windows and FreeBSD due to a difference in the value for Avg_row_length. The average row length normally depends on the values for data length and row count. According to the 5.5 manual data length is approximate with Memory tables. With MyISAM and InnoDB the Avg_row_length is the same on Windows and Solaris. The solution implemented by this patch is to mask out the value for Avg_row_length, as it may vary when using Memory tables. --- mysql-test/r/show_check.result | 2 +- mysql-test/t/show_check.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 9cb57b06c38..feeba25c536 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1334,7 +1334,7 @@ CREATE DATABASE ` CREATE TABLE `ä`.`ä` (a int) ENGINE=Memory; SHOW TABLE STATUS FROM `ä` LIKE 'ä'; 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 -ä MEMORY 10 Fixed 0 8 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +ä MEMORY 10 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL DROP DATABASE `ä`; show columns from `#mysql50#????????`; Got one of the listed errors diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 14e29722409..a334a5f7791 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -1073,7 +1073,7 @@ set names latin1; SET NAMES latin1; CREATE DATABASE `ä`; CREATE TABLE `ä`.`ä` (a int) ENGINE=Memory; ---replace_column 7 # 8 # 9 # +--replace_column 6 # 7 # 8 # 9 # SHOW TABLE STATUS FROM `ä` LIKE 'ä'; DROP DATABASE `ä`; From 5d75729c928338c2b49752b9b271ff7eb9a261ec Mon Sep 17 00:00:00 2001 From: Libing Song Date: Wed, 19 Jan 2011 01:23:49 +0800 Subject: [PATCH 09/10] Bug#58546 test rpl_packet timeout failure sporadically on PB rpl_packet got a timeout failure sporadically on PB when stopping slave. The real reason of this bug is that STOP SLAVE stopped IO thread first and then stopped SQL thread. It was possible that IO thread stopped after replicating part of a transaction which SQL thread was executing. SQL thread would be hung if the transaction could not be rolled back safely. After this patch, STOP SLAVE will stop SQL thread first and then stop IO thread, which guarantees that IO thread will fetch the reset of the events of the transaction that SQL thread is executing, so that SQL thread can finish the transaction if it cannot be rolled back safely. Added below auxiliary files to make the test code neater. restart_slave_sql.inc rpl_connection_master.inc rpl_connection_slave.inc rpl_connection_slave1.inc --- mysql-test/include/restart_slave_sql.inc | 43 +++++++++++++ mysql-test/include/rpl_connection_master.inc | 2 + mysql-test/include/rpl_connection_slave.inc | 2 + mysql-test/include/rpl_connection_slave1.inc | 2 + mysql-test/suite/rpl/r/rpl_stop_slave.result | 42 +++++++++++++ mysql-test/suite/rpl/t/rpl_packet.test | 2 +- mysql-test/suite/rpl/t/rpl_stop_slave.test | 64 +++++++++++++++++++- sql/slave.cc | 22 +++---- sql/sql_repl.cc | 23 +++++++ 9 files changed, 189 insertions(+), 13 deletions(-) create mode 100644 mysql-test/include/restart_slave_sql.inc create mode 100644 mysql-test/include/rpl_connection_master.inc create mode 100644 mysql-test/include/rpl_connection_slave.inc create mode 100644 mysql-test/include/rpl_connection_slave1.inc diff --git a/mysql-test/include/restart_slave_sql.inc b/mysql-test/include/restart_slave_sql.inc new file mode 100644 index 00000000000..ee6c6d7ced6 --- /dev/null +++ b/mysql-test/include/restart_slave_sql.inc @@ -0,0 +1,43 @@ +# ==== Purpose ==== +# +# Provide a earier way to restart SQL thread when you want to stop sql thread +# and then start it immediately. +# +# Sources stop_slave_sql.inc to stop SQL thread on the current connection. +# Then issues START SLAVE SQL_THREAD and then waits until +# the SQL threads have started, or until a timeout is reached. +# +# Please use this instead of 'STOP|START SLAVE SQL_THREAD', to reduce the risk of +# test case bugs. +# +# +# ==== Usage ==== +# +# [--let $slave_timeout= NUMBER] +# [--let $rpl_debug= 1] +# --source include/restart_slave_sql.inc +# +# Parameters: +# $slave_timeout +# See include/wait_for_slave_param.inc +# +# $rpl_debug +# See include/rpl_init.inc + + +--let $include_filename= restart_slave.inc +--source include/begin_include_file.inc + + +if (!$rpl_debug) +{ + --disable_query_log +} + +source include/stop_slave_sql.inc; +START SLAVE SQL_THREAD; +source include/wait_for_slave_sql_to_start.inc; + + +--let $include_filename= restart_slave.inc +--source include/end_include_file.inc \ No newline at end of file diff --git a/mysql-test/include/rpl_connection_master.inc b/mysql-test/include/rpl_connection_master.inc new file mode 100644 index 00000000000..e54e34071c8 --- /dev/null +++ b/mysql-test/include/rpl_connection_master.inc @@ -0,0 +1,2 @@ +let $rpl_connection_name= master; +source include/rpl_connection.inc; \ No newline at end of file diff --git a/mysql-test/include/rpl_connection_slave.inc b/mysql-test/include/rpl_connection_slave.inc new file mode 100644 index 00000000000..ef3876394d6 --- /dev/null +++ b/mysql-test/include/rpl_connection_slave.inc @@ -0,0 +1,2 @@ +let $rpl_connection_name= slave; +source include/rpl_connection.inc; \ No newline at end of file diff --git a/mysql-test/include/rpl_connection_slave1.inc b/mysql-test/include/rpl_connection_slave1.inc new file mode 100644 index 00000000000..8aee6defbdd --- /dev/null +++ b/mysql-test/include/rpl_connection_slave1.inc @@ -0,0 +1,2 @@ +let $rpl_connection_name= slave1; +source include/rpl_connection.inc; \ No newline at end of file diff --git a/mysql-test/suite/rpl/r/rpl_stop_slave.result b/mysql-test/suite/rpl/r/rpl_stop_slave.result index 2e9522e8947..ff0061f264b 100644 --- a/mysql-test/suite/rpl/r/rpl_stop_slave.result +++ b/mysql-test/suite/rpl/r/rpl_stop_slave.result @@ -128,5 +128,47 @@ START SLAVE SQL_THREAD; include/wait_for_slave_sql_to_start.inc # Test end SET GLOBAL debug= '$debug_save'; +include/restart_slave.inc +[connection master] DROP TABLE t1, t2; + +# Bug#58546 test rpl_packet timeout failure sporadically on PB +# ---------------------------------------------------------------------- +# STOP SLAVE stopped IO thread first and then stopped SQL thread. It was +# possible that IO thread stopped after replicating part of a transaction +# which SQL thread was executing. SQL thread would be hung if the +# transaction could not be rolled back safely. +# It caused some sporadic failures on PB2. +# +# This test verifies that when 'STOP SLAVE' is issued by a user, IO +# thread will continue to fetch the rest events of the transaction which +# is being executed by SQL thread and is not able to be rolled back safely. +CREATE TABLE t1 (c1 INT KEY, c2 INT) ENGINE=InnoDB; +CREATE TABLE t2 (c1 INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES(1, 1); +SET GLOBAL debug= 'd,dump_thread_wait_before_send_xid'; +[connection slave] +include/restart_slave.inc +BEGIN; +UPDATE t1 SET c2 = 2 WHERE c1 = 1; +[connection master] +BEGIN; +INSERT INTO t1 VALUES(2, 2); +INSERT INTO t2 VALUES(1); +UPDATE t1 SET c2 = 3 WHERE c1 = 1; +COMMIT; +[connection slave1] +STOP SLAVE; +[connection slave] +ROLLBACK; +[connection master] +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; +[connection slave] +include/wait_for_slave_to_stop.inc +[connection slave1] +include/start_slave.inc +[connection master] +DROP TABLE t1, t2; +SET GLOBAL debug= $debug_save; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_packet.test b/mysql-test/suite/rpl/t/rpl_packet.test index b11bd0a227e..3197b6160cd 100644 --- a/mysql-test/suite/rpl/t/rpl_packet.test +++ b/mysql-test/suite/rpl/t/rpl_packet.test @@ -26,8 +26,8 @@ let $old_net_buffer_length= `SELECT @@global.net_buffer_length`; SET @@global.max_allowed_packet=1024; SET @@global.net_buffer_length=1024; +sync_slave_with_master; # Restart slave for setting to take effect -connection slave; source include/stop_slave.inc; source include/start_slave.inc; diff --git a/mysql-test/suite/rpl/t/rpl_stop_slave.test b/mysql-test/suite/rpl/t/rpl_stop_slave.test index e7c67448dbe..e44b2f15f25 100644 --- a/mysql-test/suite/rpl/t/rpl_stop_slave.test +++ b/mysql-test/suite/rpl/t/rpl_stop_slave.test @@ -54,7 +54,69 @@ source extra/rpl_tests/rpl_stop_slave.test; --echo # Test end SET GLOBAL debug= '$debug_save'; +source include/restart_slave_sql.inc; -connection master; +--source include/rpl_connection_master.inc DROP TABLE t1, t2; + +--echo +--echo # Bug#58546 test rpl_packet timeout failure sporadically on PB +--echo # ---------------------------------------------------------------------- +--echo # STOP SLAVE stopped IO thread first and then stopped SQL thread. It was +--echo # possible that IO thread stopped after replicating part of a transaction +--echo # which SQL thread was executing. SQL thread would be hung if the +--echo # transaction could not be rolled back safely. +--echo # It caused some sporadic failures on PB2. +--echo # +--echo # This test verifies that when 'STOP SLAVE' is issued by a user, IO +--echo # thread will continue to fetch the rest events of the transaction which +--echo # is being executed by SQL thread and is not able to be rolled back safely. + +CREATE TABLE t1 (c1 INT KEY, c2 INT) ENGINE=InnoDB; +CREATE TABLE t2 (c1 INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES(1, 1); + +let $debug_save= `SELECT @@GLOBAL.debug`; +SET GLOBAL debug= 'd,dump_thread_wait_before_send_xid'; + +sync_slave_with_master; + +--source include/rpl_connection_slave.inc +source include/restart_slave_sql.inc; + +BEGIN; +UPDATE t1 SET c2 = 2 WHERE c1 = 1; + +--source include/rpl_connection_master.inc +BEGIN; +INSERT INTO t1 VALUES(2, 2); +INSERT INTO t2 VALUES(1); +UPDATE t1 SET c2 = 3 WHERE c1 = 1; +COMMIT; + +--source include/rpl_connection_slave1.inc +let $show_statement= SHOW PROCESSLIST; +let $field= Info; +let $condition= = 'UPDATE t1 SET c2 = 3 WHERE c1 = 1'; +source include/wait_show_condition.inc; + +send STOP SLAVE; + +--source include/rpl_connection_slave.inc +ROLLBACK; + +--source include/rpl_connection_master.inc +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'RESET'; + +--source include/rpl_connection_slave.inc +source include/wait_for_slave_to_stop.inc; + +--source include/rpl_connection_slave1.inc +reap; +source include/start_slave.inc; + +--source include/rpl_connection_master.inc +DROP TABLE t1, t2; +SET GLOBAL debug= $debug_save; --source include/rpl_end.inc diff --git a/sql/slave.cc b/sql/slave.cc index 96319de5427..0e74d0ce3c0 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -408,17 +408,6 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock) int error,force_all = (thread_mask & SLAVE_FORCE_ALL); pthread_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock; - if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) - { - DBUG_PRINT("info",("Terminating IO thread")); - mi->abort_slave=1; - if ((error=terminate_slave_thread(mi->io_thd, io_lock, - &mi->stop_cond, - &mi->slave_running, - skip_lock)) && - !force_all) - DBUG_RETURN(error); - } if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL)) { DBUG_PRINT("info",("Terminating SQL thread")); @@ -430,6 +419,17 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock) !force_all) DBUG_RETURN(error); } + if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) + { + DBUG_PRINT("info",("Terminating IO thread")); + mi->abort_slave=1; + if ((error=terminate_slave_thread(mi->io_thd, io_lock, + &mi->stop_cond, + &mi->slave_running, + skip_lock)) && + !force_all) + DBUG_RETURN(error); + } DBUG_RETURN(0); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index cb5aac863c0..0ade0b759d5 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -21,6 +21,7 @@ #include "log_event.h" #include "rpl_filter.h" #include +#include "debug_sync.h" int max_binlog_dump_events = 0; // unlimited my_bool opt_sporadic_binlog_dump_fail = 0; @@ -556,6 +557,20 @@ impossible position"; } #endif + DBUG_EXECUTE_IF("dump_thread_wait_before_send_xid", + { + if ((*packet)[EVENT_TYPE_OFFSET+1] == XID_EVENT) + { + net_flush(net); + const char act[]= + "now " + "wait_for signal.continue"; + DBUG_ASSERT(opt_debug_sync_timeout > 0); + DBUG_ASSERT(!debug_sync_set_action(current_thd, + STRING_WITH_LEN(act))); + } + }); + if ((*packet)[EVENT_TYPE_OFFSET+1] == FORMAT_DESCRIPTION_EVENT) { binlog_can_be_corrupted= test((*packet)[FLAGS_OFFSET+1] & @@ -572,6 +587,14 @@ impossible position"; goto err; } + DBUG_EXECUTE_IF("dump_thread_wait_before_send_xid", + { + if ((*packet)[EVENT_TYPE_OFFSET+1] == XID_EVENT) + { + net_flush(net); + } + }); + DBUG_PRINT("info", ("log event code %d", (*packet)[LOG_EVENT_OFFSET+1] )); if ((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT) From ff7d07062da60bca7952f115e304e0d1782c38f6 Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Tue, 18 Jan 2011 23:21:39 +0530 Subject: [PATCH 10/10] Bug#47449: This problem not seen in PB2. Remove from experimental group --- mysql-test/collections/default.experimental | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 298205e1b7d..7ffc88745ea 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -10,7 +10,6 @@ innodb.innodb_information_schema # Bug#48883 2010-05-11 alik Test "innod main.func_math @freebsd # Bug#43020 2010-05-04 alik main.func_math fails on FreeBSD in PB2 main.gis # Bug#52208 2010-11-24 alik gis fails on some platforms (Solaris, HP-UX, Linux) main.gis-rtree @freebsd # Bug#38965 2010-05-04 alik test cases gis-rtree, type_float, type_newdecimal fail in embedded server -main.information_schema # Bug#47449 2009-09-19 alik main.information_schema and innodb.innodb_information_schema fail sporadically main.lock_multi_bug38499 # Bug#47448 2009-09-19 alik main.lock_multi_bug38499 times out sporadically main.outfile_loaddata @solaris # Bug#46895 2010-01-20 alik Test "outfile_loaddata" fails (reproducible) main.signal_demo3 @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun