From 5903c66b822cc5ba7542b1620257c5130bf662cb Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 30 Jun 2011 16:51:02 +0200 Subject: [PATCH 01/32] 11766640 addendum: disable unit tests in MTR with --do-test or --start-from --- mysql-test/lib/mtr_cases.pm | 3 +++ mysql-test/mysql-test-run.pl | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index d677645d9da..044ebb1f176 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -111,6 +111,9 @@ sub collect_test_cases ($$$$) { my $opt_skip_test_list= shift; my $cases= []; # Array of hash(one hash for each testcase) + # Unit tests off by default also if using --do-test or --start-from + $::opt_ctest= 0 if $::opt_ctest == -1 && ($do_test || $start_from); + $do_test_reg= init_pattern($do_test, "--do-test"); $skip_test_reg= init_pattern($skip_test, "--skip-test"); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 423518cd788..82d17a21f89 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -197,7 +197,7 @@ our $opt_debug_server; our @opt_cases; # The test cases names in argv our $opt_embedded_server; # -1 indicates use default, override with env.var. -my $opt_ctest= env_or_val(MTR_UNIT_TESTS => -1); +our $opt_ctest= env_or_val(MTR_UNIT_TESTS => -1); # Unit test report stored here for delayed printing my $ctest_report; From be8f64ff294644759202ca24e8d44e8d1a257410 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 1 Jul 2011 13:10:04 +0200 Subject: [PATCH 02/32] Bug #11757091 49093: 5.1 CONFIGURE SCRIPT SHOULD WARN ABOUT MYSQL CLUSTER NOT BEING MAINTAINED Added a conditional echo at end of configure.in --- configure.in | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configure.in b/configure.in index 0948fe1349d..0e336c5522b 100644 --- a/configure.in +++ b/configure.in @@ -2875,6 +2875,15 @@ AC_CONFIG_COMMANDS_POST(ac_configure_args="$ac_configure_args CFLAGS='$CFLAGS' C AC_OUTPUT +# Add warning if user configures with --with-ndbcluster +if test X"$with_plugin_ndbcluster" = Xyes ; then + echo + echo This version of MySQL Cluster is no longer maintained. + echo Please use the separate sources provided for MySQL Cluster instead. + echo See http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster.html + echo for more details. +fi + # The first line "Thank you ..." is checked in ./Do-compile to verify that configure # ended sucessfully - don't remove it. echo From 017281da2443fa8a4ff7db455f0a79fde37d4d68 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 7 Jul 2011 08:22:43 -0300 Subject: [PATCH 03/32] Bug#12727287: Maintainer mode compilation fails with gcc 4.6 GCC 4.6 has new -Wunused-but-set-variable flag, which is enabled by -Wall, that causes GCC to emit a warning whenever a local variable is assigned to, but otherwise unused (aside from its declaration). Since the maintainer mode uses -Wall and -Werror, source code which triggers these warnings will be rejected. That is, these warnings become hard errors. The solution is to fix the code which triggers these specific warnings. In most of the cases, this is a welcome cleanup as code which triggers this warning is probably dead anyway. --- dbug/dbug.c | 2 -- libmysqld/lib_sql.cc | 15 +++++++-------- sql/item_func.cc | 7 ++++--- sql/mysqld.cc | 3 +++ sql/protocol.cc | 22 +++++++++------------- sql/sql_class.h | 8 -------- sql/sql_load.cc | 4 +++- storage/innobase/btr/btr0cur.c | 8 +++----- storage/perfschema/pfs.cc | 3 +++ tests/mysql_client_test.c | 6 +----- unittest/mysys/lf-t.c | 5 ++--- 11 files changed, 35 insertions(+), 48 deletions(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index 2c06eeff95a..2dadf7bb2d5 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -1873,7 +1873,6 @@ static void DBUGOpenFile(CODE_STATE *cs, const char *name,const char *end,int append) { REGISTER FILE *fp; - REGISTER BOOLEAN newfile; if (name != NULL) { @@ -1902,7 +1901,6 @@ static void DBUGOpenFile(CODE_STATE *cs, } else { - newfile= !EXISTS(name); if (!(fp= fopen(name, append ? "a+" : "w"))) { (void) fprintf(stderr, ERR_OPEN, cs->process, name); diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index eed5e90edcd..93790082fba 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -1144,8 +1144,7 @@ bool net_send_error_packet(THD *thd, uint sql_errno, const char *err, const char *sqlstate) { uint error; - uchar converted_err[MYSQL_ERRMSG_SIZE]; - uint32 converted_err_len; + char converted_err[MYSQL_ERRMSG_SIZE]; MYSQL_DATA *data= thd->cur_data; struct embedded_query_result *ei; @@ -1160,12 +1159,12 @@ bool net_send_error_packet(THD *thd, uint sql_errno, const char *err, ei= data->embedded_info; ei->last_errno= sql_errno; - converted_err_len= convert_error_message((char*)converted_err, - sizeof(converted_err), - thd->variables.character_set_results, - err, strlen(err), - system_charset_info, &error); - strmake(ei->info, (const char*) converted_err, sizeof(ei->info)-1); + convert_error_message(converted_err, sizeof(converted_err), + thd->variables.character_set_results, + err, strlen(err), + system_charset_info, &error); + /* Converted error message is always null-terminated. */ + strmake(ei->info, converted_err, sizeof(ei->info)-1); strmov(ei->sqlstate, sqlstate); ei->server_status= thd->server_status; thd->cur_data= 0; diff --git a/sql/item_func.cc b/sql/item_func.cc index 754eae6d55b..19fc313a675 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4965,8 +4965,9 @@ longlong Item_func_get_user_var::val_int() */ -int get_var_with_binlog(THD *thd, enum_sql_command sql_command, - LEX_STRING &name, user_var_entry **out_entry) +static int +get_var_with_binlog(THD *thd, enum_sql_command sql_command, + LEX_STRING &name, user_var_entry **out_entry) { BINLOG_USER_VAR_EVENT *user_var_event; user_var_entry *var_entry; @@ -5096,7 +5097,7 @@ void Item_func_get_user_var::fix_length_and_dec() 'var_entry' is NULL only if there occured an error during the call to get_var_with_binlog. */ - if (var_entry) + if (!error && var_entry) { m_cached_result_type= var_entry->type; unsigned_flag= var_entry->unsigned_flag; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3d06fd0c4d6..e2a1f694aee 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5161,6 +5161,9 @@ void handle_connections_sockets() DBUG_ENTER("handle_connections_sockets"); + (void) ip_flags; + (void) socket_flags; + #ifndef HAVE_POLL FD_ZERO(&clientFDs); #endif diff --git a/sql/protocol.cc b/sql/protocol.cc index 00ce5701756..b563925f612 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -368,9 +368,8 @@ bool net_send_error_packet(THD *thd, uint sql_errno, const char *err, buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + MYSQL_ERRMSG_SIZE:512 */ uint error; - uchar converted_err[MYSQL_ERRMSG_SIZE]; - uint32 converted_err_len; - uchar buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos; + char converted_err[MYSQL_ERRMSG_SIZE]; + char buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos; DBUG_ENTER("send_error_packet"); @@ -390,19 +389,16 @@ bool net_send_error_packet(THD *thd, uint sql_errno, const char *err, { /* The first # is to make the protocol backward compatible */ buff[2]= '#'; - pos= (uchar*) strmov((char*) buff+3, sqlstate); + pos= strmov(buff+3, sqlstate); } - converted_err_len= convert_error_message((char*)converted_err, - sizeof(converted_err), - thd->variables.character_set_results, - err, strlen(err), - system_charset_info, &error); - length= (uint) (strmake((char*) pos, (char*)converted_err, - MYSQL_ERRMSG_SIZE - 1) - (char*) buff); - err= (char*) buff; + convert_error_message(converted_err, sizeof(converted_err), + thd->variables.character_set_results, + err, strlen(err), system_charset_info, &error); + /* Converted error message is always null-terminated. */ + length= (uint) (strmake(pos, converted_err, MYSQL_ERRMSG_SIZE - 1) - buff); - DBUG_RETURN(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) err, + DBUG_RETURN(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) buff, length)); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 8a427057d83..fafbab07979 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3642,14 +3642,6 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, STATUS_VAR *dec_var); void mark_transaction_to_rollback(THD *thd, bool all); -/* - This prototype is placed here instead of in item_func.h because it - depends on the definition of enum_sql_command, which is in this - file. - */ -int get_var_with_binlog(THD *thd, enum_sql_command sql_command, - LEX_STRING &name, user_var_entry **out_entry); - /* Inline functions */ inline bool add_item_to_list(THD *thd, Item *item) diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 1261568f212..1819102aa34 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -177,6 +177,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, #ifndef EMBEDDED_LIBRARY LOAD_FILE_INFO lf_info; THD::killed_state killed_status= THD::NOT_KILLED; + bool is_concurrent; #endif char *db = table_list->db; // This is never null /* @@ -187,7 +188,6 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, char *tdb= thd->db ? thd->db : db; // Result is never null ulong skip_lines= ex->skip_lines; bool transactional_table; - bool is_concurrent; DBUG_ENTER("mysql_load"); /* @@ -256,7 +256,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, table= table_list->table; transactional_table= table->file->has_transactions(); +#ifndef EMBEDDED_LIBRARY is_concurrent= (table_list->lock_type == TL_WRITE_CONCURRENT_INSERT); +#endif if (!fields_vars.elements) { diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index e1060af525c..46a52b549af 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -3575,7 +3575,6 @@ static void btr_record_not_null_field_in_rec( /*=============================*/ - rec_t* rec, /*!< in: physical record */ ulint n_unique, /*!< in: dict_index_get_n_unique(index), number of columns uniquely determine an index entry */ @@ -3595,9 +3594,8 @@ btr_record_not_null_field_in_rec( for (i = 0; i < n_unique; i++) { ulint rec_len; - byte* field; - field = rec_get_nth_field(rec, offsets, i, &rec_len); + rec_get_nth_field_offs(offsets, i, &rec_len); if (rec_len != UNIV_SQL_NULL) { n_not_null[i]++; @@ -3712,7 +3710,7 @@ btr_estimate_number_of_different_key_vals( if (n_not_null) { btr_record_not_null_field_in_rec( - rec, n_cols, offsets_rec, n_not_null); + n_cols, offsets_rec, n_not_null); } } @@ -3747,7 +3745,7 @@ btr_estimate_number_of_different_key_vals( if (n_not_null) { btr_record_not_null_field_in_rec( - next_rec, n_cols, offsets_next_rec, + n_cols, offsets_next_rec, n_not_null); } diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index 139064ab212..27350c59604 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.cc @@ -1574,6 +1574,9 @@ static void unlock_rwlock_v1(PSI_rwlock *rwlock) aggregate_single_stat_chain(&pfs_rwlock->m_read_lock_stat, locked_time); } } +#else + (void) last_reader; + (void) last_writer; #endif } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 5401e360f33..b3da65485dd 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -18596,11 +18596,8 @@ static void test_bug38486(void) static void test_bug33831(void) { MYSQL *l_mysql; - my_bool error; DBUG_ENTER("test_bug33831"); - - error= 0; if (!(l_mysql= mysql_client_init(NULL))) { @@ -18623,9 +18620,8 @@ static void test_bug33831(void) DIE_UNLESS(0); } - mysql_close(l_mysql); - + DBUG_VOID_RETURN; } diff --git a/unittest/mysys/lf-t.c b/unittest/mysys/lf-t.c index 16821c862b0..573a56cc1d6 100644 --- a/unittest/mysys/lf-t.c +++ b/unittest/mysys/lf-t.c @@ -34,8 +34,7 @@ int with_my_thread_init=0; */ pthread_handler_t test_lf_pinbox(void *arg) { - int m= *(int *)arg; - int32 x= 0; + int m= *(int *)arg; LF_PINS *pins; if (with_my_thread_init) @@ -43,7 +42,7 @@ pthread_handler_t test_lf_pinbox(void *arg) pins= lf_pinbox_get_pins(&lf_allocator.pinbox); - for (x= ((int)(intptr)(&m)); m ; m--) + for (; m ; m--) { lf_pinbox_put_pins(pins); pins= lf_pinbox_get_pins(&lf_allocator.pinbox); From 535855eb753f55b5f39c307da48c96691204dbfb Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Thu, 7 Jul 2011 17:22:24 +0200 Subject: [PATCH 04/32] Fix bug#45415: "rpm upgrade recreates test database" Let the creation of the "test" database happen only during a new installation, not in an RPM upgrade. --- support-files/mysql.spec.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 0baffd5444f..006dea45e64 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -798,13 +798,12 @@ else fi # echo "Analyzed: SERVER_TO_START=$SERVER_TO_START" if [ ! -d $mysql_datadir/mysql ] ; then - mkdir $mysql_datadir/mysql; + mkdir $mysql_datadir/mysql $mysql_datadir/test echo "MySQL RPM installation of version $NEW_VERSION" >> $STATUS_FILE else # If the directory exists, we may assume it is an upgrade. echo "MySQL RPM upgrade to version $NEW_VERSION" >> $STATUS_FILE fi -if [ ! -d $mysql_datadir/test ] ; then mkdir $mysql_datadir/test; fi # ---------------------------------------------------------------------- # Make MySQL start/shutdown automatically when the machine does it. @@ -837,7 +836,12 @@ chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir # ---------------------------------------------------------------------- # Initiate databases if needed # ---------------------------------------------------------------------- -%{_bindir}/mysql_install_db --rpm --user=%{mysqld_user} +if ! grep '^MySQL RPM upgrade' $STATUS_FILE >/dev/null 2>&1 ; then + # Fix bug#45415: no "mysql_install_db" on an upgrade + # Do this as a negative to err towards more "install" runs + # rather than to miss one. + %{_bindir}/mysql_install_db --rpm --user=%{mysqld_user} +fi # ---------------------------------------------------------------------- # Upgrade databases if needed would go here - but it cannot be automated yet @@ -1161,6 +1165,12 @@ fi # merging BK trees) ############################################################################## %changelog +* Thu Jul 07 2011 Joerg Bruehe + +- Fix bug#45415: "rpm upgrade recreates test database" + Let the creation of the "test" database happen only during a new installation, + not in an RPM upgrade. + This affects both the "mkdir" and the call of "mysql_install_db". * Thu Feb 03 2011 Joerg Bruehe From e3fab622c2bedd11415ef069b176e7b953c07660 Mon Sep 17 00:00:00 2001 From: "kevin.lewis@oracle.com" <> Date: Thu, 7 Jul 2011 16:29:30 -0500 Subject: [PATCH 05/32] Bug#12637786 was fixed with rb:692 by marko. But that fix has a remaining bug. It added this assert; ut_ad(ind_field->prefix_len); before a section of code that assumes there is a prefix_len. The patch replaced code that explicitly avoided this with a check for prefix_len. It turns out that the purge thread can get to that assert without a prefix_len because it does not use a row_ext_t* . When UNIV_DEBUG is not defined, the affect of this is that the purge thread sets the dfield->len to zero and then cannot find the entry in the index to purge. So secondary index entries remain unpurged. This patch does not do the assert. Instead, it uses 'if (ind_field->prefix_len) {...}' around the section of code that assumes a prefix_len. This is the way the patch I provided to Marko did it. The test case is simply modified to do a sleep(10) in order to give the purge thread a chance to run. Without the code change to row0row.c, this modified testcase will assert if InnoDB was compiled with UNIV_DEBUG. I tried to sleep(5), but it did not always assert. --- .../suite/innodb_plugin/r/innodb-index.result | 1 + .../suite/innodb_plugin/t/innodb-index.test | 3 +++ storage/innodb_plugin/row/row0row.c | 21 ++++++++++++------- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/r/innodb-index.result b/mysql-test/suite/innodb_plugin/r/innodb-index.result index 32a029bc4ca..b24f282dfc4 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb-index.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-index.result @@ -1022,6 +1022,7 @@ v16 VARCHAR(500), v17 VARCHAR(500), v18 VARCHAR(500) CREATE INDEX idx1 ON t1(a,v1); INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); UPDATE t1 SET a=1000; +DELETE FROM t1; DROP TABLE t1; set global innodb_file_per_table=0; set global innodb_file_format=Antelope; diff --git a/mysql-test/suite/innodb_plugin/t/innodb-index.test b/mysql-test/suite/innodb_plugin/t/innodb-index.test index 28393553ec2..52f94990b15 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb-index.test +++ b/mysql-test/suite/innodb_plugin/t/innodb-index.test @@ -475,6 +475,9 @@ CREATE TABLE t1(a INT, CREATE INDEX idx1 ON t1(a,v1); INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r); UPDATE t1 SET a=1000; +DELETE FROM t1; +# Let the purge thread clean up this file. +-- sleep 10 DROP TABLE t1; eval set global innodb_file_per_table=$per_table; diff --git a/storage/innodb_plugin/row/row0row.c b/storage/innodb_plugin/row/row0row.c index 69753d15737..9cdbbe76e04 100644 --- a/storage/innodb_plugin/row/row0row.c +++ b/storage/innodb_plugin/row/row0row.c @@ -148,22 +148,27 @@ row_build_index_entry( continue; } } else if (dfield_is_ext(dfield)) { - /* This table should be in Antelope format - (ROW_FORMAT=REDUNDANT or ROW_FORMAT=COMPACT). - In that format, the maximum column prefix + /* This table is either in Antelope format + (ROW_FORMAT=REDUNDANT or ROW_FORMAT=COMPACT) + or a purge record where the ordered part of + the field is not external. + In Antelope, the maximum column prefix index length is 767 bytes, and the clustered index record contains a 768-byte prefix of each off-page column. */ ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE); len -= BTR_EXTERN_FIELD_REF_SIZE; + dfield_set_len(dfield, len); } /* If a column prefix index, take only the prefix. */ - ut_ad(ind_field->prefix_len); - len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminlen, col->mbmaxlen, - ind_field->prefix_len, len, dfield_get_data(dfield)); - dfield_set_len(dfield, len); + if (ind_field->prefix_len) { + len = dtype_get_at_most_n_mbchars( + col->prtype, col->mbminlen, col->mbmaxlen, + ind_field->prefix_len, len, + dfield_get_data(dfield)); + dfield_set_len(dfield, len); + } } ut_ad(dtuple_check_typed(entry)); From cc17ce723aa4254b7e58b2c5b6e8b0c6b6278f42 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Mon, 11 Jul 2011 17:11:41 +0100 Subject: [PATCH 06/32] BUG#12695969: FIX OUTDATED COPYRIGHT NOTICES IN REPLACTION CLIENT TOOLS The fix is to backport part of revision: - alexander.nozdrin@oracle.com-20101006150613-ls60rb2tq5dpyb5c from mysql-5.5. In detail, we add the oracle welcome notice header file proposed in the original patch and include/use it in client/mysqlbinlog.cc, replacing the existing and obsolete notice. --- client/mysqlbinlog.cc | 10 +++------- include/welcome_copyright_notice.h | 31 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 include/welcome_copyright_notice.h diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index adf6c94ac52..e62c10024e5 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1,6 +1,4 @@ -/* - Copyright (c) 2000-2008 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. +/* Copyright (c) 2000, 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 @@ -39,6 +37,7 @@ #include "mysql_priv.h" #include "log_event.h" #include "sql_common.h" +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE #define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) @@ -859,10 +858,7 @@ static void print_version() static void usage() { print_version(); - puts("By Monty and Sasha, for your professional use\n\ -This software comes with NO WARRANTY: This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n"); - + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); printf("\ Dumps a MySQL binary log in a format usable for viewing or for piping to\n\ the mysql command line client\n\n"); diff --git a/include/welcome_copyright_notice.h b/include/welcome_copyright_notice.h new file mode 100644 index 00000000000..5a96da4ceb4 --- /dev/null +++ b/include/welcome_copyright_notice.h @@ -0,0 +1,31 @@ +/* Copyright (c) 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef _welcome_copyright_notice_h_ +#define _welcome_copyright_notice_h_ + +/* + This define specifies copyright notice which is displayed by every MySQL + program on start, or on help screen. +*/ + +#define ORACLE_WELCOME_COPYRIGHT_NOTICE(years) \ + "Copyright (c) " years ", Oracle and/or its affiliates. All rights reserved.\n" \ + "\n" \ + "Oracle is a registered trademark of Oracle Corporation and/or its\n" \ + "affiliates. Other names may be trademarks of their respective\n" \ + "owners.\n" + +#endif /* _welcome_copyright_notice_h_ */ From eae6fde71af59ffff6158b7135246d97d8163ebe Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 12 Jul 2011 02:10:28 +0100 Subject: [PATCH 07/32] BUG#12695969 Follow-up patch that adds the newly added header file to Makefile.am noinst_HEADERS. --- include/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Makefile.am b/include/Makefile.am index e233e02e206..f97014b0b04 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -34,7 +34,7 @@ noinst_HEADERS = config-win.h config-netware.h \ my_aes.h my_tree.h hash.h thr_alarm.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ mysql_version.h.in my_compare.h my_time.h \ - my_user.h my_libwrap.h + my_user.h my_libwrap.h welcome_copyright_notice.h # Remove built files and the symlinked directories CLEANFILES = $(BUILT_SOURCES) readline openssl From ae2db9b9706e976d2f06c86c648c6af925228224 Mon Sep 17 00:00:00 2001 From: MySQL Release Engineering Date: Wed, 13 Jul 2011 19:35:34 +0200 Subject: [PATCH 08/32] build 5.5.15 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 796544a7013..d9f537cb915 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=15 +MYSQL_VERSION_PATCH=16 MYSQL_VERSION_EXTRA= From 73340d03fc57b811bb34cf047137f5df39705cff Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Thu, 14 Jul 2011 14:58:51 +0530 Subject: [PATCH 09/32] Bug#12561297 : Disabled the test --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index ebcfa6b1845..08db85a3f45 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -16,3 +16,4 @@ alter_table-big : Bug#11748731 2010-11-15 mattiasj was not tested create-big : Bug#11748731 2010-11-15 mattiasj was not tested archive-big : Bug#11817185 2011-03-10 Anitha Disabled since this leads to timeout on Solaris Sparc log_tables-big : Bug#11756699 2010-11-15 mattiasj report already exists +mysql_embedded : Bug#12561297 2011-05-14 Anitha Dependent on PB2 changes - eventum#41836 From ce8077d8d37e37f4b007f64c5ca301d096699db8 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 14 Jul 2011 12:15:24 +0100 Subject: [PATCH 10/32] BUG#11753004: 44360: REPLICATION FAILED The server crashes if it processes table map events that are corrupted, especially if they map different tables to the same identifier. This could happen, for instance, due to BUG 56226. We fix this by checking whether the table map has already been mapped before actually applying the event. If it has been mapped with different settings an error is raised and the slave SQL thread stops. If it has been mapped with same settings the event is skipped. If the table is set to be ignored by the filtering rules, there is no change in behavior: the event is skipped and ids are not checked. --- .../suite/rpl/r/rpl_row_corruption.result | 49 ++++++ .../suite/rpl/t/rpl_row_corruption-slave.opt | 1 + .../suite/rpl/t/rpl_row_corruption.test | 115 ++++++++++++++ sql/log_event.cc | 148 ++++++++++++++++-- 4 files changed, 301 insertions(+), 12 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_row_corruption.result create mode 100644 mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_corruption.test diff --git a/mysql-test/suite/rpl/r/rpl_row_corruption.result b/mysql-test/suite/rpl/r/rpl_row_corruption.result new file mode 100644 index 00000000000..7fd47a20f03 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_corruption.result @@ -0,0 +1,49 @@ +include/master-slave.inc +[connection master] +CREATE TABLE t1_11753004 (c1 INT); +CREATE TABLE t2_11753004 (c1 INT); +INSERT INTO t1_11753004 VALUES (1); +INSERT INTO t2_11753004 VALUES (2); +call mtr.add_suppression(".*Found table map event mapping table id 0 which was already mapped but with different settings.*"); +include/stop_slave.inc +SET @save_debug= @@global.debug; +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +include/start_slave.inc +UPDATE t1_11753004, t2_11753004 SET t1_11753004.c1=3, t2_11753004.c1=4 WHERE t1_11753004.c1=1 OR t2_11753004.c1=2; +include/wait_for_slave_sql_error.inc [errno=1593 ] +include/stop_slave.inc +SET GLOBAL debug="-d,inject_tblmap_same_id_maps_diff_table"; +include/start_slave.inc +include/rpl_reset.inc +DROP TABLE t1_11753004, t2_11753004; +include/stop_slave.inc +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +include/start_slave.inc +include/rpl_reset.inc +CREATE TABLE t1_11753004 (c1 INT); +CREATE TABLE t2_11753004_ign (c1 INT); +INSERT INTO t1_11753004 VALUES (1); +INSERT INTO t2_11753004_ign VALUES (2); +UPDATE t1_11753004, t2_11753004_ign SET t1_11753004.c1=3, t2_11753004_ign.c1=4 WHERE t1_11753004.c1=1 OR t2_11753004_ign.c1=2; +CREATE TABLE t1 (c1 INT); +CREATE TABLE t2 (c1 INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +BINLOG ' +SOgWTg8BAAAAbgAAAHIAAAAAAAQANS42LjMtbTUtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAABI6BZOEzgNAAgAEgAEBAQEEgAAVgAEGggAAAAICAgCAAAAAAVAYI8= +'/*!*/; +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +BINLOG ' +SOgWThMBAAAAKQAAAAYDAAAAAEIAAAAAAAEABHRlc3QAAnQxAAEDAAE= +SOgWThMBAAAAKQAAAC8DAAAAAEMAAAAAAAEABHRlc3QAAnQyAAEDAAE= +SOgWThgBAAAAKAAAAFcDAAAAAEIAAAAAAAAAAf///gEAAAD+AwAAAA== +SOgWThgBAAAAKAAAAH8DAAAAAEMAAAAAAAEAAf///gEAAAD+BAAAAA== +'/*!*/; +ERROR HY000: Fatal error: Found table map event mapping table id 0 which was already mapped but with different settings. +DROP TABLE t1,t2; +SET GLOBAL debug="-d,inject_tblmap_same_id_maps_diff_table"; +DROP TABLE t1_11753004; +DROP TABLE t2_11753004_ign; +SET GLOBAL debug= @save_debug; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt b/mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt new file mode 100644 index 00000000000..da199510eb3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt @@ -0,0 +1 @@ +--replicate-ignore-table=test.t2_11753004_ign diff --git a/mysql-test/suite/rpl/t/rpl_row_corruption.test b/mysql-test/suite/rpl/t/rpl_row_corruption.test new file mode 100644 index 00000000000..a7650c615a3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_corruption.test @@ -0,0 +1,115 @@ +# +--source include/master-slave.inc +--source include/have_debug.inc +--source include/have_binlog_format_row.inc + +# BUG#11753004: 44360: REPLICATION FAILED + +## assert that we get an error when checking the +## identifiers at the slave (instead of a crash or +## different table being updated) + +--let $t1= t1_11753004 +--let $t2= t2_11753004 +--let $t2_ign= t2_11753004_ign + +## test #1: assert that we get an error raised when multiple +## tables in the same RBR statement are mapped with the +## same identifier + +--eval CREATE TABLE $t1 (c1 INT) +--eval CREATE TABLE $t2 (c1 INT) +--eval INSERT INTO $t1 VALUES (1) +--eval INSERT INTO $t2 VALUES (2) + +--sync_slave_with_master +call mtr.add_suppression(".*Found table map event mapping table id 0 which was already mapped but with different settings.*"); + +# stop the slave and inject corruption +--source include/stop_slave.inc +SET @save_debug= @@global.debug; +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +--source include/start_slave.inc +--connection master +# both tables get mapped to 0 (in a way, simulating scenario +# originated by BUG#56226) +--eval UPDATE $t1, $t2 SET $t1.c1=3, $t2.c1=4 WHERE $t1.c1=1 OR $t2.c1=2 +--connection slave + +# wait for error 1593 (ER_SLAVE_FATAL_ERROR) +--let $slave_sql_errno=1593 +--source include/wait_for_slave_sql_error.inc +--source include/stop_slave.inc + +# clean up +SET GLOBAL debug="-d,inject_tblmap_same_id_maps_diff_table"; +--source include/start_slave.inc +--connection master +--source include/rpl_reset.inc +--eval DROP TABLE $t1, $t2 +--sync_slave_with_master + +## test #2: assert that ignored tables that may have been mapped +## with the same identifier are skipped, thus no error +## is raised. + +--connection slave +--source include/stop_slave.inc +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +--source include/start_slave.inc +--source include/rpl_reset.inc +--connection master +--eval CREATE TABLE $t1 (c1 INT) +--eval CREATE TABLE $t2_ign (c1 INT) +--eval INSERT INTO $t1 VALUES (1) +--eval INSERT INTO $t2_ign VALUES (2) +--eval UPDATE $t1, $t2_ign SET $t1.c1=3, $t2_ign.c1=4 WHERE $t1.c1=1 OR $t2_ign.c1=2 + +# must not raise error as second table is filtered +--sync_slave_with_master + + +## test #3: check that BINLOG statements will also raise an +## error if containing table map events mapping different +## tables to same table identifier. + +CREATE TABLE t1 (c1 INT); +CREATE TABLE t2 (c1 INT); + +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); + +# FD event +BINLOG ' +SOgWTg8BAAAAbgAAAHIAAAAAAAQANS42LjMtbTUtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAABI6BZOEzgNAAgAEgAEBAQEEgAAVgAEGggAAAAICAgCAAAAAAVAYI8= +'/*!*/; + +#110708 12:21:44 server id 1 end_log_pos 774 Table_map: `test`.`t1` mapped to number 66 +# at 774 +#110708 12:21:44 server id 1 end_log_pos 815 Table_map: `test`.`t2` mapped to number 67 +# at 815 +#110708 12:21:44 server id 1 end_log_pos 855 Update_rows: table id 66 +# at 855 +#110708 12:21:44 server id 1 end_log_pos 895 Update_rows: table id 67 flags: STMT_END_F +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +--error ER_SLAVE_FATAL_ERROR +BINLOG ' +SOgWThMBAAAAKQAAAAYDAAAAAEIAAAAAAAEABHRlc3QAAnQxAAEDAAE= +SOgWThMBAAAAKQAAAC8DAAAAAEMAAAAAAAEABHRlc3QAAnQyAAEDAAE= +SOgWThgBAAAAKAAAAFcDAAAAAEIAAAAAAAAAAf///gEAAAD+AwAAAA== +SOgWThgBAAAAKAAAAH8DAAAAAEMAAAAAAAEAAf///gEAAAD+BAAAAA== +'/*!*/; + + +# clean up +DROP TABLE t1,t2; +--connection slave +SET GLOBAL debug="-d,inject_tblmap_same_id_maps_diff_table"; +--connection master +--eval DROP TABLE $t1 +--eval DROP TABLE $t2_ign +--sync_slave_with_master +SET GLOBAL debug= @save_debug; + +--source include/rpl_end.inc diff --git a/sql/log_event.cc b/sql/log_event.cc index 1f58c7ed1bf..82a6d9e8ffc 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8222,6 +8222,97 @@ Table_map_log_event::~Table_map_log_event() */ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + +enum enum_tbl_map_status +{ + /* no duplicate identifier found */ + OK_TO_PROCESS= 0, + + /* this table map must be filtered out */ + FILTERED_OUT= 1, + + /* identifier mapping table with different properties */ + SAME_ID_MAPPING_DIFFERENT_TABLE= 2, + + /* a duplicate identifier was found mapping the same table */ + SAME_ID_MAPPING_SAME_TABLE= 3 +}; + +/* + Checks if this table map event should be processed or not. First + it checks the filtering rules, and then looks for duplicate identifiers + in the existing list of rli->tables_to_lock. + + It checks that there hasn't been any corruption by verifying that there + are no duplicate entries with different properties. + + In some cases, some binary logs could get corrupted, showing several + tables mapped to the same table_id, 0 (see: BUG#56226). Thus we do this + early sanity check for such cases and avoid that the server crashes + later. + + In some corner cases, the master logs duplicate table map events, i.e., + same id, same database name, same table name (see: BUG#37137). This is + different from the above as it's the same table that is mapped again + to the same identifier. Thus we cannot just check for same ids and + assume that the event is corrupted we need to check every property. + + NOTE: in the event that BUG#37137 ever gets fixed, this extra check + will still be valid because we would need to support old binary + logs anyway. + + @param rli The relay log info reference. + @param table_list A list element containing the table to check against. + @return OK_TO_PROCESS + if there was no identifier already in rli->tables_to_lock + + FILTERED_OUT + if the event is filtered according to the filtering rules + + SAME_ID_MAPPING_DIFFERENT_TABLE + if the same identifier already maps a different table in + rli->tables_to_lock + + SAME_ID_MAPPING_SAME_TABLE + if the same identifier already maps the same table in + rli->tables_to_lock. +*/ +static enum_tbl_map_status +check_table_map(Relay_log_info const *rli, RPL_TABLE_LIST *table_list) +{ + DBUG_ENTER("check_table_map"); + enum_tbl_map_status res= OK_TO_PROCESS; + + if (rli->sql_thd->slave_thread /* filtering is for slave only */ && + (!rpl_filter->db_ok(table_list->db) || + (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))) + res= FILTERED_OUT; + else + { + for(RPL_TABLE_LIST *ptr= static_cast(rli->tables_to_lock); + ptr; + ptr= static_cast(ptr->next_local)) + { + if (ptr->table_id == table_list->table_id) + { + + if (strcmp(ptr->db, table_list->db) || + strcmp(ptr->alias, table_list->table_name) || + ptr->lock_type != TL_WRITE) // the ::do_apply_event always sets TL_WRITE + res= SAME_ID_MAPPING_DIFFERENT_TABLE; + else + res= SAME_ID_MAPPING_SAME_TABLE; + + break; + } + } + } + + DBUG_PRINT("debug", ("check of table map ended up with: %u", res)); + + DBUG_RETURN(res); +} + int Table_map_log_event::do_apply_event(Relay_log_info const *rli) { RPL_TABLE_LIST *table_list; @@ -8248,20 +8339,13 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) table_list->alias= table_list->table_name = tname_mem; table_list->lock_type= TL_WRITE; table_list->next_global= table_list->next_local= 0; - table_list->table_id= m_table_id; + table_list->table_id= DBUG_EVALUATE_IF("inject_tblmap_same_id_maps_diff_table", 0, m_table_id); table_list->updating= 1; strmov(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len)); strmov(table_list->table_name, m_tblnam); - - int error= 0; - - if (rli->sql_thd->slave_thread /* filtering is for slave only */ && - (!rpl_filter->db_ok(table_list->db) || - (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))) - { - my_free(memory, MYF(MY_WME)); - } - else + DBUG_PRINT("debug", ("table: %s is mapped to %u", table_list->table_name, table_list->table_id)); + enum_tbl_map_status tblmap_status= check_table_map(rli, table_list); + if (tblmap_status == OK_TO_PROCESS) { DBUG_ASSERT(thd->lex->query_tables != table_list); @@ -8290,8 +8374,48 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) const_cast(rli)->tables_to_lock_count++; /* 'memory' is freed in clear_tables_to_lock */ } + else // FILTERED_OUT, SAME_ID_MAPPING_* + { + /* + If mapped already but with different properties, we raise an + error. + If mapped already but with same properties we skip the event. + If filtered out we skip the event. - DBUG_RETURN(error); + In all three cases, we need to free the memory previously + allocated. + */ + if (tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE) + { + /* + Something bad has happened. We need to stop the slave as strange things + could happen if we proceed: slave crash, wrong table being updated, ... + As a consequence we push an error in this case. + */ + + char buf[256]; + + my_snprintf(buf, sizeof(buf), + "Found table map event mapping table id %u which " + "was already mapped but with different settings.", + table_list->table_id); + + if (thd->slave_thread) + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER(ER_SLAVE_FATAL_ERROR), buf); + else + /* + For the cases in which a 'BINLOG' statement is set to + execute in a user session + */ + my_printf_error(ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR), + MYF(0), buf); + } + + my_free(memory, MYF(0)); + } + + DBUG_RETURN(tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE); } Log_event::enum_skip_reason From dbba17dad11764535d9cf98f635189c47afca98d Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 15 Jul 2011 12:42:06 +0100 Subject: [PATCH 11/32] DBUG_PRINT in solaris does not work well with NULL parameters. HA_ERR was returning 0 (null string) when no error happened (error=0). Since HA_ERR is used in DBUG_PRINT, regardless there was an error or not, the server could crash in solaris debug builds. We fix this by: - deploying an assertion that ensures that the function is not called when no error has happened; - making sure that HA_ERR is only called when an error happened; - making HA_ERR return "No Error", instead of 0, for non-debug builds if it is called when no error happened. This will make HA_ERR return values to work with DBUG_PRINT on solaris debug builds. --- sql/log_event.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 82a6d9e8ffc..fac3e3f264b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -59,6 +59,11 @@ static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd); static const char *HA_ERR(int i) { + /* + This function should only be called in case of an error + was detected + */ + DBUG_ASSERT(i != 0); switch (i) { case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND"; case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY"; @@ -111,7 +116,7 @@ static const char *HA_ERR(int i) case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT"; case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY"; } - return 0; + return "No Error!"; } /** @@ -132,7 +137,7 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error, TABLE *table, const char * type, const char *log_name, ulong pos) { - const char *handler_error= HA_ERR(ha_error); + const char *handler_error= (ha_error ? HA_ERR(ha_error) : NULL); char buff[MAX_SLAVE_ERRMSG], *slider; const char *buff_end= buff + sizeof(buff); uint len; @@ -7596,7 +7601,8 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) error= do_exec_row(rli); - DBUG_PRINT("info", ("error: %s", HA_ERR(error))); + if (error) + DBUG_PRINT("info", ("error: %s", HA_ERR(error))); DBUG_ASSERT(error != HA_ERR_RECORD_DELETED); table->in_use = old_thd; @@ -9344,7 +9350,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli) restart_rnd_next: error= table->file->rnd_next(table->record[0]); - DBUG_PRINT("info", ("error: %s", HA_ERR(error))); + if (error) + DBUG_PRINT("info", ("error: %s", HA_ERR(error))); switch (error) { case 0: From 2fe4f6bb29b3fd5eeca290e735d4b881ebc8edf9 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Fri, 15 Jul 2011 16:25:00 +0400 Subject: [PATCH 12/32] Backport a fix for Bug#59060 (Valgrind warning in Protocol_text::store()). Original changeset: revision-id: alexander.nozdrin@oracle.com-20101221122349-6h8ammcro70a4pac parent: sven.sandberg@oracle.com-20101221121948-hnivuulyohzch1v4 committer: Alexander Nozdrin branch nick: mysql-trunk-bugfixing timestamp: Tue 2010-12-21 15:23:49 +0300 message: A patch for Bug#59060 (Valgrind warning in Protocol_text::store()). We should not assume to have zero-terminated strings. --- sql/protocol.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/protocol.cc b/sql/protocol.cc index b7be3f71d8e..8b652fe855a 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -857,8 +857,8 @@ bool Protocol_text::store(const char *from, size_t length, { CHARSET_INFO *tocs= this->thd->variables.character_set_results; #ifndef DBUG_OFF - DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %s", field_pos, - field_count, (length == 0? "" : from))); + DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %.*s", field_pos, + field_count, (int) length, (length == 0 ? "" : from))); DBUG_ASSERT(field_pos < field_count); DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_DECIMAL || From 7fddcd06d20fdcbe5bb67d6adcd848ff3830ceef Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Mon, 18 Jul 2011 09:47:39 +0200 Subject: [PATCH 13/32] Bug#12537160 ASSERTION FAILED: STOP0 <= &TO->BUF[TO->LEN] WITH LARGE NUMBER. Turns out the DBUG_ASSERT added by fix for Bug#11792200 was overly pessimistic: 'stop0' is used in the main loop of do_div_mod, but we only dereference 'buf0' for div operations, not for mod. --- mysql-test/r/func_math.result | 10 ++++++++++ mysql-test/t/func_math.test | 11 +++++++++++ strings/decimal.c | 4 +++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index c93e33f98b9..0be170c2f26 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -699,3 +699,13 @@ select (1.175494351E-37 div 1.7976931348623157E+308); 0 Warnings: Warning 1292 Truncated incorrect DECIMAL value: '' +# +# Bug#12537160 ASSERTION FAILED: +# STOP0 <= &TO->BUF[TO->LEN] WITH LARGE NUMBER. +# +select 999999999999999999999999999999999999999999999999999999999999999999999999999999999 % 0.1 as foo; +foo +0.0 +select 999999999999999999999999999999999999999999999999999999999999999999999999999999999 % 0.0 as foo; +foo +NULL diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 0d59f98a313..b6890bdab17 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -536,3 +536,14 @@ SELECT 1 div null; --echo # Bug #11792200 - DIVIDING LARGE NUMBERS CAUSES STACK CORRUPTIONS --echo # select (1.175494351E-37 div 1.7976931348623157E+308); + +--echo # +--echo # Bug#12537160 ASSERTION FAILED: +--echo # STOP0 <= &TO->BUF[TO->LEN] WITH LARGE NUMBER. +--echo # + +let $nine_81= +999999999999999999999999999999999999999999999999999999999999999999999999999999999; + +eval select $nine_81 % 0.1 as foo; +eval select $nine_81 % 0.0 as foo; diff --git a/strings/decimal.c b/strings/decimal.c index da5888e7b0d..b18a8c3fa50 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -2182,7 +2182,6 @@ static int do_div_mod(const decimal_t *from1, const decimal_t *from2, } buf0=to->buf; stop0=buf0+intg0+frac0; - DBUG_ASSERT(stop0 <= &to->buf[to->len]); if (likely(div_mod)) while (dintg++ < 0 && buf0 < &to->buf[to->len]) { @@ -2277,7 +2276,10 @@ static int do_div_mod(const decimal_t *from1, const decimal_t *from2, } } if (likely(div_mod)) + { + DBUG_ASSERT(buf0 < to->buf + to->len); *buf0=(dec1)guess; + } dcarry= *start1; start1++; } From b9a929082b72bbcec929e97999a81be3f2700805 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Mon, 18 Jul 2011 11:21:14 +0200 Subject: [PATCH 14/32] Bug#12711164 - 61676: RESULT OF DIV WITH DECIMAL AND INTEGER DOES NOT MAKE SENSE Truncate result of decimal division before converting to integer. --- mysql-test/r/func_math.result | 19 +++++++++++++++++++ mysql-test/t/func_math.test | 11 +++++++++++ sql/item_func.cc | 7 ++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 0be170c2f26..8d4a4171e21 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -709,3 +709,22 @@ foo select 999999999999999999999999999999999999999999999999999999999999999999999999999999999 % 0.0 as foo; foo NULL +# +# Bug#12711164 - 61676: +# RESULT OF DIV WITH DECIMAL AND INTEGER DOES NOT MAKE SENSE +# +select 5 div 2; +5 div 2 +2 +select 5.0 div 2.0; +5.0 div 2.0 +2 +select 5.0 div 2; +5.0 div 2 +2 +select 5 div 2.0; +5 div 2.0 +2 +select 5.9 div 2, 1.23456789e3 DIV 2, 1.23456789e9 DIV 2, 1.23456789e19 DIV 2; +5.9 div 2 1.23456789e3 DIV 2 1.23456789e9 DIV 2 1.23456789e19 DIV 2 +2 617 617283945 6172839450000000000 diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index b6890bdab17..a1df990fa8e 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -547,3 +547,14 @@ let $nine_81= eval select $nine_81 % 0.1 as foo; eval select $nine_81 % 0.0 as foo; + +--echo # +--echo # Bug#12711164 - 61676: +--echo # RESULT OF DIV WITH DECIMAL AND INTEGER DOES NOT MAKE SENSE +--echo # + +select 5 div 2; +select 5.0 div 2.0; +select 5.0 div 2; +select 5 div 2.0; +select 5.9 div 2, 1.23456789e3 DIV 2, 1.23456789e9 DIV 2, 1.23456789e19 DIV 2; diff --git a/sql/item_func.cc b/sql/item_func.cc index 19fc313a675..7257b411ec4 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1605,8 +1605,13 @@ longlong Item_func_int_div::val_int() return 0; } + my_decimal truncated; + const bool do_truncate= true; + if (my_decimal_round(E_DEC_FATAL_ERROR, &tmp, 0, do_truncate, &truncated)) + DBUG_ASSERT(false); + longlong res; - if (my_decimal2int(E_DEC_FATAL_ERROR, &tmp, unsigned_flag, &res) & + if (my_decimal2int(E_DEC_FATAL_ERROR, &truncated, unsigned_flag, &res) & E_DEC_OVERFLOW) raise_integer_overflow(); return res; From c1d55fb255f543bbd7ea62c1f7531b4fba3aa8ea Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Mon, 18 Jul 2011 18:18:03 +0100 Subject: [PATCH 15/32] BUG#11809016 - NO WAY TO DISCOVER AN INSTANCE IS NO LONGER A SLAVE FOLLOWING MYSQL BUG#28796 Before BUG#28796, an empty host was used to identify that an instance was no longer a slave. However, BUG#28796 changed this behavior and one cannot set an empty host. Besides, a RESET SLAVE only cleans up information on the next event to retrieve from the master, disables ssl and resets heartbeat period. So a call to SHOW SLAVE STATUS after issuing a RESET SLAVE still returns some valid information, such as host, port, user and password. To fix this problem, we have introduced the command RESET SLAVE ALL that does what a regular RESET SLAVE does and also clears host, port, user and password information thus allowing users to identify when an instance is no longer a slave. --- .../extra/rpl_tests/rpl_reset_slave.test | 28 ++++++++++++++++++- .../suite/rpl/r/rpl_row_reset_slave.result | 8 ++++++ .../suite/rpl/r/rpl_stm_reset_slave.result | 8 ++++++ sql/rpl_mi.cc | 14 +++++++++- sql/rpl_mi.h | 2 +- sql/sql_lex.h | 5 ++++ sql/sql_repl.cc | 5 ++-- sql/sql_yacc.yy | 6 ++++ 8 files changed, 71 insertions(+), 5 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_reset_slave.test b/mysql-test/extra/rpl_tests/rpl_reset_slave.test index 14b457f601e..0d94f04ca44 100644 --- a/mysql-test/extra/rpl_tests/rpl_reset_slave.test +++ b/mysql-test/extra/rpl_tests/rpl_reset_slave.test @@ -77,5 +77,31 @@ reset slave; source include/check_slave_no_error.inc; change master to master_user='root'; ---let $rpl_only_running_threads= 1 + +# +# BUG#11809016 - NO WAY TO DISCOVER AN INSTANCE IS NO LONGER A SLAVE FOLLOWING MYSQL BUG#28796 +# + +reset slave; +--source include/start_slave.inc + +--source include/stop_slave.inc +--let $_slave_master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1) +--let $_slave_master_user= query_get_value(SHOW SLAVE STATUS, Master_User, 1) +--let $_slave_master_port= query_get_value(SHOW SLAVE STATUS, Master_Port, 1) + +reset slave all; +--error ER_BAD_SLAVE +start slave; + +--let $_show_master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1) +if ($_show_master_host != No such row) +{ + die; +} + +--replace_result $_slave_master_host MASTER_HOST $_slave_master_user MASTER_USER $_slave_master_port MASTER_PORT +--eval CHANGE MASTER TO MASTER_HOST= '$_slave_master_host', MASTER_USER= '$_slave_master_user', MASTER_PORT= $_slave_master_port +--source include/start_slave.inc + --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_row_reset_slave.result b/mysql-test/suite/rpl/r/rpl_row_reset_slave.result index 7dc94bab481..41fe0b1a9f3 100644 --- a/mysql-test/suite/rpl/r/rpl_row_reset_slave.result +++ b/mysql-test/suite/rpl/r/rpl_row_reset_slave.result @@ -41,4 +41,12 @@ include/stop_slave_sql.inc reset slave; include/check_slave_no_error.inc change master to master_user='root'; +reset slave; +include/start_slave.inc +include/stop_slave.inc +reset slave all; +start slave; +ERROR HY000: The server is not configured as slave; fix in config file or with CHANGE MASTER TO +CHANGE MASTER TO MASTER_HOST= 'MASTER_HOST', MASTER_USER= 'MASTER_USER', MASTER_PORT= MASTER_PORT; +include/start_slave.inc include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result b/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result index aa8bc63a432..b1473c937a1 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result +++ b/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result @@ -41,4 +41,12 @@ include/stop_slave_sql.inc reset slave; include/check_slave_no_error.inc change master to master_user='root'; +reset slave; +include/start_slave.inc +include/stop_slave.inc +reset slave all; +start slave; +ERROR HY000: The server is not configured as slave; fix in config file or with CHANGE MASTER TO +CHANGE MASTER TO MASTER_HOST= 'MASTER_HOST', MASTER_USER= 'MASTER_USER', MASTER_PORT= MASTER_PORT; +include/start_slave.inc include/rpl_end.inc diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index d1fd6bac41c..0060bcb6b1e 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -31,6 +31,8 @@ int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val); int init_dynarray_intvar_from_file(DYNAMIC_ARRAY* arr, IO_CACHE* f); +static void init_master_log_pos(Master_info* mi); + Master_info::Master_info(bool is_slave_recovery) :Slave_reporting_capability("I/O"), ssl(0), ssl_verify_server_cert(0), fd(-1), io_thd(0), @@ -100,6 +102,16 @@ bool Master_info::shall_ignore_server_id(ulong s_id) != NULL; } +void Master_info::clear_in_memory_info(bool all) +{ + init_master_log_pos(this); + if (all) + { + port= MYSQL_PORT; + host[0] = 0; user[0] = 0; password[0] = 0; + } +} + void init_master_log_pos(Master_info* mi) { DBUG_ENTER("init_master_log_pos"); @@ -234,7 +246,7 @@ file '%s')", fname); } mi->fd = fd; - init_master_log_pos(mi); + mi->clear_in_memory_info(false); } else // file exists diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 2e06d3e8b94..1434ba45519 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -62,6 +62,7 @@ class Master_info : public Slave_reporting_capability Master_info(bool is_slave_recovery); ~Master_info(); bool shall_ignore_server_id(ulong s_id); + void clear_in_memory_info(bool all); /* the variables below are needed because we can change masters on the fly */ char master_log_name[FN_REFLEN]; @@ -113,7 +114,6 @@ class Master_info : public Slave_reporting_capability DYNAMIC_ARRAY ignore_server_ids; ulong master_id; }; -void init_master_log_pos(Master_info* mi); int init_master_info(Master_info* mi, const char* master_info_fname, const char* slave_info_fname, bool abort_if_no_master_info_file, diff --git a/sql/sql_lex.h b/sql/sql_lex.h index accbd78246e..d3b0f578007 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -294,6 +294,10 @@ typedef struct st_lex_master_info DYNAMIC_ARRAY repl_ignore_server_ids; } LEX_MASTER_INFO; +typedef struct st_lex_reset_slave +{ + bool all; +} LEX_RESET_SLAVE; enum sub_select_type { @@ -2232,6 +2236,7 @@ struct LEX: public Query_tables_list LEX_MASTER_INFO mi; // used by CHANGE MASTER LEX_SERVER_OPTIONS server_options; USER_RESOURCES mqh; + LEX_RESET_SLAVE reset_slave_info; ulong type; /* This variable is used in post-parse stage to declare that sum-functions, diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 001c4cec678..8653607263f 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1285,8 +1285,9 @@ int reset_slave(THD *thd, Master_info* mi) goto err; } - /* Clear master's log coordinates */ - init_master_log_pos(mi); + /* Clear master's log coordinates and associated information */ + mi->clear_in_memory_info(thd->lex->reset_slave_info.all); + /* Reset errors (the idea is that we forget about the old master). diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 564250a9bf2..90a55471792 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -11337,10 +11337,16 @@ reset_options: reset_option: SLAVE { Lex->type|= REFRESH_SLAVE; } + slave_reset_options { } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;} ; +slave_reset_options: + /* empty */ { Lex->reset_slave_info.all= false; } + | ALL { Lex->reset_slave_info.all= true; } + ; + purge: PURGE { From a31dc61865b537da7e8a3602080920f87756fb02 Mon Sep 17 00:00:00 2001 From: Sunanda Menon Date: Tue, 19 Jul 2011 09:35:14 +0200 Subject: [PATCH 16/32] #41836: Eventum Request to enable the mysql_embedded binary --- libmysqld/examples/CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libmysqld/examples/CMakeLists.txt b/libmysqld/examples/CMakeLists.txt index f4a888c10ef..9c7c5bdb85c 100644 --- a/libmysqld/examples/CMakeLists.txt +++ b/libmysqld/examples/CMakeLists.txt @@ -23,9 +23,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ADD_DEFINITIONS(-DEMBEDDED_LIBRARY -UMYSQL_CLIENT) -# We never use "mysql_embedded", is more of a linktest, so we don't -# use MYSQL_ADD_EXECUTABLE as that would install it and package it -ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc +MYSQL_ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc ../../client/mysql.cc ../../client/readline.cc) TARGET_LINK_LIBRARIES(mysql_embedded mysqlserver) IF(UNIX) From 41258f8e6c46d06e817d55921c66309ae9701799 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Tue, 19 Jul 2011 10:37:37 -0400 Subject: [PATCH 17/32] Bug 12356373 - PERFORMANCE REGRESSION FROM 5.1 TO 5.5 : GROUP BY: The title of the bug is a little confusing. The actual fix is to reintroduce random readahead inside InnoDB with a dynamic, global switch innodb_random_read_ahead [default = off]. Approved by: Sunny Bains rb://696 --- storage/innodb_plugin/ChangeLog | 7 + storage/innodb_plugin/buf/buf0buf.c | 6 +- storage/innodb_plugin/buf/buf0rea.c | 170 +++++++++++++++++++++ storage/innodb_plugin/handler/ha_innodb.cc | 8 + storage/innodb_plugin/include/buf0buf.h | 14 ++ storage/innodb_plugin/include/buf0buf.ic | 28 +++- storage/innodb_plugin/include/srv0srv.h | 2 + storage/innodb_plugin/srv/srv0srv.c | 4 + 8 files changed, 232 insertions(+), 7 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 853ae782a44..617df0a61fe 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,10 @@ +2011-07-19 The InnoDB Team + + * buf/buf0buf.c, buf/buf0rea.c, handler/ha_innodb.cc, + include/buf0buf.h, include/buf0buf.ic, include/srv0srv.h, + srv/srv0srv.c: + Fix bug#Bug 12356373 by reintroducing random readahead + 2011-06-30 The InnoDB Team * row/row0row.c: diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index c0da7dbdbe5..cd1461d22b7 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -3590,12 +3590,16 @@ buf_print_io( /* Statistics about read ahead algorithm */ fprintf(file, "Pages read ahead %.2f/s," - " evicted without access %.2f/s\n", + " evicted without access %.2f/s," + " Random read ahead %.2f/s\n", (buf_pool->stat.n_ra_pages_read - buf_pool->old_stat.n_ra_pages_read) / time_elapsed, (buf_pool->stat.n_ra_pages_evicted - buf_pool->old_stat.n_ra_pages_evicted) + / time_elapsed, + (buf_pool->stat.n_ra_pages_read_rnd + - buf_pool->old_stat.n_ra_pages_read_rnd) / time_elapsed); /* Print some values to help us with visualizing what is diff --git a/storage/innodb_plugin/buf/buf0rea.c b/storage/innodb_plugin/buf/buf0rea.c index 81f788baac2..0b36eeb5cd3 100644 --- a/storage/innodb_plugin/buf/buf0rea.c +++ b/storage/innodb_plugin/buf/buf0rea.c @@ -38,6 +38,14 @@ Created 11/5/1995 Heikki Tuuri #include "srv0start.h" #include "srv0srv.h" +/** The size in blocks of the area where the random read-ahead algorithm counts +the accessed pages when deciding whether to read-ahead */ +#define BUF_READ_AHEAD_RANDOM_AREA BUF_READ_AHEAD_AREA + +/** There must be at least this many pages in buf_pool in the area to start +a random read-ahead */ +#define BUF_READ_AHEAD_RANDOM_THRESHOLD (5 + BUF_READ_AHEAD_RANDOM_AREA / 8) + /** The linear read-ahead area size */ #define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA @@ -157,6 +165,165 @@ buf_read_page_low( return(1); } +/********************************************************************//** +Applies a random read-ahead in buf_pool if there are at least a threshold +value of accessed pages from the random read-ahead area. Does not read any +page, not even the one at the position (space, offset), if the read-ahead +mechanism is not activated. NOTE 1: the calling thread may own latches on +pages: to avoid deadlocks this function must be written such that it cannot +end up waiting for these latches! NOTE 2: the calling thread must want +access to the page given: this rule is set to prevent unintended read-aheads +performed by ibuf routines, a situation which could result in a deadlock if +the OS does not support asynchronous i/o. +@return number of page read requests issued; NOTE that if we read ibuf +pages, it may happen that the page at the given page number does not +get read even if we return a positive value! */ +static +ulint +buf_read_ahead_random( +/*==================*/ + ulint space, /*!< in: space id */ + ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ + ulint offset) /*!< in: page number of a page which the current thread + wants to access */ +{ + ib_int64_t tablespace_version; + ulint recent_blocks = 0; + ulint count; + ulint ibuf_mode; + ulint low, high; + ulint err; + ulint i; + ulint buf_read_ahead_random_area; + + if (!srv_random_read_ahead) { + /* Disabled by user */ + return(0); + } + + if (srv_startup_is_before_trx_rollback_phase) { + /* No read-ahead to avoid thread deadlocks */ + return(0); + } + + if (ibuf_bitmap_page(zip_size, offset) + || trx_sys_hdr_page(space, offset)) { + + /* If it is an ibuf bitmap page or trx sys hdr, we do + no read-ahead, as that could break the ibuf page access + order */ + + return(0); + } + + /* Remember the tablespace version before we ask the tablespace size + below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we + do not try to read outside the bounds of the tablespace! */ + + tablespace_version = fil_space_get_version(space); + + buf_read_ahead_random_area = BUF_READ_AHEAD_RANDOM_AREA; + + low = (offset / buf_read_ahead_random_area) + * buf_read_ahead_random_area; + high = (offset / buf_read_ahead_random_area + 1) + * buf_read_ahead_random_area; + if (high > fil_space_get_size(space)) { + + high = fil_space_get_size(space); + } + + buf_pool_mutex_enter(); + + if (buf_pool->n_pend_reads + > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) { + buf_pool_mutex_exit(); + + return(0); + } + + /* Count how many blocks in the area have been recently accessed, + that is, reside near the start of the LRU list. */ + + for (i = low; i < high; i++) { + const buf_page_t* bpage = buf_page_hash_get(space, i); + + if (bpage + && buf_page_is_accessed(bpage) + && buf_page_peek_if_young(bpage)) { + + recent_blocks++; + + if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) { + + buf_pool_mutex_exit(); + goto read_ahead; + } + } + } + + buf_pool_mutex_exit(); + /* Do nothing */ + return(0); + +read_ahead: + /* Read all the suitable blocks within the area */ + + if (ibuf_inside()) { + ibuf_mode = BUF_READ_IBUF_PAGES_ONLY; + } else { + ibuf_mode = BUF_READ_ANY_PAGE; + } + + count = 0; + + for (i = low; i < high; i++) { + /* It is only sensible to do read-ahead in the non-sync aio + mode: hence FALSE as the first parameter */ + + if (!ibuf_bitmap_page(zip_size, i)) { + count += buf_read_page_low( + &err, FALSE, + ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER, + space, zip_size, FALSE, + tablespace_version, i); + if (err == DB_TABLESPACE_DELETED) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Warning: in random" + " readahead trying to access\n" + "InnoDB: tablespace %lu page %lu,\n" + "InnoDB: but the tablespace does not" + " exist or is just being dropped.\n", + (ulong) space, (ulong) i); + } + } + } + + /* In simulated aio we wake the aio handler threads only after + queuing all aio requests, in native aio the following call does + nothing: */ + + os_aio_simulated_wake_handler_threads(); + +#ifdef UNIV_DEBUG + if (buf_debug_prints && (count > 0)) { + fprintf(stderr, + "Random read-ahead space %lu offset %lu pages %lu\n", + (ulong) space, (ulong) offset, + (ulong) count); + } +#endif /* UNIV_DEBUG */ + + /* Read ahead is considered one I/O operation for the purpose of + LRU policy decision. */ + buf_LRU_stat_inc_io(); + + buf_pool->stat.n_ra_pages_read_rnd += count; + return(count); +} + + /********************************************************************//** High-level function which reads a page asynchronously from a file to the buffer buf_pool if it is not already there. Sets the io_fix flag and sets @@ -175,6 +342,9 @@ buf_read_page( ulint count; ulint err; + count = buf_read_ahead_random(space, zip_size, offset); + srv_buf_pool_reads += count; + tablespace_version = fil_space_get_version(space); /* We do the i/o in the synchronous aio mode to save thread diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index a9c9f379528..6f88ea3fde1 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -501,6 +501,8 @@ static SHOW_VAR innodb_status_variables[]= { (char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG}, {"buffer_pool_pages_total", (char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG}, + {"buffer_pool_read_ahead_rnd", + (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG}, {"buffer_pool_read_ahead", (char*) &export_vars.innodb_buffer_pool_read_ahead, SHOW_LONG}, {"buffer_pool_read_ahead_evicted", @@ -11027,6 +11029,11 @@ static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, NULL, NULL, 0, 0, 1, 0); #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ +static MYSQL_SYSVAR_BOOL(random_read_ahead, srv_random_read_ahead, + PLUGIN_VAR_NOCMDARG, + "Whether to use read ahead for random access within an extent.", + NULL, NULL, FALSE); + static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold, PLUGIN_VAR_RQCMDARG, "Number of pages that must be accessed sequentially for InnoDB to " @@ -11091,6 +11098,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG MYSQL_SYSVAR(change_buffering_debug), #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + MYSQL_SYSVAR(random_read_ahead), MYSQL_SYSVAR(read_ahead_threshold), MYSQL_SYSVAR(io_capacity), NULL diff --git a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h index 86c47a6edba..9856bfce409 100644 --- a/storage/innodb_plugin/include/buf0buf.h +++ b/storage/innodb_plugin/include/buf0buf.h @@ -427,6 +427,18 @@ buf_block_get_freed_page_clock( __attribute__((pure)); /********************************************************************//** +Tells if a block is still close enough to the MRU end of the LRU list +meaning that it is not in danger of getting evicted and also implying +that it has been accessed recently. +Note that this is for heuristics only and does not reserve buffer pool +mutex. +@return TRUE if block is close to MRU end of LRU */ +UNIV_INLINE +ibool +buf_page_peek_if_young( +/*===================*/ + const buf_page_t* bpage); /*!< in: block */ +/********************************************************************//** Recommends a move of a block to the start of the LRU list if there is danger of dropping from the buffer pool. NOTE: does not reserve the buffer pool mutex. @@ -1334,6 +1346,8 @@ struct buf_pool_stat_struct{ ulint n_pages_written;/*!< number write operations */ ulint n_pages_created;/*!< number of pages created in the pool with no read */ + ulint n_ra_pages_read_rnd;/*!< number of pages read in + as part of random read ahead */ ulint n_ra_pages_read;/*!< number of pages read in as part of read ahead */ ulint n_ra_pages_evicted;/*!< number of read ahead diff --git a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic index 35c63f034f5..2f3d65e80bd 100644 --- a/storage/innodb_plugin/include/buf0buf.ic +++ b/storage/innodb_plugin/include/buf0buf.ic @@ -61,6 +61,27 @@ buf_block_get_freed_page_clock( return(buf_page_get_freed_page_clock(&block->page)); } +/********************************************************************//** +Tells if a block is still close enough to the MRU end of the LRU list +meaning that it is not in danger of getting evicted and also implying +that it has been accessed recently. +Note that this is for heuristics only and does not reserve buffer pool +mutex. +@return TRUE if block is close to MRU end of LRU */ +UNIV_INLINE +ibool +buf_page_peek_if_young( +/*===================*/ + const buf_page_t* bpage) /*!< in: block */ +{ + /* FIXME: bpage->freed_page_clock is 31 bits */ + return((buf_pool->freed_page_clock & ((1UL << 31) - 1)) + < ((ulint) bpage->freed_page_clock + + (buf_pool->curr_size + * (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio) + / (BUF_LRU_OLD_RATIO_DIV * 4)))); +} + /********************************************************************//** Recommends a move of a block to the start of the LRU list if there is danger of dropping from the buffer pool. NOTE: does not reserve the buffer pool @@ -89,12 +110,7 @@ buf_page_peek_if_too_old( buf_pool->stat.n_pages_not_made_young++; return(FALSE); } else { - /* FIXME: bpage->freed_page_clock is 31 bits */ - return((buf_pool->freed_page_clock & ((1UL << 31) - 1)) - > ((ulint) bpage->freed_page_clock - + (buf_pool->curr_size - * (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio) - / (BUF_LRU_OLD_RATIO_DIV * 4)))); + return(!buf_page_peek_if_young(bpage)); } } diff --git a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h index 91ae895040c..7c63a5f0d45 100644 --- a/storage/innodb_plugin/include/srv0srv.h +++ b/storage/innodb_plugin/include/srv0srv.h @@ -143,6 +143,7 @@ extern ulint srv_mem_pool_size; extern ulint srv_lock_table_size; extern ulint srv_n_file_io_threads; +extern my_bool srv_random_read_ahead; extern ulong srv_read_ahead_threshold; extern ulint srv_n_read_io_threads; extern ulint srv_n_write_io_threads; @@ -618,6 +619,7 @@ struct export_var_struct{ ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */ ulint innodb_buffer_pool_pages_flushed; /*!< srv_buf_pool_flushed */ ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */ + ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */ ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */ ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/ ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */ diff --git a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c index b1fc1ac67fd..8ad4c02e322 100644 --- a/storage/innodb_plugin/srv/srv0srv.c +++ b/storage/innodb_plugin/srv/srv0srv.c @@ -203,6 +203,8 @@ UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX; UNIV_INTERN ulint srv_n_read_io_threads = ULINT_MAX; UNIV_INTERN ulint srv_n_write_io_threads = ULINT_MAX; +/* Switch to enable random read ahead. */ +UNIV_INTERN my_bool srv_random_read_ahead = FALSE; /* User settable value of the number of pages that must be present in the buffer cache and accessed sequentially for InnoDB to trigger a readahead request. */ @@ -1906,6 +1908,8 @@ srv_export_innodb_status(void) export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free; export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed; export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads; + export_vars.innodb_buffer_pool_read_ahead_rnd + = buf_pool->stat.n_ra_pages_read_rnd; export_vars.innodb_buffer_pool_read_ahead = buf_pool->stat.n_ra_pages_read; export_vars.innodb_buffer_pool_read_ahead_evicted From f95192fb06fc37b1d8a3b395c9b1274172f1296f Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Wed, 20 Jul 2011 08:50:47 +0200 Subject: [PATCH 18/32] Bug#12756017 - PROFILING: SET_THD_PROC_INFO DOES NOT NEED TO CALL DIRNAME_LENGTH EACH TIME --- mysql-test/t/implicit_commit.test | 1 + sql/sql_class.cc | 6 +++--- sql/sql_profile.cc | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/mysql-test/t/implicit_commit.test b/mysql-test/t/implicit_commit.test index b10788bd891..59f8dc3a44c 100644 --- a/mysql-test/t/implicit_commit.test +++ b/mysql-test/t/implicit_commit.test @@ -1,5 +1,6 @@ source include/have_innodb.inc; source include/not_embedded.inc; +source include/have_profiling.inc; SET GLOBAL EVENT_SCHEDULER = OFF; SET BINLOG_FORMAT = STATEMENT; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index dd8133835d3..1608b8c49ff 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -520,11 +520,11 @@ const char *set_thd_proc_info(void *thd_arg, const char *info, thd= current_thd; const char *old_info= thd->proc_info; - const char *basename= calling_file ? base_name(calling_file) : NULL; - DBUG_PRINT("proc_info", ("%s:%d %s", basename, calling_line, info)); + DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line, info)); #if defined(ENABLED_PROFILING) - thd->profiling.status_change(info, calling_function, basename, calling_line); + thd->profiling.status_change(info, + calling_function, calling_file, calling_line); #endif thd->proc_info= info; return old_info; diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc index 6c398ca0cb5..5910833612a 100644 --- a/sql/sql_profile.cc +++ b/sql/sql_profile.cc @@ -294,7 +294,7 @@ void QUERY_PROFILE::new_status(const char *status_arg, DBUG_ASSERT(status_arg != NULL); if ((function_arg != NULL) && (file_arg != NULL)) - prof= new PROF_MEASUREMENT(this, status_arg, function_arg, file_arg, line_arg); + prof= new PROF_MEASUREMENT(this, status_arg, function_arg, base_name(file_arg), line_arg); else prof= new PROF_MEASUREMENT(this, status_arg); From 4b426e23929358e1ce9c6f637220d27acd68118f Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Wed, 20 Jul 2011 22:42:47 +0530 Subject: [PATCH 19/32] Fixed the bug number since Bug#11755949 was closed as duplicate of Bug#11753919 --- mysql-test/collections/default.experimental | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 6ef1a377b6c..90f25482137 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -8,8 +8,8 @@ funcs_1.charset_collation_1 # depends on compile-time decisions main.func_math @freebsd # Bug#11751977 2010-05-04 alik main.func_math fails on FreeBSD in PB2 main.lock_multi_bug38499 # Bug#11755645 2009-09-19 alik main.lock_multi_bug38499 times out sporadically main.outfile_loaddata @solaris # Bug#11755168 2010-01-20 alik Test "outfile_loaddata" fails (reproducible) -main.signal_demo3 @solaris # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun -main.sp @solaris # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun +main.signal_demo3 @solaris # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun +main.sp @solaris # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun main.wait_timeout @solaris # Bug#11758972 2010-04-26 alik wait_timeout fails on OpenSolaris rpl.rpl_innodb_bug28430 # Bug#11754425 @@ -17,7 +17,7 @@ rpl.rpl_bug37426 # WL#5867: skozlov: test case moved fro rpl.rpl_heartbeat_basic # BUG#12403008 2011-04-27 sven fails sporadically rpl.rpl_show_slave_hosts # BUG#12416700 2011-05-02 sven fails sporadically -sys_vars.max_sp_recursion_depth_func @solaris # Bug#11755949 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun +sys_vars.max_sp_recursion_depth_func @solaris # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun sys_vars.wait_timeout_func # Bug#11750645 2010-04-26 alik wait_timeout_func fails # BUG #59055 : All ndb tests should be removed from the repository From 96a2bbcbdf37b2f543fca1d0d5aee7bf37b31317 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Thu, 21 Jul 2011 17:45:38 +0200 Subject: [PATCH 20/32] Bug#12779790 COMPILATION FAILS OS X 10.7 - IMPLICIT DECLARATION OF FUNCTION 'PTHREAD_INIT' The problem was that compilation would fail with a warning: Implicit declaration of function 'pthread_init' if MySQL was compiled on OS X 10.7 (Lion). The reason was that pthread_init() is now part of an internal OS X pthread library so it was found by CMake. This patch fixes the problem by removing HAVE_PTHREAD_INIT and related code. pthread_init() was specific to MIT-pthreads which has not been supported since 4.1 and was therefore no longer relevant. No test case added. --- config.h.cmake | 1 - configure.cmake | 1 - dbug/dbug_analyze.c | 3 --- dbug/my_main.c | 3 --- dbug/tests.c | 3 --- mysys/my_init.c | 4 ---- 6 files changed, 15 deletions(-) diff --git a/config.h.cmake b/config.h.cmake index 3247093c613..8c146011c7b 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -219,7 +219,6 @@ #cmakedefine HAVE_PTHREAD_ATTR_SETSTACKSIZE 1 #cmakedefine HAVE_PTHREAD_CONDATTR_CREATE 1 #cmakedefine HAVE_PTHREAD_CONDATTR_SETCLOCK 1 -#cmakedefine HAVE_PTHREAD_INIT 1 #cmakedefine HAVE_PTHREAD_KEY_DELETE 1 #cmakedefine HAVE_PTHREAD_KEY_DELETE 1 #cmakedefine HAVE_PTHREAD_KILL 1 diff --git a/configure.cmake b/configure.cmake index 64de376f669..c3cc787ebc8 100644 --- a/configure.cmake +++ b/configure.cmake @@ -391,7 +391,6 @@ CHECK_FUNCTION_EXISTS (pthread_attr_setscope HAVE_PTHREAD_ATTR_SETSCOPE) CHECK_FUNCTION_EXISTS (pthread_attr_setstacksize HAVE_PTHREAD_ATTR_SETSTACKSIZE) CHECK_FUNCTION_EXISTS (pthread_condattr_create HAVE_PTHREAD_CONDATTR_CREATE) CHECK_FUNCTION_EXISTS (pthread_condattr_setclock HAVE_PTHREAD_CONDATTR_SETCLOCK) -CHECK_FUNCTION_EXISTS (pthread_init HAVE_PTHREAD_INIT) CHECK_FUNCTION_EXISTS (pthread_key_delete HAVE_PTHREAD_KEY_DELETE) CHECK_FUNCTION_EXISTS (pthread_rwlock_rdlock HAVE_PTHREAD_RWLOCK_RDLOCK) CHECK_FUNCTION_EXISTS (pthread_sigmask HAVE_PTHREAD_SIGMASK) diff --git a/dbug/dbug_analyze.c b/dbug/dbug_analyze.c index 3d5713758ae..cd395cd3b02 100644 --- a/dbug/dbug_analyze.c +++ b/dbug/dbug_analyze.c @@ -571,9 +571,6 @@ int main (int argc, char **argv) FILE *infile; FILE *outfile = {stdout}; -#if defined(HAVE_PTHREAD_INIT) - pthread_init(); /* Must be called before DBUG_ENTER */ -#endif my_thread_global_init(); { DBUG_ENTER ("main"); diff --git a/dbug/my_main.c b/dbug/my_main.c index 48d092ca10a..490e1808dd2 100644 --- a/dbug/my_main.c +++ b/dbug/my_main.c @@ -16,9 +16,6 @@ char *argv[]; { register int result, ix; extern int factorial(int); -#if defined(HAVE_PTHREAD_INIT) - pthread_init(); /* Must be called before DBUG_ENTER */ -#endif my_thread_global_init(); { diff --git a/dbug/tests.c b/dbug/tests.c index 837a477aef3..5fb84d48ffc 100644 --- a/dbug/tests.c +++ b/dbug/tests.c @@ -44,9 +44,6 @@ int main (int argc, char *argv[]) if (argc == 1) return 0; -#if defined(HAVE_PTHREAD_INIT) - pthread_init(); /* Must be called before DBUG_ENTER */ -#endif my_thread_global_init(); dup2(1, 2); diff --git a/mysys/my_init.c b/mysys/my_init.c index b5da20b262c..e81752fb271 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -99,10 +99,6 @@ my_bool my_init(void) fastmutex_global_init(); /* Must be called early */ #endif -#if defined(HAVE_PTHREAD_INIT) - pthread_init(); /* Must be called before DBUG_ENTER */ -#endif - /* $HOME is needed early to parse configuration files located in ~/ */ if ((home_dir= getenv("HOME")) != 0) home_dir= intern_filename(home_dir_buff, home_dir); From f7618904bf99d98c958216ec4343def04d026ce2 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Fri, 22 Jul 2011 11:45:15 +0400 Subject: [PATCH 21/32] For for Bug#12696072: FIX OUTDATED COPYRIGHT NOTICES IN RUNTIME RELATED CLIENT TOOLS Backport a fix for Bug 57094 from 5.5. The following revision was backported: # revision-id: alexander.nozdrin@oracle.com-20101006150613-ls60rb2tq5dpyb5c # parent: bar@mysql.com-20101006121559-am1e05ykeicwnx48 # committer: Alexander Nozdrin # branch nick: mysql-5.5-bugteam-bug57094 # timestamp: Wed 2010-10-06 19:06:13 +0400 # message: # Fix for Bug 57094 (Copyright notice incorrect?). # # The fix is to: # - introduce ORACLE_WELCOME_COPYRIGHT_NOTICE define to have a single place # to specify copyright notice; # - replace custom copyright notices with ORACLE_WELCOME_COPYRIGHT_NOTICE # in programs. --- client/mysql.cc | 11 +++++------ client/mysql_upgrade.c | 6 ++++-- client/mysqladmin.cc | 11 ++++------- client/mysqlcheck.c | 10 +++------- client/mysqldump.c | 8 ++++---- client/mysqlimport.c | 17 ++++++----------- client/mysqlshow.c | 8 ++++---- client/mysqltest.c | 18 ++++++------------ sql/gen_lex_hash.cc | 34 ++++++++++------------------------ sql/mysqld.cc | 10 ++++------ 10 files changed, 50 insertions(+), 83 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 3c9272c1a74..57867c658cc 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1,6 +1,5 @@ /* - Copyright (c) 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc. - Use is subject to license terms. + Copyright (c) 2000, 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 @@ -111,6 +110,7 @@ extern "C" { #endif #include "completion_hash.h" +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE #define PROMPT_CHAR '\\' #define DEFAULT_DELIMITER ";" @@ -1162,6 +1162,8 @@ int main(int argc,char *argv[]) mysql_thread_id(&mysql), server_version_string(&mysql)); put_info((char*) glob_buffer.ptr(),INFO_INFO); + put_info(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"), INFO_INFO); + #ifdef HAVE_READLINE initialize_readline((char*) my_progname); if (!status.batch && !quick && !opt_html && !opt_xml) @@ -1535,10 +1537,7 @@ static void usage(int version) if (version) return; - printf("\ -Copyright (C) 2000-2008 MySQL AB\n\ -This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); printf("Usage: %s [OPTIONS] [database]\n", my_progname); my_print_help(my_long_options); print_defaults("my", load_default_groups); diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 5829dfb67a6..03eaab95285 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1,6 +1,5 @@ /* - Copyright (c) 2006-2008 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. + Copyright (c) 2006, 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 @@ -20,6 +19,8 @@ #include #include "../scripts/mysql_fix_privilege_tables_sql.c" +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + #ifdef HAVE_SYS_WAIT_H #include #endif @@ -212,6 +213,7 @@ get_one_option(int optid, const struct my_option *opt, switch (optid) { case '?': + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); printf("MySQL utility for upgrading database to MySQL version %s\n", MYSQL_SERVER_VERSION); my_print_help(my_long_options); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 358b2bedcdc..f83672f9bb1 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -1,6 +1,4 @@ -/* - Copyright (c) 2000-2007 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. +/* Copyright (c) 2000, 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 @@ -26,6 +24,7 @@ #include #include #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ #ifdef LATER_HAVE_NDBCLUSTER_DB #include "../ndb/src/mgmclient/ndb_mgmclient.h" @@ -692,8 +691,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_VER: new_line=1; print_version(); - puts("Copyright (C) 2000-2006 MySQL AB"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); printf("Server version\t\t%s\n", mysql_get_server_info(mysql)); printf("Protocol version\t%d\n", mysql_get_proto_info(mysql)); printf("Connection\t\t%s\n",mysql_get_host_info(mysql)); @@ -1081,8 +1079,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright (C) 2000-2006 MySQL AB"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); puts("Administration program for the mysqld daemon."); printf("Usage: %s [OPTIONS] command command....\n", my_progname); my_print_help(my_long_options); diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index ec29c4475e2..409c86bc8dc 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,6 +1,5 @@ /* - Copyright (c) 2001-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc. - Use is subject to license terms. + Copyright (c) 2001, 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 @@ -16,8 +15,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* By Jani Tolonen, 2001-04-20, MySQL Development Team */ - #define CHECK_VERSION "2.4.4" #include "client_priv.h" @@ -25,6 +22,7 @@ #include #include #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ /* Exit codes */ @@ -206,9 +204,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("By Jani Tolonen, 2001-04-20, MySQL Development Team\n"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); - puts("and you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); puts("This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)"); puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be"); puts("used at the same time. Not all options are supported by all storage engines."); diff --git a/client/mysqldump.c b/client/mysqldump.c index 2b2224bd234..96b92a21f51 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,6 +1,5 @@ /* - Copyright (c) 2000-2008 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. + Copyright (c) 2000, 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 @@ -54,6 +53,8 @@ #include "mysql_version.h" #include "mysqld_error.h" +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + /* Exit codes */ #define EX_USAGE 1 @@ -537,8 +538,7 @@ static void short_usage_sub(void) static void usage(void) { print_version(); - puts("By Igor Romanenko, Monty, Jani & Sinisa"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); puts("Dumping definition and data mysql database or table"); short_usage_sub(); print_defaults("my",load_default_groups); diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 442ac15a94b..39d4733d1c8 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2006 MySQL AB + Copyright (c) 2000, 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 @@ -12,25 +12,21 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* ** mysqlimport.c - Imports all given files ** into a table(s). -** -** ************************* -** * * -** * AUTHOR: Monty & Jani * -** * DATE: June 24, 1997 * -** * * -** ************************* */ + #define IMPORT_VERSION "3.5" #include "client_priv.h" #include "mysql_version.h" +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + static void db_error_with_table(MYSQL *mysql, char *table); static void db_error(MYSQL *mysql); static char *field_escape(char *to,const char *from,uint length); @@ -172,8 +168,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright (C) 2000-2006 MySQL AB"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); printf("\ Loads tables from text files in various formats. The base name of the\n\ text file must be the name of the table that should be used.\n\ diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 60d11e3bdec..a8025ab66a5 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2006 MySQL AB + Copyright (c) 2000, 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 @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Show databases, tables or columns */ @@ -27,6 +27,7 @@ #include #include #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ static my_string host=0,opt_password=0,user=0; static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0, @@ -243,8 +244,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright (C) 2000-2006 MySQL AB"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011)")); puts("Shows the structure of a mysql database (databases,tables and columns)\n"); printf("Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname); puts("\n\ diff --git a/client/mysqltest.c b/client/mysqltest.c index 6dcd80d3cac..cd9e1fcde54 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2000-2008 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. +/* + Copyright (c) 2000, 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 @@ -12,7 +12,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ /* mysqltest @@ -23,13 +24,6 @@ http://dev.mysql.com/doc/mysqltest/en/index.html Please keep the test framework tools identical in all versions! - - Written by: - Sasha Pachev - Matt Wagner - Monty - Jani - Holyfoot */ #define MTEST_VERSION "3.2" @@ -56,6 +50,7 @@ #include #endif +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE #ifndef WEXITSTATUS # ifdef __WIN__ @@ -5256,8 +5251,7 @@ void print_version(void) void usage() { print_version(); - printf("MySQL AB, by Sasha, Matt, Monty & Jani\n"); - printf("This software comes with ABSOLUTELY NO WARRANTY\n\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); printf("Runs a test against the mysql server and compares output with a results file.\n\n"); printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname); my_print_help(my_long_options); diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 55d9ae656ec..f2216ced8ca 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000-2007 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. +/* + Copyright (c) 2000, 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 @@ -12,7 +12,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ /* @@ -83,6 +84,8 @@ TODO: #include "mysql_version.h" #include "lex.h" +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + const char *default_dbug_option="d:t:o,/tmp/gen_lex_hash.trace"; struct my_option my_long_options[] = @@ -342,9 +345,7 @@ static void usage(int version) my_progname, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); if (version) return; - puts("Copyright (C) 2001 MySQL AB, by VVA and Monty"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); puts("This program generates a perfect hashing function for the sql_lex.cc"); printf("Usage: %s [OPTIONS]\n\n", my_progname); my_print_help(my_long_options); @@ -446,24 +447,9 @@ int main(int argc,char **argv) /* Broken up to indicate that it's not advice to you, gentle reader. */ printf("/*\n\n Do " "not " "edit " "this " "file " "directly!\n\n*/\n"); - printf("\ -/* Copyright (C) 2000-2007 MySQL AB, 2008 Sun Microsystems, Inc.\n\ -\n\ - This program is free software; you can redistribute it and/or modify\n\ - it under the terms of the GNU General Public License as published by\n\ - the Free Software Foundation; version 2 of the License.\n\ -\n\ - This program is distributed in the hope that it will be useful,\n\ - but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ - GNU General Public License for more details.\n\ -\n\ - You should have received a copy of the GNU General Public License\n\ - along with this program; see the file COPYING. If not, write to the\n\ - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston\n\ - MA 02110-1301 USA. */\n\ -\n\ -"); + puts("/*"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); + puts("*/"); /* Broken up to indicate that it's not advice to you, gentle reader. */ printf("/* Do " "not " "edit " "this " "file! This is generated by " diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8d2293386c2..1ad8161d93f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -240,6 +240,8 @@ extern "C" sig_handler handle_segfault(int sig); /* Constants */ +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE + const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"}; static const char *sql_mode_names[]= { @@ -6748,12 +6750,8 @@ static void usage(void) if (!default_collation_name) default_collation_name= (char*) default_charset_info->name; print_version(); - puts("\ -Copyright (C) 2000 MySQL AB, by Monty and others\n\ -This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n\n\ -Starts the MySQL database server\n"); - + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); + puts("Starts the MySQL database server.\n"); printf("Usage: %s [OPTIONS]\n", my_progname); if (!opt_verbose) puts("\nFor more help options (several pages), use mysqld --verbose --help\n"); From c8519150b4f4d8f80354a6a47a17ea93d23b81ef Mon Sep 17 00:00:00 2001 From: Sunanda Menon Date: Fri, 22 Jul 2011 10:34:45 +0200 Subject: [PATCH 22/32] Bug #12561297: Added the MySQL embedded binary --- support-files/mysql.spec.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index cc4477f2fac..dde7d4696e4 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -1121,6 +1121,7 @@ echo "=====" >> $STATUS_HISTORY # ---------------------------------------------------------------------------- %files -n MySQL-embedded%{product_suffix} %defattr(-, root, root, 0755) +%attr(755, root, root) %{_bindir}/mysql_embedded %attr(644, root, root) %{_libdir}/mysql/libmysqld.a %attr(644, root, root) %{_libdir}/mysql/libmysqld-debug.a @@ -1130,6 +1131,10 @@ echo "=====" >> $STATUS_HISTORY # merging BK trees) ############################################################################## %changelog +* Thu Jul 21 2011 Sunanda Menon + +- Fix bug#12561297: Added the MySQL embedded binary + * Thu Jul 07 2011 Joerg Bruehe - Fix bug#45415: "rpm upgrade recreates test database" From 9fe60b4d5b18abc9283991ccd3df6de16f4e163d Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Fri, 22 Jul 2011 16:31:10 +0400 Subject: [PATCH 23/32] Fix for bug #11754210 - "45777: CHECK TABLE DOESN'T SHOW ALL PROBLEMS FOR MERGE TABLE COMPLIANCE IN 5.1". The problem was that CHECK/REPAIR TABLE for a MERGE table which had several children missing or in wrong engine reported only issue with the first such table in its result-set. While in 5.0 this statement returned the whole list of problematic tables. Ability to report problems for all children was lost during significant refactorings of MERGE code which were done as part of work on 5.1 and 5.5 releases. This patch restores status quo ante refactorings by changing code in such a way that: 1) Failure to open child table due to its absence during CHECK/ REPAIR TABLE for a MERGE table is not reported immediately when its absence is discovered in open_tables(). Instead handling/error reporting in such a situation is postponed until the moment when children are attached. 2) Code performing attaching of children no longer stops when it encounters first problem with one of the children during CHECK/REPAIR TABLE. Instead it continues iteration through the child list until all problems caused by child absence/ wrong engine are reported. Note that even after this change problem with mismatch of child/parent definition won't be reported if there is also another child missing, but this is how it was in 5.0 as well. --- mysql-test/r/merge.result | 46 +++++++++++++++--- mysql-test/t/merge.test | 27 ++++++++++- sql/sql_base.cc | 77 +++++++++++++++++++++++++++++++ storage/myisammrg/ha_myisammrg.cc | 70 +++++++++++++++++++--------- storage/myisammrg/myrg_open.c | 24 ++++++---- 5 files changed, 208 insertions(+), 36 deletions(-) diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index f668761cb16..6e4e6c5a443 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -904,7 +904,8 @@ SELECT * FROM tm1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist CHECK TABLE tm1; Table Op Msg_type Msg_text -test.tm1 check Error Table 'test.t1' doesn't exist +test.tm1 check Error Table 'test.t1' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.tm1 check error Corrupt CREATE TABLE t1(a INT); @@ -912,7 +913,7 @@ SELECT * FROM tm1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist CHECK TABLE tm1; Table Op Msg_type Msg_text -test.tm1 check Error Table 'test.t2' doesn't exist +test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.tm1 check error Corrupt CREATE TABLE t2(a BLOB); @@ -920,7 +921,7 @@ SELECT * FROM tm1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist CHECK TABLE tm1; Table Op Msg_type Msg_text -test.tm1 check Warning Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.tm1 check error Corrupt ALTER TABLE t2 MODIFY a INT; @@ -3634,7 +3635,7 @@ test.t1 analyze Error Unable to open underlying table which is differently defin test.t1 analyze error Corrupt CHECK TABLE t1; Table Op Msg_type Msg_text -test.t1 check Error Table 'test.t_not_exists' doesn't exist +test.t1 check Error Table 'test.t_not_exists' is differently defined or of non-MyISAM type or doesn't exist test.t1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.t1 check error Corrupt CHECKSUM TABLE t1; @@ -3650,7 +3651,7 @@ test.t1 optimize Error Unable to open underlying table which is differently defi test.t1 optimize error Corrupt REPAIR TABLE t1; Table Op Msg_type Msg_text -test.t1 repair Error Table 'test.t_not_exists' doesn't exist +test.t1 repair Error Table 'test.t_not_exists' is differently defined or of non-MyISAM type or doesn't exist test.t1 repair Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.t1 repair error Corrupt REPAIR TABLE t1 USE_FRM; @@ -3676,4 +3677,37 @@ ALTER TABLE t1 engine=myisam; ERROR HY000: Table 't1' was locked with a READ lock and can't be updated UNLOCK TABLES; DROP TABLE m1, t1; -End of 6.0 tests +# +# Test for bug #11754210 - "45777: CHECK TABLE DOESN'T SHOW ALL +# PROBLEMS FOR MERGE TABLE COMPLIANCE IN 5.1" +# +drop tables if exists t1, t2, t3, t4, m1; +create table t1(id int) engine=myisam; +create view t3 as select 1 as id; +create table t4(id int) engine=memory; +create table m1(id int) engine=merge union=(t1,t2,t3,t4); +select * from m1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +# The below CHECK and REPAIR TABLE statements should +# report all problems with underlying tables: +# - absence of 't2', +# - missing base table for 't3', +# - wrong engine of 't4'. +check table m1; +Table Op Msg_type Msg_text +test.m1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist +test.m1 check Error Table 'test.t3' is differently defined or of non-MyISAM type or doesn't exist +test.m1 check Error Table 'test.t4' is differently defined or of non-MyISAM type or doesn't exist +test.m1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +test.m1 check error Corrupt +repair table m1; +Table Op Msg_type Msg_text +test.m1 repair Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist +test.m1 repair Error Table 'test.t3' is differently defined or of non-MyISAM type or doesn't exist +test.m1 repair Error Table 'test.t4' is differently defined or of non-MyISAM type or doesn't exist +test.m1 repair Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +test.m1 repair error Corrupt +# Clean-up. +drop tables m1, t1, t4; +drop view t3; +End of 5.5 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 07839257a15..74110962299 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -2798,7 +2798,32 @@ UNLOCK TABLES; DROP TABLE m1, t1; ---echo End of 6.0 tests +--echo # +--echo # Test for bug #11754210 - "45777: CHECK TABLE DOESN'T SHOW ALL +--echo # PROBLEMS FOR MERGE TABLE COMPLIANCE IN 5.1" +--echo # +--disable_warnings +drop tables if exists t1, t2, t3, t4, m1; +--enable_warnings +create table t1(id int) engine=myisam; +create view t3 as select 1 as id; +create table t4(id int) engine=memory; +create table m1(id int) engine=merge union=(t1,t2,t3,t4); +--error ER_WRONG_MRG_TABLE +select * from m1; +--echo # The below CHECK and REPAIR TABLE statements should +--echo # report all problems with underlying tables: +--echo # - absence of 't2', +--echo # - missing base table for 't3', +--echo # - wrong engine of 't4'. +check table m1; +repair table m1; +--echo # Clean-up. +drop tables m1, t1, t4; +drop view t3; + + +--echo End of 5.5 tests --disable_result_log --disable_query_log diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 43ad400ce64..d47525c3d4e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -89,6 +89,69 @@ bool No_such_table_error_handler::safely_trapped_errors() return ((m_handled_errors > 0) && (m_unhandled_errors == 0)); } + +/** + This internal handler is used to trap ER_NO_SUCH_TABLE and + ER_WRONG_MRG_TABLE errors during CHECK/REPAIR TABLE for MERGE + tables. +*/ + +class Repair_mrg_table_error_handler : public Internal_error_handler +{ +public: + Repair_mrg_table_error_handler() + : m_handled_errors(false), m_unhandled_errors(false) + {} + + bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); + + /** + Returns TRUE if there were ER_NO_SUCH_/WRONG_MRG_TABLE and there + were no unhandled errors. FALSE otherwise. + */ + bool safely_trapped_errors() + { + /* + Check for m_handled_errors is here for extra safety. + It can be useful in situation when call to open_table() + fails because some error which was suppressed by another + error handler (e.g. in case of MDL deadlock which we + decided to solve by back-off and retry). + */ + return (m_handled_errors && (! m_unhandled_errors)); + } + +private: + bool m_handled_errors; + bool m_unhandled_errors; +}; + + +bool +Repair_mrg_table_error_handler::handle_condition(THD *, + uint sql_errno, + const char*, + MYSQL_ERROR::enum_warning_level level, + const char*, + MYSQL_ERROR ** cond_hdl) +{ + *cond_hdl= NULL; + if (sql_errno == ER_NO_SUCH_TABLE || sql_errno == ER_WRONG_MRG_TABLE) + { + m_handled_errors= true; + return TRUE; + } + + m_unhandled_errors= true; + return FALSE; +} + + /** @defgroup Data_Dictionary Data Dictionary @{ @@ -4377,6 +4440,20 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, thd->pop_internal_handler(); safe_to_ignore_table= no_such_table_handler.safely_trapped_errors(); } + else if (tables->parent_l && (thd->open_options & HA_OPEN_FOR_REPAIR)) + { + /* + Also fail silently for underlying tables of a MERGE table if this + table is opened for CHECK/REPAIR TABLE statement. This is needed + to provide complete list of problematic underlying tables in + CHECK/REPAIR TABLE output. + */ + Repair_mrg_table_error_handler repair_mrg_table_handler; + thd->push_internal_handler(&repair_mrg_table_handler); + error= open_table(thd, tables, new_frm_mem, ot_ctx); + thd->pop_internal_handler(); + safe_to_ignore_table= repair_mrg_table_handler.safely_trapped_errors(); + } else error= open_table(thd, tables, new_frm_mem, ot_ctx); diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 233f63ba680..c76e9ee0bfe 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -159,9 +159,14 @@ extern "C" void myrg_print_wrong_table(const char *table_name) buf[db.length]= '.'; memcpy(buf + db.length + 1, name.str, name.length); buf[db.length + name.length + 1]= 0; - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ADMIN_WRONG_MRG_TABLE, ER(ER_ADMIN_WRONG_MRG_TABLE), - buf); + /* + Push an error to be reported as part of CHECK/REPAIR result-set. + Note that calling my_error() from handler is a hack which is kept + here to avoid refactoring. Normally engines should report errors + through return value which will be interpreted by caller using + handler::print_error() call. + */ + my_error(ER_ADMIN_WRONG_MRG_TABLE, MYF(0), buf); } @@ -593,8 +598,7 @@ public: @return pointer to open MyISAM table structure @retval !=NULL OK, returning pointer - @retval NULL, my_errno == 0 Ok, no more child tables - @retval NULL, my_errno != 0 error + @retval NULL, Error. @detail This function retrieves the MyISAM table handle from the @@ -614,16 +618,32 @@ extern "C" MI_INFO *myisammrg_attach_children_callback(void *callback_param) MI_INFO *myisam= NULL; DBUG_ENTER("myisammrg_attach_children_callback"); - if (!child_l) - { - DBUG_PRINT("myrg", ("No more children to attach")); - my_errno= 0; /* Ok, no more child tables. */ - goto end; - } + /* + Number of children in the list and MYRG_INFO::tables_count, + which is used by caller of this function, should always match. + */ + DBUG_ASSERT(child_l); + child= child_l->table; /* Prepare for next child. */ param->next(); + /* + When MERGE table is opened for CHECK or REPAIR TABLE statements, + failure to open any of underlying tables is ignored until this moment + (this is needed to provide complete list of the problematic underlying + tables in CHECK/REPAIR TABLE output). + Here we detect such a situation and report an appropriate error. + */ + if (! child) + { + DBUG_PRINT("error", ("failed to open underlying table '%s'.'%s'", + child_l->db, child_l->table_name)); + /* This should only happen inside of CHECK/REPAIR TABLE. */ + DBUG_ASSERT(current_thd->open_options & HA_OPEN_FOR_REPAIR); + goto end; + } + /* Do a quick compatibility check. The table def version is set when the table share is created. The child def version is copied @@ -653,7 +673,6 @@ extern "C" MI_INFO *myisammrg_attach_children_callback(void *callback_param) { DBUG_PRINT("error", ("temporary table mismatch parent: %d child: %d", parent->s->tmp_table, child->s->tmp_table)); - my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; goto end; } @@ -664,12 +683,27 @@ extern "C" MI_INFO *myisammrg_attach_children_callback(void *callback_param) DBUG_PRINT("error", ("no MyISAM handle for child table: '%s'.'%s' 0x%lx", child->s->db.str, child->s->table_name.str, (long) child)); - my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; } - DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d", - my_errno ? 0L : (long) myisam, my_errno)); + + DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx", (long) myisam)); end: + + if (!myisam && + (current_thd->open_options & HA_OPEN_FOR_REPAIR)) + { + char buf[2*NAME_LEN + 1 + 1]; + strxnmov(buf, sizeof(buf) - 1, child_l->db, ".", child_l->table_name, NULL); + /* + Push an error to be reported as part of CHECK/REPAIR result-set. + Note that calling my_error() from handler is a hack which is kept + here to avoid refactoring. Normally engines should report errors + through return value which will be interpreted by caller using + handler::print_error() call. + */ + my_error(ER_ADMIN_WRONG_MRG_TABLE, MYF(0), buf); + } + DBUG_RETURN(myisam); } @@ -783,12 +817,6 @@ int ha_myisammrg::attach_children(void) /* Must call this with children list in place. */ DBUG_ASSERT(this->table->pos_in_table_list->next_global == this->children_l); - /* - 'my_errno' is set by myisammrg_attach_children_callback() in - case of an error. - */ - my_errno= 0; - if (myrg_attach_children(this->file, this->test_if_locked | current_thd->open_options, myisammrg_attach_children_callback, ¶m, diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c index 533e5d13cdd..d51036fc69d 100644 --- a/storage/myisammrg/myrg_open.c +++ b/storage/myisammrg/myrg_open.c @@ -385,6 +385,7 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, uint UNINIT_VAR(key_parts); uint min_keys; my_bool bad_children= FALSE; + my_bool first_child= TRUE; DBUG_ENTER("myrg_attach_children"); DBUG_PRINT("myrg", ("handle_locking: %d", handle_locking)); @@ -399,16 +400,26 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, errpos= 0; file_offset= 0; min_keys= 0; - child_nr= 0; - while ((myisam= (*callback)(callback_param))) + for (child_nr= 0; child_nr < m_info->tables; child_nr++) { + if (! (myisam= (*callback)(callback_param))) + { + if (handle_locking & HA_OPEN_FOR_REPAIR) + { + /* An appropriate error should've been already pushed by callback. */ + bad_children= TRUE; + continue; + } + goto bad_children; + } + DBUG_PRINT("myrg", ("child_nr: %u table: '%s'", child_nr, myisam->filename)); - DBUG_ASSERT(child_nr < m_info->tables); /* Special handling when the first child is attached. */ - if (!child_nr) + if (first_child) { + first_child= FALSE; m_info->reclength= myisam->s->base.reclength; min_keys= myisam->s->base.keys; key_parts= myisam->s->base.key_parts; @@ -456,14 +467,11 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, for (idx= 0; idx < key_parts; idx++) m_info->rec_per_key_part[idx]+= (myisam->s->state.rec_per_key_part[idx] / m_info->tables); - child_nr++; } if (bad_children) goto bad_children; - /* Note: callback() resets my_errno, so it is safe to check it here */ - if (my_errno == HA_ERR_WRONG_MRG_TABLE_DEF) - goto err; + if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L) { my_errno= HA_ERR_RECORD_FILE_FULL; From f2c7452f1cca15868989096bdbe88adef72132ef Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Sun, 24 Jul 2011 12:26:58 +0100 Subject: [PATCH 24/32] Post-push fix for BUG#11809016. In 5.5, REFRESH SLAVE is used as an alias for RESET SLAVE and was removed in 5.6. Reseting a slave through REFRESH SLAVE was causing errors in the valgrind platform since reset_slave_info was undefined. To fix the problem, we have set reset_slave_info while calling REFRESH SLAVE. --- sql/sql_yacc.yy | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 90a55471792..ba1b9e43713 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -11306,7 +11306,10 @@ flush_option: | STATUS_SYM { Lex->type|= REFRESH_STATUS; } | SLAVE - { Lex->type|= REFRESH_SLAVE; } + { + Lex->type|= REFRESH_SLAVE; + Lex->reset_slave_info.all= false; + } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } | DES_KEY_FILE From 75eaa30d26b65e6da5ebe35728824a3603719599 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 27 Jul 2011 12:34:25 +0400 Subject: [PATCH 25/32] Bug#12584302 AFTER FIX FOR #12403504: ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0, The problem is that TIME_FUZZY_DATE is explicitly used for get_arg0_date() function in Item_date_typecast::get_date method. The fix is to use real fuzzy_date value. --- mysql-test/r/func_time.result | 6 ++++++ mysql-test/t/func_time.test | 6 ++++++ sql/item_timefunc.cc | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 63744d4ef29..68c1e667440 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1426,4 +1426,10 @@ NULL SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1) NULL +# +# Bug#12584302 AFTER FIX FOR #12403504: ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0, +# +DO WEEK((DATE_ADD((CAST(0 AS DATE)), INTERVAL 1 YEAR_MONTH)), 5); +Warnings: +Warning 1292 Incorrect datetime value: '0' End of 5.1 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index de92f313992..2dcac0d5796 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -928,4 +928,10 @@ SELECT DATE_FORMAT('0000-00-11', '%w'); SELECT MAKEDATE(11111111,1); SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); +--echo # +--echo # Bug#12584302 AFTER FIX FOR #12403504: ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0, +--echo # + +DO WEEK((DATE_ADD((CAST(0 AS DATE)), INTERVAL 1 YEAR_MONTH)), 5); + --echo End of 5.1 tests diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 83b0b7cdebc..31474f1d6ca 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2646,7 +2646,7 @@ String *Item_time_typecast::val_str(String *str) bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date) { - bool res= get_arg0_date(ltime, TIME_FUZZY_DATE); + bool res= get_arg0_date(ltime, fuzzy_date); ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0; ltime->time_type= MYSQL_TIMESTAMP_DATE; return res; From 7841c3f574a7a12b8ed44001b92da7f28764de63 Mon Sep 17 00:00:00 2001 From: Sven Sandberg Date: Wed, 27 Jul 2011 12:35:44 +0200 Subject: [PATCH 26/32] Updated default.experimental; now rpl tests are up to date as of 2011-07-25. --- mysql-test/collections/default.experimental | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 8883acfa606..961a93b8741 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -23,7 +23,8 @@ main.query_cache_28249 # Bug#12584161 2009-03-25 main.query_ca ndb.* # joro : NDB tests marked as experimental as agreed with bochklin -rpl.rpl_innodb_bug28430 @solaris # Bug#11754425 +rpl.rpl_innodb_bug28430 # Bug#11754425 +rpl.rpl_insert # Sven: BUG#12764817 rpl.rpl_row_sp011 @solaris # Joro : Bug #11753919 rpl.rpl_stop_slave # Sven : BUG#12345981 From e1643f98feb9908a6c830ea90c946a8a7131221a Mon Sep 17 00:00:00 2001 From: Sven Sandberg Date: Wed, 27 Jul 2011 12:36:33 +0200 Subject: [PATCH 27/32] Updated default.experimental; now rpl tests are up to date as of 2011-07-25. --- mysql-test/collections/default.experimental | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 90f25482137..b3623402065 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -12,10 +12,9 @@ main.signal_demo3 @solaris # Bug#11753919 2010-01-20 alik Several main.sp @solaris # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun main.wait_timeout @solaris # Bug#11758972 2010-04-26 alik wait_timeout fails on OpenSolaris -rpl.rpl_innodb_bug28430 # Bug#11754425 -rpl.rpl_bug37426 # WL#5867: skozlov: test case moved from unused bugs suite rpl.rpl_heartbeat_basic # BUG#12403008 2011-04-27 sven fails sporadically -rpl.rpl_show_slave_hosts # BUG#12416700 2011-05-02 sven fails sporadically +rpl.rpl_innodb_bug28430 # Bug#11754425 +rpl.rpl_row_sp011 @solaris # Bug#11753919 2011-07-25 sven Several test cases fail on Solaris with error Thread stack overrun sys_vars.max_sp_recursion_depth_func @solaris # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun sys_vars.wait_timeout_func # Bug#11750645 2010-04-26 alik wait_timeout_func fails From 07b95519dd09a73837192f5b599192270069c9ea Mon Sep 17 00:00:00 2001 From: "hery.ramilison@oracle.com" <> Date: Thu, 28 Jul 2011 19:14:12 +0200 Subject: [PATCH 28/32] Merge from mysql-5.5.15-release From de3693a1cd292af3efd8841414da866ee2c2e1de Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 2 Aug 2011 11:33:45 +0400 Subject: [PATCH 29/32] Bug#11766594 59736: SELECT DISTINCT.. INCORRECT RESULT WITH DETERMINISTIC FUNCTION IN WHERE C There is an optimization of DISTINCT in JOIN::optimize() which depends on THD::used_tables value. Each SELECT statement inside SP resets used_tables value(see mysql_select()) and it leads to wrong result. The fix is to replace THD::used_tables with LEX::used_tables. --- mysql-test/r/sp.result | 19 +++++++++++++++++++ mysql-test/t/sp.test | 27 +++++++++++++++++++++++++++ sql/sql_base.cc | 8 ++++---- sql/sql_class.cc | 1 - sql/sql_class.h | 7 ------- sql/sql_insert.cc | 4 ++-- sql/sql_lex.cc | 1 + sql/sql_lex.h | 10 ++++++++++ sql/sql_prepare.cc | 4 ++-- sql/sql_select.cc | 8 ++++---- 10 files changed, 69 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 2180a23b91a..1ce14d38166 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -7053,6 +7053,25 @@ init_connect SET @@GLOBAL.init_connect= @old_init_connect; DROP PROCEDURE p2; DROP PROCEDURE p5; +# +# Bug#11766594 59736: SELECT DISTINCT.. INCORRECT RESULT WITH DETERMINISTIC FUNCTION IN WHERE C +# +CREATE TABLE t1 (a INT, b INT, KEY(b)); +CREATE TABLE t2 (c INT, d INT, KEY(c)); +INSERT INTO t1 VALUES (1,1),(1,1),(1,2); +INSERT INTO t2 VALUES (1,1),(1,2); +CREATE FUNCTION f1() RETURNS INT DETERMINISTIC +BEGIN +DECLARE a int; +-- SQL statement inside +SELECT 1 INTO a; +RETURN a; +END $ +SELECT COUNT(DISTINCT d) FROM t1, t2 WHERE a = c AND b = f1(); +COUNT(DISTINCT d) +2 +DROP FUNCTION f1; +DROP TABLE t1, t2; # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 5cf050146dd..9207ea22290 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8350,6 +8350,33 @@ SET @@GLOBAL.init_connect= @old_init_connect; DROP PROCEDURE p2; DROP PROCEDURE p5; +--echo # +--echo # Bug#11766594 59736: SELECT DISTINCT.. INCORRECT RESULT WITH DETERMINISTIC FUNCTION IN WHERE C +--echo # + +CREATE TABLE t1 (a INT, b INT, KEY(b)); +CREATE TABLE t2 (c INT, d INT, KEY(c)); +INSERT INTO t1 VALUES (1,1),(1,1),(1,2); +INSERT INTO t2 VALUES (1,1),(1,2); + +DELIMITER $; + +CREATE FUNCTION f1() RETURNS INT DETERMINISTIC +BEGIN + DECLARE a int; + -- SQL statement inside + SELECT 1 INTO a; + RETURN a; +END $ + +DELIMITER ;$ + +SELECT COUNT(DISTINCT d) FROM t1, t2 WHERE a = c AND b = f1(); + +DROP FUNCTION f1; +DROP TABLE t1, t2; + + --echo # ------------------------------------------------------------------ --echo # -- End of 5.1 tests --echo # ------------------------------------------------------------------ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 87d28402e01..ab1ba156905 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7576,7 +7576,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM && sum_func_list) item->split_sum_func(thd, ref_pointer_array, *sum_func_list); - thd->used_tables|= item->used_tables(); + thd->lex->used_tables|= item->used_tables(); thd->lex->current_select->cur_pos_in_select_list++; } thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup; @@ -7923,7 +7923,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, views and natural joins this update is performed inside the loop below. */ if (table) - thd->used_tables|= table->map; + thd->lex->used_tables|= table->map; /* Initialize a generic field iterator for the current table reference. @@ -8008,7 +8008,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, field_table= nj_col->table_ref->table; if (field_table) { - thd->used_tables|= field_table->map; + thd->lex->used_tables|= field_table->map; field_table->covering_keys.intersect(field->part_of_key); field_table->merge_keys.merge(field->part_of_key); field_table->used_fields++; @@ -8016,7 +8016,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, } } else - thd->used_tables|= item->used_tables(); + thd->lex->used_tables|= item->used_tables(); thd->lex->current_select->cur_pos_in_select_list++; } /* diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b9df35fe8be..7fb1d2ade5f 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -649,7 +649,6 @@ THD::THD() is_slave_error= thread_specific_used= FALSE; hash_clear(&handler_tables_hash); tmp_table=0; - used_tables=0; cuted_fields= sent_row_count= row_count= 0L; limit_found_rows= 0; row_count_func= -1; diff --git a/sql/sql_class.h b/sql/sql_class.h index bf197fee9c3..3c1b2c1330f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1734,13 +1734,6 @@ public: */ ha_rows examined_row_count; - /* - The set of those tables whose fields are referenced in all subqueries - of the query. - TODO: possibly this it is incorrect to have used tables in THD because - with more than one subquery, it is not clear what does the field mean. - */ - table_map used_tables; USER_CONN *user_connect; CHARSET_INFO *db_charset; /* diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index baf5af16e2b..e176e5c9b6d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -631,7 +631,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, lock_type= table_list->lock_type; thd_proc_info(thd, "init"); - thd->used_tables=0; + thd->lex->used_tables=0; values= its++; value_count= values->elements; @@ -779,7 +779,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, } else { - if (thd->used_tables) // Column used in values() + if (thd->lex->used_tables) // Column used in values() restore_record(table,s->default_values); // Get empty record else { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index f0289ab86ce..6e40f9b9614 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -360,6 +360,7 @@ void lex_start(THD *thd) lex->server_options.port= -1; lex->is_lex_started= TRUE; + lex->used_tables= 0; DBUG_VOID_RETURN; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index b4dbbc5162e..035fa1fde91 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1836,6 +1836,16 @@ typedef struct st_lex : public Query_tables_list uint create_select_pos; bool create_select_in_comment; + /* + The set of those tables whose fields are referenced in all subqueries + of the query. + TODO: possibly this it is incorrect to have used tables in LEX because + with subquery, it is not clear what does the field mean. To fix this + we should aggregate used tables information for selected expressions + into the select_lex. + */ + table_map used_tables; + st_lex(); virtual ~st_lex() diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index b296eb22cdb..ec7a7fb73b8 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1382,7 +1382,7 @@ static int mysql_test_select(Prepared_statement *stmt, if (open_normal_and_derived_tables(thd, tables, 0)) goto error; - thd->used_tables= 0; // Updated by setup_fields + thd->lex->used_tables= 0; // Updated by setup_fields /* JOIN::prepare calls @@ -1551,7 +1551,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt, if (specific_prepare && (*specific_prepare)(thd)) DBUG_RETURN(TRUE); - thd->used_tables= 0; // Updated by setup_fields + thd->lex->used_tables= 0; // Updated by setup_fields /* Calls JOIN::prepare */ DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option)); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2346f744b47..516c9c37473 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -406,7 +406,7 @@ fix_inner_refs(THD *thd, List &all_fields, SELECT_LEX *select, if (!ref->fixed && ref->fix_fields(thd, 0)) return TRUE; - thd->used_tables|= item->used_tables(); + thd->lex->used_tables|= item->used_tables(); } return false; } @@ -1632,7 +1632,7 @@ JOIN::optimize() if (exec_tmp_table1->distinct) { - table_map used_tables= thd->used_tables; + table_map used_tables= thd->lex->used_tables; JOIN_TAB *last_join_tab= join_tab+tables-1; do { @@ -2526,7 +2526,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, if (!(join= new JOIN(thd, fields, select_options, result))) DBUG_RETURN(TRUE); thd_proc_info(thd, "init"); - thd->used_tables=0; // Updated by setup_fields + thd->lex->used_tables=0; // Updated by setup_fields err= join->prepare(rref_pointer_array, tables, wild_num, conds, og_num, order, group, having, proc_param, select_lex, unit); @@ -16949,7 +16949,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, need_order=0; extra.append(STRING_WITH_LEN("; Using filesort")); } - if (distinct & test_all_bits(used_tables,thd->used_tables)) + if (distinct & test_all_bits(used_tables, thd->lex->used_tables)) extra.append(STRING_WITH_LEN("; Distinct")); for (uint part= 0; part < tab->ref.key_parts; part++) From 1392945b60a0ad4772318cc3e0566cc545a14c25 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Wed, 3 Aug 2011 17:53:44 +0400 Subject: [PATCH 30/32] backport from mysql-trunk BUG #11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG The mysql_affected_rows() client call returns 3 instead of 2 on INSERT ... ON DUPLICATE KEY UPDATE query with a duplicated key value. The fix for the old bug #29692 was incomplete: unnecessary double increment of "touched" rows still happened. This bugfix removes: 1) unneeded increment of "touched" rows and 2) useless double resetting of auto-increment value. --- sql/sql_insert.cc | 5 ----- tests/mysql_client_test.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 5dc2a7e2abb..eaf7f4c895b 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1610,9 +1610,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) goto before_trg_err; table->file->restore_auto_increment(prev_insert_id); - if (table->next_number_field) - table->file->adjust_next_insert_id_after_explicit_value( - table->next_number_field->val_int()); info->touched++; if (!records_are_comparable(table) || compare_records(table)) { @@ -1649,8 +1646,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (table->next_number_field) table->file->adjust_next_insert_id_after_explicit_value( table->next_number_field->val_int()); - info->touched++; - goto ok_or_after_trg_err; } else /* DUP_REPLACE */ diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b3da65485dd..14a60f0e857 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -19660,6 +19660,34 @@ static void test_bug12337762() DBUG_VOID_RETURN; } + +/* + BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG +*/ + +static void test_bug11754979() +{ + MYSQL* conn; + DBUG_ENTER("test_bug11754979"); + + myheader("test_bug11754979"); + DIE_UNLESS((conn= mysql_client_init(NULL))); + DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user, + opt_password, opt_db ? opt_db:"test", opt_port, + opt_unix_socket, CLIENT_FOUND_ROWS)); + myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1")); + myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))")); + myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')")); + myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') " + "ON DUPLICATE KEY UPDATE id = 4")); + DIE_UNLESS(mysql_affected_rows(conn) == 2); + myquery(mysql_query(conn, "DROP TABLE t1")); + mysql_close(conn); + + DBUG_VOID_RETURN; +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -20005,6 +20033,7 @@ static struct my_tests_st my_tests[]= { { "test_bug56976", test_bug56976 }, { "test_bug11766854", test_bug11766854 }, { "test_bug12337762", test_bug12337762 }, + { "test_bug11754979", test_bug11754979 }, { 0, 0 } }; From 6c821acddd58e0cc7e62a161054eda42e187c223 Mon Sep 17 00:00:00 2001 From: "hery.ramilison@oracle.com" <> Date: Sat, 6 Aug 2011 01:51:25 +0200 Subject: [PATCH 31/32] fixing BUG 11759958 - 52319: MYSQL RHEL5 RPMS DO NOT REQUIRE NET-TOOLS --- support-files/mysql.spec.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index dde7d4696e4..69eecbb3d01 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -127,13 +127,13 @@ %define distro_description Oracle Enterprise Linux 4 %define distro_releasetag oel4 %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel - %define distro_requires chkconfig coreutils grep procps shadow-utils + %define distro_requires chkconfig coreutils grep procps shadow-utils net-tools %else %if "%oelver" == "5" %define distro_description Oracle Enterprise Linux 5 %define distro_releasetag oel5 %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel - %define distro_requires chkconfig coreutils grep procps shadow-utils + %define distro_requires chkconfig coreutils grep procps shadow-utils net-tools %else %{error:Oracle Enterprise Linux %{oelver} is unsupported} %endif @@ -145,13 +145,13 @@ %define distro_description Red Hat Enterprise Linux 4 %define distro_releasetag rhel4 %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel - %define distro_requires chkconfig coreutils grep procps shadow-utils + %define distro_requires chkconfig coreutils grep procps shadow-utils net-tools %else %if "%rhelver" == "5" %define distro_description Red Hat Enterprise Linux 5 %define distro_releasetag rhel5 %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel - %define distro_requires chkconfig coreutils grep procps shadow-utils + %define distro_requires chkconfig coreutils grep procps shadow-utils net-tools %else %{error:Red Hat Enterprise Linux %{rhelver} is unsupported} %endif From 7e8d625b79f1ad3b3849c11616519cc86f1c07b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 8 Aug 2011 11:22:18 +0300 Subject: [PATCH 32/32] Bug#12770537 I_S.TABLES.DATA_LENGTH does not show on-disk size for compressed InnoDB tables ha_innodb::info_low(): For calculating data_length or index_length, use the compressed page size for compressed tables instead of UNIV_PAGE_SIZE. rb:714 approved by Sunny Bains --- .../suite/innodb_plugin/r/innodb-zip.result | 114 +++++++++--------- .../suite/innodb_plugin/t/innodb-zip.test | 20 +-- storage/innodb_plugin/ChangeLog | 8 +- storage/innodb_plugin/handler/ha_innodb.cc | 19 ++- 4 files changed, 87 insertions(+), 74 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/r/innodb-zip.result b/mysql-test/suite/innodb_plugin/r/innodb-zip.result index fc35143b305..16947bf16dc 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb-zip.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-zip.result @@ -62,42 +62,42 @@ row_format=compressed; create table t14(a int primary key) engine=innodb key_block_size=9; Warnings: Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=9. -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t0 Compact -test t00 Compact -test t1 Compact -test t10 Dynamic -test t11 Compressed -test t12 Compressed -test t13 Compressed -test t14 Compact -test t2 Redundant -test t3 Compact -test t4 Compact -test t5 Redundant -test t6 Redundant -test t7 Redundant -test t8 Compact -test t9 Compact +table_schema table_name row_format data_length index_length +test t0 Compact 16384 0 +test t00 Compact 16384 0 +test t1 Compact 16384 0 +test t10 Dynamic 16384 0 +test t11 Compressed 1024 0 +test t12 Compressed 1024 0 +test t13 Compressed 8192 0 +test t14 Compact 16384 0 +test t2 Redundant 16384 0 +test t3 Compact 16384 0 +test t4 Compact 16384 0 +test t5 Redundant 16384 0 +test t6 Redundant 16384 0 +test t7 Redundant 16384 0 +test t8 Compact 16384 0 +test t9 Compact 16384 0 drop table t0,t00,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14; alter table t1 key_block_size=0; alter table t1 row_format=dynamic; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Dynamic +table_schema table_name row_format data_length index_length +test t1 Dynamic 16384 0 alter table t1 row_format=compact; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compact +table_schema table_name row_format data_length index_length +test t1 Compact 16384 0 alter table t1 row_format=redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Redundant +table_schema table_name row_format data_length index_length +test t1 Redundant 16384 0 drop table t1; create table t1(a int not null, b text, index(b(10))) engine=innodb key_block_size=1; @@ -114,11 +114,11 @@ rollback; select a,left(b,40) from t1 natural join t2; a left(b,40) 1 1abcdefghijklmnopqrstuvwxyzAAAAAAAAAAAAA -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compressed -test t2 Compact +table_schema table_name row_format data_length index_length +test t1 Compressed 2048 1024 +test t2 Compact 16384 0 drop table t1,t2; SET SESSION innodb_strict_mode = off; CREATE TABLE t1( @@ -206,19 +206,19 @@ create table t8 (id int primary key) engine = innodb row_format = compressed; create table t9 (id int primary key) engine = innodb row_format = dynamic; create table t10(id int primary key) engine = innodb row_format = compact; create table t11(id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compact -test t10 Compact -test t11 Redundant -test t3 Compressed -test t4 Compressed -test t5 Compressed -test t6 Compressed -test t7 Compressed -test t8 Compressed -test t9 Dynamic +table_schema table_name row_format data_length index_length +test t1 Compact 16384 0 +test t10 Compact 16384 0 +test t11 Redundant 16384 0 +test t3 Compressed 1024 0 +test t4 Compressed 2048 0 +test t5 Compressed 4096 0 +test t6 Compressed 8192 0 +test t7 Compressed 16384 0 +test t8 Compressed 8192 0 +test t9 Dynamic 16384 0 drop table t1, t3, t4, t5, t6, t7, t8, t9, t10, t11; create table t1 (id int primary key) engine = innodb key_block_size = 8 row_format = compressed; @@ -245,11 +245,11 @@ Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t4' (errno: 1478) create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compressed -test t5 Compressed +table_schema table_name row_format data_length index_length +test t1 Compressed 8192 0 +test t5 Compressed 8192 0 drop table t1, t5; create table t1 (id int primary key) engine = innodb key_block_size = 9 row_format = redundant; @@ -275,9 +275,9 @@ Level Code Message Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t2' (errno: 1478) -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format +table_schema table_name row_format data_length index_length set global innodb_file_per_table = off; create table t1 (id int primary key) engine = innodb key_block_size = 1; ERROR HY000: Can't create table 'test.t1' (errno: 1478) @@ -323,11 +323,11 @@ Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. Error 1005 Can't create table 'test.t7' (errno: 1478) create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t8 Compact -test t9 Redundant +table_schema table_name row_format data_length index_length +test t8 Compact 16384 0 +test t9 Redundant 16384 0 drop table t8, t9; set global innodb_file_per_table = on; set global innodb_file_format = `0`; @@ -375,11 +375,11 @@ Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. Error 1005 Can't create table 'test.t7' (errno: 1478) create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t8 Compact -test t9 Redundant +table_schema table_name row_format data_length index_length +test t8 Compact 16384 0 +test t9 Redundant 16384 0 drop table t8, t9; set global innodb_file_per_table=0; set global innodb_file_format=Antelope; diff --git a/mysql-test/suite/innodb_plugin/t/innodb-zip.test b/mysql-test/suite/innodb_plugin/t/innodb-zip.test index 8c1ef1f5467..5ed101b7f20 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb-zip.test +++ b/mysql-test/suite/innodb_plugin/t/innodb-zip.test @@ -36,19 +36,19 @@ create table t13(a int primary key) engine=innodb row_format=compressed; create table t14(a int primary key) engine=innodb key_block_size=9; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t0,t00,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14; alter table t1 key_block_size=0; alter table t1 row_format=dynamic; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; alter table t1 row_format=compact; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; alter table t1 row_format=redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t1; @@ -81,7 +81,7 @@ connection default; disconnect a; disconnect b; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t1,t2; @@ -192,7 +192,7 @@ create table t9 (id int primary key) engine = innodb row_format = dynamic; create table t10(id int primary key) engine = innodb row_format = compact; create table t11(id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t1, t3, t4, t5, t6, t7, t8, t9, t10, t11; @@ -218,7 +218,7 @@ show warnings; create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t1, t5; @@ -238,7 +238,7 @@ create table t2 (id int primary key) engine = innodb key_block_size = 9 row_format = dynamic; show warnings; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; #test valid values with innodb_file_per_table unset @@ -268,7 +268,7 @@ show warnings; create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t8, t9; @@ -300,7 +300,7 @@ show warnings; create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t8, t9; diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 617df0a61fe..d5d1e8d1b66 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,9 +1,15 @@ +2011-08-08 The InnoDB Team + + * handler/ha_innodb.cc: + Fix Bug#12770537 I_S.TABLES.DATA_LENGTH DOES NOT SHOW ON-DISK SIZE + FOR COMPRESSED INNODB + 2011-07-19 The InnoDB Team * buf/buf0buf.c, buf/buf0rea.c, handler/ha_innodb.cc, include/buf0buf.h, include/buf0buf.ic, include/srv0srv.h, srv/srv0srv.c: - Fix bug#Bug 12356373 by reintroducing random readahead + Fix Bug#12356373 by reintroducing random readahead 2011-06-30 The InnoDB Team diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 6f88ea3fde1..609299efce5 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -7652,6 +7652,8 @@ ha_innobase::info_low( if (flag & HA_STATUS_VARIABLE) { + ulint page_size; + dict_table_stats_lock(ib_table, RW_S_LATCH); n_rows = ib_table->stat_n_rows; @@ -7694,14 +7696,19 @@ ha_innobase::info_low( prebuilt->autoinc_last_value = 0; } + page_size = dict_table_zip_size(ib_table); + if (page_size == 0) { + page_size = UNIV_PAGE_SIZE; + } + stats.records = (ha_rows)n_rows; stats.deleted = 0; - stats.data_file_length = ((ulonglong) - ib_table->stat_clustered_index_size) - * UNIV_PAGE_SIZE; - stats.index_file_length = ((ulonglong) - ib_table->stat_sum_of_other_index_sizes) - * UNIV_PAGE_SIZE; + stats.data_file_length + = ((ulonglong) ib_table->stat_clustered_index_size) + * page_size; + stats.index_file_length = + ((ulonglong) ib_table->stat_sum_of_other_index_sizes) + * page_size; dict_table_stats_unlock(ib_table, RW_S_LATCH);