From 49411edb69cd5ad26bd48850ce4637fda7659a34 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 28 Aug 2008 16:16:06 +0300 Subject: [PATCH 01/12] on behalf of jasonh : fix of a test problem re bug#37051: Wait for slave to stop before set skip counter --- mysql-test/include/wait_for_slave_sql_error_and_skip.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/include/wait_for_slave_sql_error_and_skip.inc b/mysql-test/include/wait_for_slave_sql_error_and_skip.inc index ef17ffed12f..4b4776d2923 100644 --- a/mysql-test/include/wait_for_slave_sql_error_and_skip.inc +++ b/mysql-test/include/wait_for_slave_sql_error_and_skip.inc @@ -17,6 +17,9 @@ if ($show_sql_error) echo Last_SQL_Error = $error; } +# wait for SQL thread to stop after the error +source include/wait_for_slave_sql_to_stop.inc; + # skip the erroneous statement set global sql_slave_skip_counter=1; start slave; From 86af3f63ff9be54c1d4b27d2b38d4a540bcaf988 Mon Sep 17 00:00:00 2001 From: mysqldev Date: Thu, 28 Aug 2008 16:16:43 +0200 Subject: [PATCH 02/12] Added "-rc" to the release number --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 56bdb4ba006..dacd3864e6a 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in mysqlbinlog::check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.1.28) +AM_INIT_AUTOMAKE(mysql, 5.1.28-rc) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 From d93fe583027ed49d22b4778e28c3818d24b9fe12 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Oct 2008 18:35:49 +0200 Subject: [PATCH 03/12] Aligned declaration and defintion of ha_change_partitions(), to avoid link error using SunStudio 12. --- sql/handler.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index a988c34b7ca..a127b3fa9f2 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3333,8 +3333,8 @@ handler::ha_create_handler_files(const char *name, const char *old_name, int handler::ha_change_partitions(HA_CREATE_INFO *create_info, const char *path, - ulonglong *copied, - ulonglong *deleted, + ulonglong * const copied, + ulonglong * const deleted, const uchar *pack_frm_data, size_t pack_frm_len) { From 1153d1edad159c944b1ac8bee3663eee2e23bf84 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Oct 2008 20:28:13 +0200 Subject: [PATCH 04/12] Made dist support script more portable sh --- BUILD/compile-dist | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/BUILD/compile-dist b/BUILD/compile-dist index 74690fb0c95..caee172f196 100755 --- a/BUILD/compile-dist +++ b/BUILD/compile-dist @@ -13,34 +13,51 @@ path=`dirname $0` # Default to gcc for CC and CXX if test -z "$CXX" ; then - export CXX=gcc + CXX=gcc # Set some required compile options if test -z "$CXXFLAGS" ; then - export CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" + CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" fi fi if test -z "$CC" ; then - export CC=gcc + CC=gcc fi # Use ccache, if available if ccache -V > /dev/null 2>&1 then - if ! (echo "$CC" | grep "ccache" > /dev/null) + if echo "$CC" | grep "ccache" > /dev/null then - export CC="ccache $CC" + : + else + CC="ccache $CC" fi - if ! (echo "$CXX" | grep "ccache" > /dev/null) + if echo "$CXX" | grep "ccache" > /dev/null then - export CXX="ccache $CXX" + : + else + CXX="ccache $CXX" fi fi +if test -z "$MAKE" +then + if gmake -v > /dev/null 2>&1 + then + MAKE="gmake" + else + MAKE="make" + fi +fi + +export CC CXX MAKE + # Make sure to enable all features that affect "make dist" # Remember that configure restricts the man pages to the configured features ! ./configure \ --with-embedded-server \ --with-ndbcluster -make +$MAKE + From eab7404c8f112737d7c2aee37db12a9d48cc6cba Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Oct 2008 23:51:58 +0200 Subject: [PATCH 05/12] More portable sh in configure script --- configure.in | 64 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/configure.in b/configure.in index d81114daa59..c7e18d25811 100644 --- a/configure.in +++ b/configure.in @@ -405,12 +405,15 @@ dnl Find paths to some shell programs AC_PATH_PROG(LN, ln, ln) # This must be able to take a -f flag like normal unix ln. AC_PATH_PROG(LN_CP_F, ln, ln) -if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then -# If ln -f does not exists use -s (AFS systems) -if test -n "$LN_CP_F"; then - LN_CP_F="$LN_CP_F -s" -fi -fi +case $SYSTEM_TYPE in + *netware*) ;; + *) + # If ln -f does not exists use -s (AFS systems) + if test -n "$LN_CP_F"; then + LN_CP_F="$LN_CP_F -s" + fi + ;; +esac AC_PATH_PROG(MV, mv, mv) AC_PATH_PROG(RM, rm, rm) @@ -1642,14 +1645,16 @@ else OPTIMIZE_CXXFLAGS="-O" fi -if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then - DEBUG_CFLAGS="-g -DDEBUG -sym internal,codeview4" - DEBUG_CXXFLAGS="-g -DDEBUG -sym internal,codeview4" - DEBUG_OPTIMIZE_CC="-DDEBUG" - DEBUG_OPTIMIZE_CXX="-DDEBUG" - OPTIMIZE_CFLAGS="-O3 -DNDEBUG" - OPTIMIZE_CXXFLAGS="-O3 -DNDEBUG" -fi +case $SYSTEM_TYPE in + *netware*) + DEBUG_CFLAGS="-g -DDEBUG -sym internal,codeview4" + DEBUG_CXXFLAGS="-g -DDEBUG -sym internal,codeview4" + DEBUG_OPTIMIZE_CC="-DDEBUG" + DEBUG_OPTIMIZE_CXX="-DDEBUG" + OPTIMIZE_CFLAGS="-O3 -DNDEBUG" + OPTIMIZE_CXXFLAGS="-O3 -DNDEBUG" + ;; +esac # If the user specified CFLAGS, we won't add any optimizations if test -n "$SAVE_CFLAGS" @@ -1915,15 +1920,18 @@ MYSQL_TZNAME # Do the c++ compiler have a bool type MYSQL_CXX_BOOL # Check some common bugs with gcc 2.8.# on sparc -if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then -MYSQL_CHECK_LONGLONG_TO_FLOAT -if test "$ac_cv_conv_longlong_to_float" != "yes" -then - AC_MSG_ERROR([Your compiler cannot convert a longlong value to a float! -If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try -again]) -fi -fi +case $SYSTEM_TYPE in + *netware*) ;; + *) + MYSQL_CHECK_LONGLONG_TO_FLOAT + if test "$ac_cv_conv_longlong_to_float" != "yes" + then + AC_MSG_ERROR([Your compiler cannot convert a longlong value to a float! + If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try + again]) + fi + ;; +esac AC_CHECK_TYPES([sigset_t, off_t], [], [], [#include ]) AC_CHECK_TYPES([size_t], [], [], [#include ]) AC_CHECK_TYPES([u_int32_t]) @@ -2549,11 +2557,12 @@ readline_h_ln_cmd="" readline_link="" want_to_use_readline="no" -if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null -then +case $SYSTEM_TYPE in + *netware*) # For NetWare, do not need readline echo "Skipping readline" -else + ;; + *) if [test "$with_libedit" = "yes"] || [test "$with_libedit" = "undefined"] && [test "$with_readline" = "undefined"] then readline_topdir="cmd-line-utils" @@ -2606,7 +2615,8 @@ else be built with libreadline. Please use --with-libedit to use the bundled version of libedit instead.]) fi -fi + ;; +esac AC_SUBST(readline_dir) AC_SUBST(readline_topdir) From bba814d0b9dd248a14c25c703542f26fe0d65d4a Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 17 Oct 2008 17:45:17 +0500 Subject: [PATCH 06/12] Fix for bug #40053: 'check table .. for upgrade' doesn't detect collation change made in 5.1.24-rc Problem: 'CHECK TABLE ... FOR UPGRADE' did not check for incompatible collation changes made in MySQL 5.1.24-rc. Fix: add the check. sql/handler.cc: - check for incompatible collation changes made in 5.1.24-rc: bug #27877: utf8_general_ci ucs2_general_ci --- sql/handler.cc | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index a988c34b7ca..d82b2dd967e 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2765,7 +2765,7 @@ int handler::check_collation_compatibility() { ulong mysql_version= table->s->mysql_version; - if (mysql_version < 50048) + if (mysql_version < 50124) { KEY *key= table->key_info; KEY *key_end= key + table->s->keys; @@ -2779,15 +2779,18 @@ int handler::check_collation_compatibility() continue; Field *field= table->field[key_part->fieldnr - 1]; uint cs_number= field->charset()->number; - if (mysql_version < 50048 && - (cs_number == 11 || /* ascii_general_ci - bug #29499, bug #27562 */ - cs_number == 41 || /* latin7_general_ci - bug #29461 */ - cs_number == 42 || /* latin7_general_cs - bug #29461 */ - cs_number == 20 || /* latin7_estonian_cs - bug #29461 */ - cs_number == 21 || /* latin2_hungarian_ci - bug #29461 */ - cs_number == 22 || /* koi8u_general_ci - bug #29461 */ - cs_number == 23 || /* cp1251_ukrainian_ci - bug #29461 */ - cs_number == 26)) /* cp1250_general_ci - bug #29461 */ + if ((mysql_version < 50048 && + (cs_number == 11 || /* ascii_general_ci - bug #29499, bug #27562 */ + cs_number == 41 || /* latin7_general_ci - bug #29461 */ + cs_number == 42 || /* latin7_general_cs - bug #29461 */ + cs_number == 20 || /* latin7_estonian_cs - bug #29461 */ + cs_number == 21 || /* latin2_hungarian_ci - bug #29461 */ + cs_number == 22 || /* koi8u_general_ci - bug #29461 */ + cs_number == 23 || /* cp1251_ukrainian_ci - bug #29461 */ + cs_number == 26)) || /* cp1250_general_ci - bug #29461 */ + (mysql_version < 50124 && + (cs_number == 33 || /* utf8_general_ci - bug #27877 */ + cs_number == 35))) /* ucs2_general_ci - bug #27877 */ return HA_ADMIN_NEEDS_UPGRADE; } } From 2019f17276a3a3bb37f81824aa34b0428f5d8753 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Mon, 20 Oct 2008 20:50:08 +0200 Subject: [PATCH 07/12] Bug #40004 Replication failure with no PK + no indexes In certain situations, a scan of the table will return the error code HA_ERR_RECORD_DELETED, and this error code is not correctly caught in the Rows_log_event::find_row() function, which causes an error to be returned for this case. This patch fixes the problem by adding code to either ignore the record and continuing with the next one, the the event of a table scan, or change the error code to HA_ERR_KEY_NOT_FOUND, in the event that a key lookup is attempted. --- mysql-test/extra/rpl_tests/rpl_row_basic.test | 91 +++++++++++++++++++ .../suite/rpl/r/rpl_row_basic_2myisam.result | 57 ++++++++++++ .../suite/rpl/r/rpl_row_basic_3innodb.result | 57 ++++++++++++ .../suite/rpl_ndb/r/rpl_row_basic_7ndb.result | 57 ++++++++++++ sql/log_event.cc | 38 ++++++-- sql/log_event_old.cc | 47 ++++++++-- 6 files changed, 332 insertions(+), 15 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_row_basic.test b/mysql-test/extra/rpl_tests/rpl_row_basic.test index 7cfbcdb4437..3491fb903a0 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_basic.test +++ b/mysql-test/extra/rpl_tests/rpl_row_basic.test @@ -471,3 +471,94 @@ source include/diff_tables.inc; connection master; drop table t1; sync_slave_with_master; + +# +# BUG#40004: Replication failure with no PK + no indexes +# + +connection master; + +eval CREATE TABLE t1 (a int) ENGINE=$type; + +INSERT IGNORE INTO t1 VALUES (NULL); +INSERT INTO t1 ( a ) VALUES ( 0 ); +INSERT INTO t1 ( a ) VALUES ( 9 ); +INSERT INTO t1 ( a ) VALUES ( 2 ); +INSERT INTO t1 ( a ) VALUES ( 9 ); +INSERT INTO t1 ( a ) VALUES ( 5 ); + +UPDATE t1 SET a = 5 WHERE a = 9; +DELETE FROM t1 WHERE a < 6; +UPDATE t1 SET a = 9 WHERE a < 3; +INSERT INTO t1 ( a ) VALUES ( 3 ); +UPDATE t1 SET a = 0 WHERE a < 4; +UPDATE t1 SET a = 8 WHERE a < 5; + +sync_slave_with_master; + +let $diff_table_1=master:test.t1; +let $diff_table_2=slave:test.t1; +source include/diff_tables.inc; + +connection master; +drop table t1; +sync_slave_with_master; + +# +# Bug #39752: Replication failure on RBR + MyISAM + no PK +# + +connection master; + +--disable_warnings +eval CREATE TABLE t1 (a bit) ENGINE=$type; +INSERT IGNORE INTO t1 VALUES (NULL); +INSERT INTO t1 ( a ) VALUES ( 0 ); +UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3; +INSERT INTO t1 ( a ) VALUES ( 5 ); +DELETE FROM t1 WHERE a < 2 LIMIT 4; +DELETE FROM t1 WHERE a < 9 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 9 ); +UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6; +INSERT INTO t1 ( a ) VALUES ( 8 ); +UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0; +INSERT INTO t1 ( a ) VALUES ( 4 ); +INSERT INTO t1 ( a ) VALUES ( 3 ); +UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6; +DELETE FROM t1 WHERE a = 4 LIMIT 7; +UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9; +UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2; +DELETE FROM t1 WHERE a < 0 LIMIT 5; +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8; +DELETE FROM t1 WHERE a < 8 LIMIT 8; +INSERT INTO t1 ( a ) VALUES ( 6 ); +DELETE FROM t1 WHERE a < 6 LIMIT 7; +UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7; +UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6; +INSERT INTO t1 ( a ) VALUES ( 7 ); +DELETE FROM t1 WHERE a < 9 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 7 ); +INSERT INTO t1 ( a ) VALUES ( 6 ); +UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4; +DELETE FROM t1 WHERE a = 2 LIMIT 9; +DELETE FROM t1 WHERE a = 1 LIMIT 4; +UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7; +INSERT INTO t1 ( a ) VALUES ( 0 ); +DELETE FROM t1 WHERE a < 3 LIMIT 0; +UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2; +INSERT INTO t1 ( a ) VALUES ( 1 ); +UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3; +--enable_warnings + +sync_slave_with_master; + +let $diff_table_1=master:test.t1; +let $diff_table_2=slave:test.t1; +source include/diff_tables.inc; + +connection master; +drop table t1; +sync_slave_with_master; diff --git a/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result b/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result index d9d96cf7eda..76ff8e15fdb 100644 --- a/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result +++ b/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result @@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY' INSERT INTO t1 VALUES (4); Comparing tables master:test.t1 and slave:test.t1 drop table t1; +CREATE TABLE t1 (a int) ENGINE='MYISAM' ; +INSERT IGNORE INTO t1 VALUES (NULL); +INSERT INTO t1 ( a ) VALUES ( 0 ); +INSERT INTO t1 ( a ) VALUES ( 9 ); +INSERT INTO t1 ( a ) VALUES ( 2 ); +INSERT INTO t1 ( a ) VALUES ( 9 ); +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 5 WHERE a = 9; +DELETE FROM t1 WHERE a < 6; +UPDATE t1 SET a = 9 WHERE a < 3; +INSERT INTO t1 ( a ) VALUES ( 3 ); +UPDATE t1 SET a = 0 WHERE a < 4; +UPDATE t1 SET a = 8 WHERE a < 5; +Comparing tables master:test.t1 and slave:test.t1 +drop table t1; +CREATE TABLE t1 (a bit) ENGINE='MYISAM' ; +INSERT IGNORE INTO t1 VALUES (NULL); +INSERT INTO t1 ( a ) VALUES ( 0 ); +UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3; +INSERT INTO t1 ( a ) VALUES ( 5 ); +DELETE FROM t1 WHERE a < 2 LIMIT 4; +DELETE FROM t1 WHERE a < 9 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 9 ); +UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6; +INSERT INTO t1 ( a ) VALUES ( 8 ); +UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0; +INSERT INTO t1 ( a ) VALUES ( 4 ); +INSERT INTO t1 ( a ) VALUES ( 3 ); +UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6; +DELETE FROM t1 WHERE a = 4 LIMIT 7; +UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9; +UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2; +DELETE FROM t1 WHERE a < 0 LIMIT 5; +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8; +DELETE FROM t1 WHERE a < 8 LIMIT 8; +INSERT INTO t1 ( a ) VALUES ( 6 ); +DELETE FROM t1 WHERE a < 6 LIMIT 7; +UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7; +UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6; +INSERT INTO t1 ( a ) VALUES ( 7 ); +DELETE FROM t1 WHERE a < 9 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 7 ); +INSERT INTO t1 ( a ) VALUES ( 6 ); +UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4; +DELETE FROM t1 WHERE a = 2 LIMIT 9; +DELETE FROM t1 WHERE a = 1 LIMIT 4; +UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7; +INSERT INTO t1 ( a ) VALUES ( 0 ); +DELETE FROM t1 WHERE a < 3 LIMIT 0; +UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2; +INSERT INTO t1 ( a ) VALUES ( 1 ); +UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3; +Comparing tables master:test.t1 and slave:test.t1 +drop table t1; diff --git a/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result b/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result index 72c94ceb525..15673768180 100644 --- a/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result @@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY' INSERT INTO t1 VALUES (4); Comparing tables master:test.t1 and slave:test.t1 drop table t1; +CREATE TABLE t1 (a int) ENGINE='INNODB' ; +INSERT IGNORE INTO t1 VALUES (NULL); +INSERT INTO t1 ( a ) VALUES ( 0 ); +INSERT INTO t1 ( a ) VALUES ( 9 ); +INSERT INTO t1 ( a ) VALUES ( 2 ); +INSERT INTO t1 ( a ) VALUES ( 9 ); +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 5 WHERE a = 9; +DELETE FROM t1 WHERE a < 6; +UPDATE t1 SET a = 9 WHERE a < 3; +INSERT INTO t1 ( a ) VALUES ( 3 ); +UPDATE t1 SET a = 0 WHERE a < 4; +UPDATE t1 SET a = 8 WHERE a < 5; +Comparing tables master:test.t1 and slave:test.t1 +drop table t1; +CREATE TABLE t1 (a bit) ENGINE='INNODB' ; +INSERT IGNORE INTO t1 VALUES (NULL); +INSERT INTO t1 ( a ) VALUES ( 0 ); +UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3; +INSERT INTO t1 ( a ) VALUES ( 5 ); +DELETE FROM t1 WHERE a < 2 LIMIT 4; +DELETE FROM t1 WHERE a < 9 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 9 ); +UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6; +INSERT INTO t1 ( a ) VALUES ( 8 ); +UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0; +INSERT INTO t1 ( a ) VALUES ( 4 ); +INSERT INTO t1 ( a ) VALUES ( 3 ); +UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6; +DELETE FROM t1 WHERE a = 4 LIMIT 7; +UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9; +UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2; +DELETE FROM t1 WHERE a < 0 LIMIT 5; +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8; +DELETE FROM t1 WHERE a < 8 LIMIT 8; +INSERT INTO t1 ( a ) VALUES ( 6 ); +DELETE FROM t1 WHERE a < 6 LIMIT 7; +UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7; +UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6; +INSERT INTO t1 ( a ) VALUES ( 7 ); +DELETE FROM t1 WHERE a < 9 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 7 ); +INSERT INTO t1 ( a ) VALUES ( 6 ); +UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4; +DELETE FROM t1 WHERE a = 2 LIMIT 9; +DELETE FROM t1 WHERE a = 1 LIMIT 4; +UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7; +INSERT INTO t1 ( a ) VALUES ( 0 ); +DELETE FROM t1 WHERE a < 3 LIMIT 0; +UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2; +INSERT INTO t1 ( a ) VALUES ( 1 ); +UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3; +Comparing tables master:test.t1 and slave:test.t1 +drop table t1; diff --git a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result index 2538358b4d3..ac8ca2b3bcd 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result @@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY' INSERT INTO t1 VALUES (4); Comparing tables master:test.t1 and slave:test.t1 drop table t1; +CREATE TABLE t1 (a int) ENGINE='NDB' ; +INSERT IGNORE INTO t1 VALUES (NULL); +INSERT INTO t1 ( a ) VALUES ( 0 ); +INSERT INTO t1 ( a ) VALUES ( 9 ); +INSERT INTO t1 ( a ) VALUES ( 2 ); +INSERT INTO t1 ( a ) VALUES ( 9 ); +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 5 WHERE a = 9; +DELETE FROM t1 WHERE a < 6; +UPDATE t1 SET a = 9 WHERE a < 3; +INSERT INTO t1 ( a ) VALUES ( 3 ); +UPDATE t1 SET a = 0 WHERE a < 4; +UPDATE t1 SET a = 8 WHERE a < 5; +Comparing tables master:test.t1 and slave:test.t1 +drop table t1; +CREATE TABLE t1 (a bit) ENGINE='NDB' ; +INSERT IGNORE INTO t1 VALUES (NULL); +INSERT INTO t1 ( a ) VALUES ( 0 ); +UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3; +INSERT INTO t1 ( a ) VALUES ( 5 ); +DELETE FROM t1 WHERE a < 2 LIMIT 4; +DELETE FROM t1 WHERE a < 9 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 9 ); +UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6; +INSERT INTO t1 ( a ) VALUES ( 8 ); +UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0; +INSERT INTO t1 ( a ) VALUES ( 4 ); +INSERT INTO t1 ( a ) VALUES ( 3 ); +UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6; +DELETE FROM t1 WHERE a = 4 LIMIT 7; +UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9; +UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2; +DELETE FROM t1 WHERE a < 0 LIMIT 5; +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 5 ); +UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8; +DELETE FROM t1 WHERE a < 8 LIMIT 8; +INSERT INTO t1 ( a ) VALUES ( 6 ); +DELETE FROM t1 WHERE a < 6 LIMIT 7; +UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7; +UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6; +INSERT INTO t1 ( a ) VALUES ( 7 ); +DELETE FROM t1 WHERE a < 9 LIMIT 4; +INSERT INTO t1 ( a ) VALUES ( 7 ); +INSERT INTO t1 ( a ) VALUES ( 6 ); +UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4; +DELETE FROM t1 WHERE a = 2 LIMIT 9; +DELETE FROM t1 WHERE a = 1 LIMIT 4; +UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7; +INSERT INTO t1 ( a ) VALUES ( 0 ); +DELETE FROM t1 WHERE a < 3 LIMIT 0; +UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2; +INSERT INTO t1 ( a ) VALUES ( 1 ); +UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3; +Comparing tables master:test.t1 and slave:test.t1 +drop table t1; diff --git a/sql/log_event.cc b/sql/log_event.cc index f91ebf3823f..0d03593946d 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7203,6 +7203,9 @@ 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))); + DBUG_ASSERT(error != HA_ERR_RECORD_DELETED); + table->in_use = old_thd; switch (error) { @@ -7218,11 +7221,13 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) case HA_ERR_TABLE_DEF_CHANGED: case HA_ERR_CANNOT_ADD_FOREIGN: - + which are not included into to the list. + + Note that HA_ERR_RECORD_DELETED is not in the list since + do_exec_row() should not return that error code. */ case HA_ERR_RECORD_CHANGED: - case HA_ERR_RECORD_DELETED: case HA_ERR_KEY_NOT_FOUND: case HA_ERR_END_OF_FILE: case HA_ERR_FOUND_DUPP_KEY: @@ -7231,7 +7236,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) case HA_ERR_NO_REFERENCED_ROW: case HA_ERR_ROW_IS_REFERENCED: - DBUG_PRINT("info", ("error: %s", HA_ERR(error))); if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) { if (global_system_variables.log_warnings) @@ -7254,7 +7258,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) m_curr_row_end. */ - DBUG_PRINT("info", ("error: %d", error)); DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu", (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end)); @@ -8269,6 +8272,8 @@ Rows_log_event::write_row(const Relay_log_info *const rli, if (error) { DBUG_PRINT("info",("rnd_pos() returns error %d",error)); + if (error == HA_ERR_RECORD_DELETED) + error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -8301,7 +8306,9 @@ Rows_log_event::write_row(const Relay_log_info *const rli, HA_READ_KEY_EXACT); if (error) { - DBUG_PRINT("info",("index_read_idx() returns error %d",error)); + DBUG_PRINT("info",("index_read_idx() returns %s", HA_ERR(error))); + if (error == HA_ERR_RECORD_DELETED) + error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -8574,6 +8581,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli) if (error) { DBUG_PRINT("info",("rnd_pos returns error %d",error)); + if (error == HA_ERR_RECORD_DELETED) + error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); } DBUG_RETURN(error); @@ -8633,6 +8642,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli) HA_READ_KEY_EXACT))) { DBUG_PRINT("info",("no record matching the key found in the table")); + if (error == HA_ERR_RECORD_DELETED) + error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); table->file->ha_index_end(); goto err; @@ -8690,8 +8701,11 @@ int Rows_log_event::find_row(const Relay_log_info *rli) 256U - (1U << table->s->last_null_bit_pos); } - if ((error= table->file->index_next(table->record[0]))) + while ((error= table->file->index_next(table->record[0]))) { + /* We just skip records that has already been deleted */ + if (error == HA_ERR_RECORD_DELETED) + continue; DBUG_PRINT("info",("no record matching the given row found")); table->file->print_error(error, MYF(0)); table->file->ha_index_end(); @@ -8722,14 +8736,22 @@ int Rows_log_event::find_row(const Relay_log_info *rli) /* Continue until we find the right record or have made a full loop */ do { + restart_rnd_next: error= table->file->rnd_next(table->record[0]); + DBUG_PRINT("info", ("error: %s", HA_ERR(error))); switch (error) { case 0: - case HA_ERR_RECORD_DELETED: break; + /* + If the record was deleted, we pick the next one without doing + any comparisons. + */ + case HA_ERR_RECORD_DELETED: + goto restart_rnd_next; + case HA_ERR_END_OF_FILE: if (++restart_count < 2) table->file->ha_rnd_init(1); @@ -8759,7 +8781,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli) DBUG_DUMP("record found", table->record[0], table->s->reclength); table->file->ha_rnd_end(); - DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == HA_ERR_RECORD_DELETED || error == 0); + DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0); goto err; } ok: diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index c6b99b1bd69..75aa8722aa9 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -556,6 +556,9 @@ replace_record(THD *thd, TABLE *table, error= table->file->rnd_pos(table->record[1], table->file->dup_ref); if (error) { + DBUG_PRINT("info",("rnd_pos() returns error %d",error)); + if (error == HA_ERR_RECORD_DELETED) + error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -582,6 +585,9 @@ replace_record(THD *thd, TABLE *table, HA_READ_KEY_EXACT); if (error) { + DBUG_PRINT("info", ("index_read_idx() returns error %d", error)); + if (error == HA_ERR_RECORD_DELETED) + error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -787,11 +793,14 @@ static int find_and_fetch_row(TABLE *table, uchar *key) 256U - (1U << table->s->last_null_bit_pos); } - if ((error= table->file->index_next(table->record[1]))) + while ((error= table->file->index_next(table->record[1]))) { - table->file->print_error(error, MYF(0)); + /* We just skip records that has already been deleted */ + if (error == HA_ERR_RECORD_DELETED) + continue; + table->file->print_error(error, MYF(0)); table->file->ha_index_end(); - DBUG_RETURN(error); + DBUG_RETURN(error); } } @@ -812,6 +821,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key) /* Continue until we find the right record or have made a full loop */ do { + restart_rnd_next: error= table->file->rnd_next(table->record[1]); DBUG_DUMP("record[0]", table->record[0], table->s->reclength); @@ -819,8 +829,14 @@ static int find_and_fetch_row(TABLE *table, uchar *key) switch (error) { case 0: + break; + + /* + If the record was deleted, we pick the next one without doing + any comparisons. + */ case HA_ERR_RECORD_DELETED: - break; + goto restart_rnd_next; case HA_ERR_END_OF_FILE: if (++restart_count < 2) @@ -1680,6 +1696,9 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli) error= do_exec_row(rli); + DBUG_PRINT("info", ("error: %d", error)); + DBUG_ASSERT(error != HA_ERR_RECORD_DELETED); + table->in_use = old_thd; switch (error) { @@ -2100,6 +2119,8 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli, if (error) { DBUG_PRINT("info",("rnd_pos() returns error %d",error)); + if (error == HA_ERR_RECORD_DELETED) + error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -2132,7 +2153,9 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli, HA_READ_KEY_EXACT); if (error) { - DBUG_PRINT("info",("index_read_idx() returns error %d",error)); + DBUG_PRINT("info",("index_read_idx() returns error %d", error)); + if (error == HA_ERR_RECORD_DELETED) + error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -2288,6 +2311,8 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) if (error) { DBUG_PRINT("info",("rnd_pos returns error %d",error)); + if (error == HA_ERR_RECORD_DELETED) + error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); } DBUG_RETURN(error); @@ -2347,6 +2372,8 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) HA_READ_KEY_EXACT))) { DBUG_PRINT("info",("no record matching the key found in the table")); + if (error == HA_ERR_RECORD_DELETED) + error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); table->file->ha_index_end(); DBUG_RETURN(error); @@ -2404,8 +2431,11 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) 256U - (1U << table->s->last_null_bit_pos); } - if ((error= table->file->index_next(table->record[0]))) + while ((error= table->file->index_next(table->record[0]))) { + /* We just skip records that has already been deleted */ + if (error == HA_ERR_RECORD_DELETED) + continue; DBUG_PRINT("info",("no record matching the given row found")); table->file->print_error(error, MYF(0)); table->file->ha_index_end(); @@ -2436,14 +2466,17 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) /* Continue until we find the right record or have made a full loop */ do { + restart_rnd_next: error= table->file->rnd_next(table->record[0]); switch (error) { case 0: - case HA_ERR_RECORD_DELETED: break; + case HA_ERR_RECORD_DELETED: + goto restart_rnd_next; + case HA_ERR_END_OF_FILE: if (++restart_count < 2) table->file->ha_rnd_init(1); From e68609848f1453b453f78e8e7765225002987283 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Wed, 29 Oct 2008 21:37:51 +0100 Subject: [PATCH 08/12] Bug #40004: Replication failure with no PK + no indexes Adding comments to test cases. --- mysql-test/extra/rpl_tests/rpl_row_basic.test | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mysql-test/extra/rpl_tests/rpl_row_basic.test b/mysql-test/extra/rpl_tests/rpl_row_basic.test index 3491fb903a0..2106ccd8a85 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_basic.test +++ b/mysql-test/extra/rpl_tests/rpl_row_basic.test @@ -476,6 +476,10 @@ sync_slave_with_master; # BUG#40004: Replication failure with no PK + no indexes # +# The test cases are taken from the bug report. It is difficult to +# produce a test case that generates a HA_ERR_RECORD_DELETED, so we go +# with the test cases we have. + connection master; eval CREATE TABLE t1 (a int) ENGINE=$type; @@ -508,6 +512,10 @@ sync_slave_with_master; # Bug #39752: Replication failure on RBR + MyISAM + no PK # +# The test cases are taken from the bug report. It is difficult to +# produce a test case that generates a HA_ERR_RECORD_DELETED, so we go +# with the test cases we have. + connection master; --disable_warnings From c3a5b59676a284232e4d3672f6c223a45023b9a6 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Mon, 3 Nov 2008 12:14:48 +0100 Subject: [PATCH 09/12] Bug #40360: Binlog related errors with binlog off When statement-based replication is used, and the transaction isolation level is READ-COMMITTED or stricter, InnoDB will print an error because statement-based replication might lead to inconsistency between master and slave databases. However, when the binary log is not engaged, this is not an issue and an error should not be printed. This patch makes thd_binlog_format() return BINLOG_FORMAT_ UNSPEC when the binary log is not engaged for the given thread. mysql-test/t/innodb_mysql.test: Adding test that no error message is printed from inside InnoDB when the binary log is turned off. --- mysql-test/r/innodb_mysql.result | 13 +++++++++++++ mysql-test/t/innodb_mysql.test | 15 +++++++++++++++ sql/sql_class.cc | 5 ++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 985f4d2b464..8e31389b6cd 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1668,3 +1668,16 @@ explain select a from t2 where a=b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL a 10 NULL # Using where; Using index drop table t1, t2; +SET SESSION BINLOG_FORMAT=STATEMENT; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +SHOW VARIABLES LIKE 'log_bin'; +Variable_name Value +log_bin OFF +SELECT @@session.binlog_format; +@@session.binlog_format +STATEMENT +SELECT @@session.tx_isolation; +@@session.tx_isolation +READ-COMMITTED +CREATE TABLE t1 ( a INT ) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1); diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index bcdb1328cb7..4aaef57e068 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -29,3 +29,18 @@ insert into t2 select @a:=A.a+10*(B.a + 10*C.a),@a, @a from t1 A, t1 B, t1 C; explain select a from t2 where a=b; drop table t1, t2; +# +# Bug #40360: Binlog related errors with binlog off +# +# This bug is triggered when the binlog format is STATEMENT and the +# binary log is turned off. In this case, no error should be shown for +# the statement since there are no replication issues. + +SET SESSION BINLOG_FORMAT=STATEMENT; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +SHOW VARIABLES LIKE 'log_bin'; +SELECT @@session.binlog_format; +SELECT @@session.tx_isolation; +CREATE TABLE t1 ( a INT ) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1); + diff --git a/sql/sql_class.cc b/sql/sql_class.cc index e63eed2d23c..12b773c91d0 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2852,7 +2852,10 @@ extern "C" int thd_non_transactional_update(const MYSQL_THD thd) extern "C" int thd_binlog_format(const MYSQL_THD thd) { - return (int) thd->variables.binlog_format; + if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG)) + return (int) thd->variables.binlog_format; + else + return BINLOG_FORMAT_UNSPEC; } extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all) From ad8ffe6add46e50b338301b28314799062156207 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Mon, 3 Nov 2008 18:46:47 +0100 Subject: [PATCH 10/12] Bug #40360: Binlog related errors with binlog off Adding missing drop of created table and tidying display. mysql-test/t/innodb_mysql.test: Adding drop of created table and cleaning variable display --- mysql-test/r/innodb_mysql.result | 14 +++++--------- mysql-test/t/innodb_mysql.test | 5 ++--- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 8e31389b6cd..2c14b1f2385 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1670,14 +1670,10 @@ id select_type table type possible_keys key key_len ref rows Extra drop table t1, t2; SET SESSION BINLOG_FORMAT=STATEMENT; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; -SHOW VARIABLES LIKE 'log_bin'; -Variable_name Value -log_bin OFF -SELECT @@session.binlog_format; -@@session.binlog_format -STATEMENT -SELECT @@session.tx_isolation; -@@session.tx_isolation -READ-COMMITTED +select @@session.sql_log_bin, @@session.binlog_format, @@session.tx_isolation; +@@session.sql_log_bin 1 +@@session.binlog_format STATEMENT +@@session.tx_isolation READ-COMMITTED CREATE TABLE t1 ( a INT ) ENGINE=InnoDB; INSERT INTO t1 VALUES(1); +DROP TABLE t1; diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 4aaef57e068..ed8de208474 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -38,9 +38,8 @@ drop table t1, t2; SET SESSION BINLOG_FORMAT=STATEMENT; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; -SHOW VARIABLES LIKE 'log_bin'; -SELECT @@session.binlog_format; -SELECT @@session.tx_isolation; +query_vertical select @@session.sql_log_bin, @@session.binlog_format, @@session.tx_isolation; CREATE TABLE t1 ( a INT ) ENGINE=InnoDB; INSERT INTO t1 VALUES(1); +DROP TABLE t1; From bcd88c9f9e617c4a9c426cbd0902f93a486e6b81 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Wed, 5 Nov 2008 15:53:28 +0100 Subject: [PATCH 11/12] Bug#40494: MYSQL server crashes on range access with partitioning and order by Problem was that the first index read was unordered, and the next was ordered, resulting in use of uninitialized data. Solution was to use the correct variable to see if the 'next' call should be ordered or not. mysql-test/r/partition.result: Bug#40494: MYSQL server crashes on range access with partitioning and order by Added test case for the bug. mysql-test/t/partition.test: Bug#40494: MYSQL server crashes on range access with partitioning and order by Added test case for the bug. sql/ha_partition.cc: Bug#40494: MYSQL server crashes on range access with partitioning and order by Used the wrong variable to decide to continue with ordered or unordered scan. --- mysql-test/r/partition.result | 74 +++++++++++++++++++++++++++++++++++ mysql-test/t/partition.test | 29 ++++++++++++++ sql/ha_partition.cc | 2 +- 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index e76c874324e..289a24685ff 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1,4 +1,78 @@ drop table if exists t1, t2; +CREATE TABLE t1 (a INT NOT NULL, KEY(a)) +PARTITION BY RANGE(a) +(PARTITION p1 VALUES LESS THAN (200), PARTITION pmax VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (2), (40), (40), (70), (60), (90), (199); +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC; +a +60 +70 +90 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95; +a +60 +70 +90 +INSERT INTO t1 VALUES (200), (250), (210); +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC; +a +60 +70 +90 +199 +200 +210 +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a ASC; +a +200 +210 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC; +a +90 +70 +60 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC; +a +210 +200 +199 +90 +70 +60 +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a DESC; +a +210 +200 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220; +a +199 +200 +210 +60 +70 +90 +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220; +a +200 +210 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95; +a +60 +70 +90 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220; +a +199 +200 +210 +60 +70 +90 +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220; +a +200 +210 +DROP TABLE t1; CREATE TABLE t1 ( a INT NOT NULL, b MEDIUMINT NOT NULL, diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 83e0cde8991..e016f72e75b 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -14,6 +14,35 @@ drop table if exists t1, t2; --enable_warnings +# +# Bug#40494: Crash MYSQL server crashes on range access with partitioning +# and order by +# +CREATE TABLE t1 (a INT NOT NULL, KEY(a)) +PARTITION BY RANGE(a) +(PARTITION p1 VALUES LESS THAN (200), PARTITION pmax VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (2), (40), (40), (70), (60), (90), (199); +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95; +INSERT INTO t1 VALUES (200), (250), (210); +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC; +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a ASC; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC; +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a DESC; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220; +DROP TABLE t1; + # # Bug35931: Index search may return duplicates # diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 14e321218ca..303a2c152fb 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4084,7 +4084,7 @@ int ha_partition::read_range_next() { DBUG_ENTER("ha_partition::read_range_next"); - if (m_ordered) + if (m_ordered_scan_ongoing) { DBUG_RETURN(handle_ordered_next(table->record[0], eq_range)); } From f40fc60cf233fe3c82aeaf7da4d29fa83e600b00 Mon Sep 17 00:00:00 2001 From: Sven Sandberg Date: Thu, 6 Nov 2008 11:00:55 +0100 Subject: [PATCH 12/12] BUG#36625: Please remove the rpl_probe and rpl_parse features from the server Problem 1: BUG#36625: rpl_redirect doesn't do anything useful. It tests an obsolete feature that was never fully implemented. Fix 1: Remove rpl_redirect. Problem 2: rpl_innodb_bug28430 and rpl_flushlog_loop are disabled despite the bugs for which they were disabled have been fixed. Fix 2: Re-enable rpl_innodb_bug28430 and rpl_flushlog_loop. mysql-test/suite/rpl/r/rpl_redirect.result: Removed result file for obsolete test.\ mysql-test/suite/rpl/t/disabled.def: Re-enabled tests. mysql-test/suite/rpl/t/rpl_redirect.test: Removed obsolete test. --- mysql-test/suite/rpl/r/rpl_redirect.result | 40 ------------------- mysql-test/suite/rpl/t/disabled.def | 3 -- mysql-test/suite/rpl/t/rpl_redirect.test | 45 ---------------------- 3 files changed, 88 deletions(-) delete mode 100644 mysql-test/suite/rpl/r/rpl_redirect.result delete mode 100644 mysql-test/suite/rpl/t/rpl_redirect.test diff --git a/mysql-test/suite/rpl/r/rpl_redirect.result b/mysql-test/suite/rpl/r/rpl_redirect.result deleted file mode 100644 index 39a7cb3ac3b..00000000000 --- a/mysql-test/suite/rpl/r/rpl_redirect.result +++ /dev/null @@ -1,40 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -SHOW SLAVE STATUS; -SHOW SLAVE HOSTS; -Server_id Host Port Rpl_recovery_rank Master_id -2 127.0.0.1 SLAVE_PORT 2 1 -create table t1 ( n int); -insert into t1 values (1),(2),(3),(4); -insert into t1 values(5); -SELECT * FROM t1 ORDER BY n; -n -1 -2 -3 -4 -5 -SELECT * FROM t1 ORDER BY n; -n -1 -2 -3 -4 -SELECT * FROM t1 ORDER BY n; -n -1 -2 -3 -4 -SELECT * FROM t1 ORDER BY n; -n -1 -2 -3 -4 -5 -drop table t1; diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index ebdb8014f88..8cae44a3607 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -10,6 +10,3 @@ # ############################################################################## -rpl_redirect : Failure is sporadic and and the test is superfluous (mats) -rpl_innodb_bug28430 : Failure on Solaris Bug #36793 -rpl_flushlog_loop : BUG#37733 2008-07-23 Sven disabled in 5.1-bugteam. the bug has been fixed in 5.1-rpl: please re-enable when that gets pushed to main diff --git a/mysql-test/suite/rpl/t/rpl_redirect.test b/mysql-test/suite/rpl/t/rpl_redirect.test deleted file mode 100644 index 1c6f31a030e..00000000000 --- a/mysql-test/suite/rpl/t/rpl_redirect.test +++ /dev/null @@ -1,45 +0,0 @@ -# -# Test of automatic redirection of queries to master/slave. -# - -source include/master-slave.inc; -# We disable this for now as PS doesn't handle redirection ---disable_ps_protocol - -#first, make sure the slave has had enough time to register -save_master_pos; -connection slave; -sync_with_master; - -#discover slaves -connection master; -source include/show_slave_status.inc; ---replace_result $SLAVE_MYPORT SLAVE_PORT -SHOW SLAVE HOSTS; -rpl_probe; - -#turn on master/slave query direction auto-magic -enable_rpl_parse; -create table t1 ( n int); -insert into t1 values (1),(2),(3),(4); -disable_rpl_parse; -save_master_pos; -connection slave; -sync_with_master; -insert into t1 values(5); -connection master; -enable_rpl_parse; -# The first of the queries will be sent to the slave, the second to the master. -SELECT * FROM t1 ORDER BY n; -SELECT * FROM t1 ORDER BY n; -disable_rpl_parse; -SELECT * FROM t1 ORDER BY n; -connection slave; -SELECT * FROM t1 ORDER BY n; - -# Cleanup -connection master; -drop table t1; -sync_slave_with_master; - -# End of 4.1 tests