From be8f64ff294644759202ca24e8d44e8d1a257410 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 1 Jul 2011 13:10:04 +0200 Subject: [PATCH 01/14] 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 535855eb753f55b5f39c307da48c96691204dbfb Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Thu, 7 Jul 2011 17:22:24 +0200 Subject: [PATCH 02/14] 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 03/14] 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 04/14] 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 05/14] 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 ce8077d8d37e37f4b007f64c5ca301d096699db8 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 14 Jul 2011 12:15:24 +0100 Subject: [PATCH 06/14] 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 07/14] 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 08/14] 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 41258f8e6c46d06e817d55921c66309ae9701799 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Tue, 19 Jul 2011 10:37:37 -0400 Subject: [PATCH 09/14] 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 f7618904bf99d98c958216ec4343def04d026ce2 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Fri, 22 Jul 2011 11:45:15 +0400 Subject: [PATCH 10/14] 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 75eaa30d26b65e6da5ebe35728824a3603719599 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 27 Jul 2011 12:34:25 +0400 Subject: [PATCH 11/14] 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 12/14] 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 de3693a1cd292af3efd8841414da866ee2c2e1de Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 2 Aug 2011 11:33:45 +0400 Subject: [PATCH 13/14] 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 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 14/14] 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);