2659 jonas@stripped 2008-08-12 [merge]
ndb - merge 5.1-telco-6.2 to 6.0-ndb
removed:
.bzr-mysql/
.bzr-mysql/default.conf
added:
.bzr-mysql/
.bzr-mysql/default.conf
mysql-test/suite/bugs/combinations
mysql-test/suite/bugs/r/rpl_bug33029.result
mysql-test/suite/bugs/r/rpl_bug37426.result
mysql-test/suite/bugs/t/rpl_bug33029.test
mysql-test/suite/bugs/t/rpl_bug37426.test
mysql-test/suite/ndb/r/ndb_dd_restore_compat.result
mysql-test/suite/ndb/t/ndb_dd_restore_compat.test
mysql-test/suite/ndb_binlog/r/ndb_binlog_restore.result
mysql-test/suite/ndb_binlog/t/ndb_binlog_restore.test
server-tools/
server-tools/instance-manager/
renamed:
storage/ndb/src/common/util/ndb_show_compat.cc => storage/ndb/src/common/util/ndb_show_compat.cpp
modified:
.bzrignore
client/mysql.cc
configure.in
include/my_base.h
mysql-test/extra/rpl_tests/rpl_row_basic.test
mysql-test/r/subselect.result
mysql-test/r/subselect_no_mat.result
mysql-test/r/subselect_no_opts.result
mysql-test/r/subselect_no_semijoin.result
mysql-test/suite/binlog/r/binlog_base64_flag.result
mysql-test/suite/binlog/r/binlog_multi_engine.result
mysql-test/suite/binlog/t/binlog_base64_flag.test
mysql-test/suite/ndb/r/ndb_multi_row.result
mysql-test/suite/ndb/r/ndb_restore.result
mysql-test/suite/ndb/r/ndb_trigger.result
mysql-test/suite/ndb/t/ndb_restore.test
mysql-test/suite/ndb/t/ndb_trigger.test
mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result
mysql-test/suite/ndb_binlog/r/ndb_binlog_format.result
mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result
mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result
mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result
mysql-test/suite/rpl/t/disabled.def
mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result
mysql-test/t/disabled.def
mysql-test/t/status.test
mysql-test/t/subselect.test
scripts/make_binary_distribution.sh
sql/field.cc
sql/field.h
sql/ha_ndbcluster.cc
sql/ha_ndbcluster_binlog.cc
sql/rpl_injector.cc
sql/rpl_injector.h
sql/rpl_utility.cc
sql/slave.cc
sql/slave.h
sql/sql_class.cc
sql/sql_insert.cc
sql/sql_select.cc
sql/structs.h
storage/ndb/include/kernel/signaldata/SumaImpl.hpp
storage/ndb/include/mgmapi/mgmapi.h
storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp
storage/ndb/include/ndbapi/NdbOperation.hpp
storage/ndb/include/ndbapi/NdbTransaction.hpp
storage/ndb/src/common/logger/Logger.cpp
storage/ndb/src/common/portlib/NdbCondition.c
storage/ndb/src/common/portlib/NdbTick.c
storage/ndb/src/common/transporter/TransporterRegistry.cpp
storage/ndb/src/common/util/Makefile.am
storage/ndb/src/common/util/ndb_init.cpp
storage/ndb/src/kernel/blocks/backup/Backup.cpp
storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
storage/ndb/src/kernel/blocks/suma/Suma.cpp
storage/ndb/src/kernel/blocks/suma/Suma.hpp
storage/ndb/src/kernel/blocks/suma/SumaInit.cpp
storage/ndb/src/mgmsrv/MgmtSrvr.cpp
storage/ndb/src/ndbapi/Ndb.cpp
storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
storage/ndb/src/ndbapi/NdbOperationExec.cpp
storage/ndb/src/ndbapi/NdbScanFilter.cpp
storage/ndb/src/ndbapi/NdbScanOperation.cpp
storage/ndb/src/ndbapi/NdbTransaction.cpp
storage/ndb/test/ndbapi/testInterpreter.cpp
storage/ndb/test/ndbapi/testNdbApi.cpp
storage/ndb/test/ndbapi/testOIBasic.cpp
storage/ndb/test/ndbapi/testScanFilter.cpp
storage/ndb/test/ndbapi/testSystemRestart.cpp
storage/ndb/test/ndbapi/test_event.cpp
storage/ndb/test/run-test/autotest-boot.sh
storage/ndb/test/run-test/daily-basic-tests.txt
storage/ndb/tools/restore/Restore.cpp
storage/ndb/tools/restore/consumer_restore.cpp
storage/ndb/tools/restore/restore_main.cpp
storage/ndb/tools/waiter.cpp
=== added directory '.bzr-mysql'
=== removed directory '.bzr-mysql'
=== added file '.bzr-mysql/default.conf'
--- a/.bzr-mysql/default.conf 1970-01-01 00:00:00 +0000
+++ b/.bzr-mysql/default.conf 2008-08-12 18:56:42 +0000
@@ -0,0 +1,4 @@
+[MYSQL]
+post_commit_to = "commits@stripped"
+post_push_to = "commits@stripped"
+tree_name = "mysql-6.0-ndb"
=== removed file '.bzr-mysql/default.conf'
--- a/.bzr-mysql/default.conf 2008-08-08 14:47:46 +0000
+++ b/.bzr-mysql/default.conf 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-[MYSQL]
-post_commit_to = commits@stripped
-tree_name = mysql-6.0-ndb
=== modified file '.bzrignore'
--- a/.bzrignore 2008-08-08 09:40:47 +0000
+++ b/.bzrignore 2008-08-12 18:56:42 +0000
@@ -3056,3 +3056,9 @@ win/vs8cache.txt
ylwrap
zlib/*.ds?
zlib/*.vcproj
+mysql-test/bug36522-64.tar
+mysql-test/bug36522.tar
+mysql-test/t.log
+mysql-test/tps.log
+libmysqld/event_parse_data.cc
+storage/ndb/src/common/util/ndb_show_compat
=== modified file 'client/mysql.cc'
--- a/client/mysql.cc 2008-04-01 10:45:05 +0000
+++ b/client/mysql.cc 2008-08-12 18:56:42 +0000
@@ -1848,7 +1848,7 @@ static int read_and_execute(bool interac
the very beginning of a text file when
you save the file using "Unicode UTF-8" format.
*/
- if (!line_number &&
+ if (line && !line_number &&
(uchar) line[0] == 0xEF &&
(uchar) line[1] == 0xBB &&
(uchar) line[2] == 0xBF)
=== modified file 'configure.in'
--- a/configure.in 2008-08-08 09:40:47 +0000
+++ b/configure.in 2008-08-12 18:56:42 +0000
@@ -2075,6 +2075,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bs
#
#
#
+AC_CHECK_LIB(rt, clock_gettime)
case "$target" in
*-*-aix4* | *-*-sco*)
# (grr) aix 4.3 has a stub for clock_gettime, (returning ENOSYS)
@@ -2085,6 +2086,7 @@ case "$target" in
*) AC_CHECK_FUNCS(clock_gettime)
;;
esac
+AC_CHECK_FUNCS(pthread_condattr_setclock)
# Check that isinf() is available in math.h and can be used in both C and C++
# code
=== modified file 'include/my_base.h'
--- a/include/my_base.h 2008-08-08 09:40:47 +0000
+++ b/include/my_base.h 2008-08-12 18:56:42 +0000
@@ -559,6 +559,7 @@ enum data_file_type {
#define GEOM_FLAG 128
#define SKIP_RANGE 256
+#define EMPTY_RANGE 512
typedef struct st_key_range
{
=== modified file 'mysql-test/extra/rpl_tests/rpl_row_basic.test'
--- a/mysql-test/extra/rpl_tests/rpl_row_basic.test 2007-12-12 19:12:29 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_row_basic.test 2008-08-08 08:10:39 +0000
@@ -259,7 +259,7 @@ DELETE FROM t1;
query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
sync_slave_with_master;
set @@global.slave_exec_mode= default;
-let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
+let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
@@ -272,3 +272,170 @@ query_vertical SELECT COUNT(*) FROM t1 O
connection master;
DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8;
sync_slave_with_master;
+
+#
+# BUG#37426: RBR breaks for CHAR() UTF8 fields > 85 chars
+#
+
+# We have 4 combinations to test with respect to the field length
+# (i.e., the number of bytes) of the CHAR fields:
+#
+# 1. Replicating from CHAR<256 to CHAR<256
+# 2. Replicating from CHAR<256 to CHAR>255
+# 3. Replicating from CHAR>255 to CHAR<256
+# 4. Replicating from CHAR>255 to CHAR>255
+
+# We also make a special case of using the max size of a field on the
+# master, i.e. CHAR(255) in UTF-8, giving another three cases.
+#
+# 5. Replicating UTF-8 CHAR(255) to CHAR(<256)
+# 6. Replicating UTF-8 CHAR(255) to CHAR(>255)
+# 7. Replicating UTF-8 CHAR(255) to CHAR(255) UTF-8
+
+connection master;
+eval CREATE TABLE t1 (i INT NOT NULL,
+ c CHAR(16) CHARACTER SET utf8 NOT NULL,
+ j INT NOT NULL) ENGINE = $type ;
+
+eval CREATE TABLE t2 (i INT NOT NULL,
+ c CHAR(16) CHARACTER SET utf8 NOT NULL,
+ j INT NOT NULL) ENGINE = $type ;
+
+sync_slave_with_master;
+ALTER TABLE t2 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
+
+connection master;
+eval CREATE TABLE t3 (i INT NOT NULL,
+ c CHAR(128) CHARACTER SET utf8 NOT NULL,
+ j INT NOT NULL) ENGINE = $type ;
+sync_slave_with_master;
+ALTER TABLE t3 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
+
+connection master;
+eval CREATE TABLE t4 (i INT NOT NULL,
+ c CHAR(128) CHARACTER SET utf8 NOT NULL,
+ j INT NOT NULL) ENGINE = $type ;
+
+eval CREATE TABLE t5 (i INT NOT NULL,
+ c CHAR(255) CHARACTER SET utf8 NOT NULL,
+ j INT NOT NULL) ENGINE = $type ;
+sync_slave_with_master;
+ALTER TABLE t5 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
+
+connection master;
+eval CREATE TABLE t6 (i INT NOT NULL,
+ c CHAR(255) CHARACTER SET utf8 NOT NULL,
+ j INT NOT NULL) ENGINE = $type ;
+sync_slave_with_master;
+ALTER TABLE t6 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
+
+connection master;
+eval CREATE TABLE t7 (i INT NOT NULL,
+ c CHAR(255) CHARACTER SET utf8 NOT NULL,
+ j INT NOT NULL) ENGINE = $type ;
+
+--echo [expecting slave to replicate correctly]
+connection master;
+INSERT INTO t1 VALUES (1, "", 1);
+INSERT INTO t1 VALUES (2, repeat(_utf8'a', 16), 2);
+
+sync_slave_with_master;
+
+let $diff_table_1=master:test.t1;
+let $diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+
+--echo [expecting slave to replicate correctly]
+connection master;
+INSERT INTO t2 VALUES (1, "", 1);
+INSERT INTO t2 VALUES (2, repeat(_utf8'a', 16), 2);
+
+sync_slave_with_master;
+
+let $diff_table_1=master:test.t2;
+let $diff_table_2=slave:test.t2;
+source include/diff_tables.inc;
+
+--echo [expecting slave to stop]
+connection master;
+INSERT INTO t3 VALUES (1, "", 1);
+INSERT INTO t3 VALUES (2, repeat(_utf8'a', 128), 2);
+
+connection slave;
+source include/wait_for_slave_sql_to_stop.inc;
+let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
+disable_query_log;
+eval SELECT "$last_error" AS Last_SQL_Error;
+enable_query_log;
+connection master;
+RESET MASTER;
+connection slave;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+
+--echo [expecting slave to replicate correctly]
+connection master;
+INSERT INTO t4 VALUES (1, "", 1);
+INSERT INTO t4 VALUES (2, repeat(_utf8'a', 128), 2);
+
+sync_slave_with_master;
+
+let $diff_table_1=master:test.t4;
+let $diff_table_2=slave:test.t4;
+source include/diff_tables.inc;
+
+--echo [expecting slave to stop]
+connection master;
+INSERT INTO t5 VALUES (1, "", 1);
+INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2);
+
+connection slave;
+source include/wait_for_slave_sql_to_stop.inc;
+let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
+disable_query_log;
+eval SELECT "$last_error" AS Last_SQL_Error;
+enable_query_log;
+connection master;
+RESET MASTER;
+connection slave;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+
+--echo [expecting slave to stop]
+connection master;
+INSERT INTO t6 VALUES (1, "", 1);
+INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2);
+
+connection slave;
+source include/wait_for_slave_sql_to_stop.inc;
+let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
+disable_query_log;
+eval SELECT "$last_error" AS Last_SQL_Error;
+enable_query_log;
+connection master;
+RESET MASTER;
+connection slave;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+
+--echo [expecting slave to replicate correctly]
+connection master;
+INSERT INTO t7 VALUES (1, "", 1);
+INSERT INTO t7 VALUES (2, repeat(_utf8'a', 255), 2);
+
+sync_slave_with_master;
+
+let $diff_table_1=master:test.t7;
+let $diff_table_2=slave:test.t7;
+source include/diff_tables.inc;
+
+connection master;
+drop table t1, t2, t3, t4, t5, t6, t7;
+sync_slave_with_master;
+
=== modified file 'mysql-test/r/subselect.result'
--- a/mysql-test/r/subselect.result 2008-05-22 18:40:15 +0000
+++ b/mysql-test/r/subselect.result 2008-08-12 18:56:42 +0000
@@ -4854,3 +4854,10 @@ ERROR 42000: You have an error in your S
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1
DROP TABLE t1, t2;
+CREATE TABLE t1(c int, KEY(c));
+CREATE TABLE t2(a int, b int);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a b
+DROP TABLE t1,t2;
=== modified file 'mysql-test/r/subselect_no_mat.result'
--- a/mysql-test/r/subselect_no_mat.result 2008-05-22 18:40:15 +0000
+++ b/mysql-test/r/subselect_no_mat.result 2008-08-12 18:56:42 +0000
@@ -4858,6 +4858,13 @@ ERROR 42000: You have an error in your S
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1
DROP TABLE t1, t2;
+CREATE TABLE t1(c int, KEY(c));
+CREATE TABLE t2(a int, b int);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a b
+DROP TABLE t1,t2;
set optimizer_switch='';
show variables like 'optimizer_switch';
Variable_name Value
=== modified file 'mysql-test/r/subselect_no_opts.result'
--- a/mysql-test/r/subselect_no_opts.result 2008-05-22 18:40:15 +0000
+++ b/mysql-test/r/subselect_no_opts.result 2008-08-12 18:56:42 +0000
@@ -4858,6 +4858,13 @@ ERROR 42000: You have an error in your S
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1
DROP TABLE t1, t2;
+CREATE TABLE t1(c int, KEY(c));
+CREATE TABLE t2(a int, b int);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a b
+DROP TABLE t1,t2;
set optimizer_switch='';
show variables like 'optimizer_switch';
Variable_name Value
=== modified file 'mysql-test/r/subselect_no_semijoin.result'
--- a/mysql-test/r/subselect_no_semijoin.result 2008-05-22 18:40:15 +0000
+++ b/mysql-test/r/subselect_no_semijoin.result 2008-08-12 18:56:42 +0000
@@ -4858,6 +4858,13 @@ ERROR 42000: You have an error in your S
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1
DROP TABLE t1, t2;
+CREATE TABLE t1(c int, KEY(c));
+CREATE TABLE t2(a int, b int);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a b
+DROP TABLE t1,t2;
set optimizer_switch='';
show variables like 'optimizer_switch';
Variable_name Value
=== modified file 'mysql-test/suite/binlog/r/binlog_base64_flag.result'
--- a/mysql-test/suite/binlog/r/binlog_base64_flag.result 2008-03-28 13:52:33 +0000
+++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result 2008-06-30 20:11:18 +0000
@@ -66,4 +66,28 @@ a
1
1
3
-drop table t1;
+CREATE TABLE char128_utf8 (
+i1 INT NOT NULL,
+c CHAR(128) CHARACTER SET utf8 NOT NULL,
+i2 INT NOT NULL);
+CREATE TABLE char63_utf8 (
+i1 INT NOT NULL,
+c CHAR(63) CHARACTER SET utf8 NOT NULL,
+i2 INT NOT NULL);
+BINLOG '
+MuNkSA8BAAAAZgAAAGoAAAAAAAQANS4xLjI1LXJjLWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAy42RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
+';
+BINLOG '
+3u9kSBMBAAAANgAAAJYBAAAAABAAAAAAAAAABHRlc3QAC2NoYXI2M191dGY4AAMD/gMC/r0A
+3u9kSBcBAAAAKgAAAMABAAAQABAAAAAAAAEAA//4AQAAAAMxMjMBAAAA
+';
+SELECT * FROM char63_utf8;
+i1 c i2
+1 123 1
+BINLOG '
+iONkSBMBAAAANwAAAJkBAAAAABAAAAAAAAAABHRlc3QADGNoYXIxMjhfdXRmOAADA/4DAv6AAA==
+iONkSBcBAAAAKwAAAMQBAAAQABAAAAAAAAEAA//4AQAAAAMAMTIzAQAAAA==
+';
+ERROR HY000: master may suffer from http://bugs.mysql.com/bug.php?id=37426 so slave stops; check error log on slave for more info
+drop table t1, char63_utf8, char128_utf8;
=== modified file 'mysql-test/suite/binlog/r/binlog_multi_engine.result'
--- a/mysql-test/suite/binlog/r/binlog_multi_engine.result 2008-03-28 12:16:41 +0000
+++ b/mysql-test/suite/binlog/r/binlog_multi_engine.result 2008-06-19 07:18:42 +0000
@@ -27,11 +27,6 @@ master-bin.000001 # Query # # use `test`
master-bin.000001 # Query # # use `test`; UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f
master-bin.000001 # Query # # use `test`; UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c
master-bin.000001 # Query # # use `test`; COMMIT
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.t1n)
-master-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; TRUNCATE t1m
master-bin.000001 # Query # # use `test`; TRUNCATE t1b
master-bin.000001 # Query # # use `test`; TRUNCATE t1n
=== modified file 'mysql-test/suite/binlog/t/binlog_base64_flag.test'
--- a/mysql-test/suite/binlog/t/binlog_base64_flag.test 2008-03-28 13:52:33 +0000
+++ b/mysql-test/suite/binlog/t/binlog_base64_flag.test 2008-06-30 20:11:18 +0000
@@ -104,6 +104,49 @@ Dl1YRxcBAAAAIgAAAFYBAAAQABAAAAAAAAEAAf/+
# the above line should fail and 5 should not be in the binlog.
select * from t1;
+# Test that BUG#37426 is triggered.
-# clean up
-drop table t1;
+CREATE TABLE char128_utf8 (
+ i1 INT NOT NULL,
+ c CHAR(128) CHARACTER SET utf8 NOT NULL,
+ i2 INT NOT NULL);
+CREATE TABLE char63_utf8 (
+ i1 INT NOT NULL,
+ c CHAR(63) CHARACTER SET utf8 NOT NULL,
+ i2 INT NOT NULL);
+
+#
+# This is the format description log event
+#
+
+BINLOG '
+MuNkSA8BAAAAZgAAAGoAAAAAAAQANS4xLjI1LXJjLWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAy42RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
+';
+
+# ... this event corresponding to
+#
+# INSERT INTO char63_utf8 VALUES ( 1, "123", 1 )
+#
+# The binlog event below shall not trigger the bug check
+
+BINLOG '
+3u9kSBMBAAAANgAAAJYBAAAAABAAAAAAAAAABHRlc3QAC2NoYXI2M191dGY4AAMD/gMC/r0A
+3u9kSBcBAAAAKgAAAMABAAAQABAAAAAAAAEAA//4AQAAAAMxMjMBAAAA
+';
+SELECT * FROM char63_utf8;
+
+# ... and this is an event corresponding to
+#
+# INSERT INTO char128_utf8 VALUES ( 1, "123", 1 )
+#
+# The binlog event below shall trigger the bug check and produce an error
+#
+
+error ER_UNKNOWN_ERROR;
+BINLOG '
+iONkSBMBAAAANwAAAJkBAAAAABAAAAAAAAAABHRlc3QADGNoYXIxMjhfdXRmOAADA/4DAv6AAA==
+iONkSBcBAAAAKwAAAMQBAAAQABAAAAAAAAEAA//4AQAAAAMAMTIzAQAAAA==
+';
+
+drop table t1, char63_utf8, char128_utf8;
=== added file 'mysql-test/suite/bugs/combinations'
--- a/mysql-test/suite/bugs/combinations 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/bugs/combinations 2008-06-30 20:11:18 +0000
@@ -0,0 +1,8 @@
+[row]
+--binlog-format=row
+
+[stmt]
+--binlog-format=statement
+
+[mix]
+--binlog-format=mixed
=== added file 'mysql-test/suite/bugs/r/rpl_bug33029.result'
--- a/mysql-test/suite/bugs/r/rpl_bug33029.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/bugs/r/rpl_bug33029.result 2008-06-19 18:47:59 +0000
@@ -0,0 +1,15 @@
+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;
+create table `t1` (`id` int not null auto_increment primary key);
+create trigger `trg` before insert on `t1` for each row begin end;
+set @@global.debug="+d,simulate_bug33029";
+stop slave;
+start slave;
+insert into `t1` values ();
+select * from t1;
+id
+1
=== added file 'mysql-test/suite/bugs/r/rpl_bug37426.result'
--- a/mysql-test/suite/bugs/r/rpl_bug37426.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/bugs/r/rpl_bug37426.result 2008-06-30 20:11:18 +0000
@@ -0,0 +1,17 @@
+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;
+CREATE TABLE char128_utf8 (
+i1 INT NOT NULL,
+c CHAR(128) CHARACTER SET utf8 NOT NULL,
+i2 INT NOT NULL);
+INSERT INTO char128_utf8 VALUES ( 1, "123", 1 );
+SELECT * FROM char128_utf8;
+i1 c i2
+1 123 1
+SELECT * FROM char128_utf8;
+i1 c i2
+1 123 1
=== added file 'mysql-test/suite/bugs/t/rpl_bug33029.test'
--- a/mysql-test/suite/bugs/t/rpl_bug33029.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/bugs/t/rpl_bug33029.test 2008-06-19 18:47:59 +0000
@@ -0,0 +1,25 @@
+#
+# Bug #36443 Server crashes when executing insert when insert trigger on table
+#
+# Emulating the former bug#33029 situation to see that there is no crash anymore.
+#
+
+
+source include/master-slave.inc;
+
+create table `t1` (`id` int not null auto_increment primary key);
+create trigger `trg` before insert on `t1` for each row begin end;
+
+sync_slave_with_master;
+set @@global.debug="+d,simulate_bug33029";
+
+stop slave;
+start slave;
+
+connection master;
+
+insert into `t1` values ();
+
+sync_slave_with_master;
+select * from t1;
+
=== added file 'mysql-test/suite/bugs/t/rpl_bug37426.test'
--- a/mysql-test/suite/bugs/t/rpl_bug37426.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/bugs/t/rpl_bug37426.test 2008-06-30 20:11:18 +0000
@@ -0,0 +1,22 @@
+#############################################################
+# Author: Mats Kindahl <mats@stripped>
+# Date: 2008-06-18
+# Purpose: Test for BUG#37426
+# RBR breaks for CHAR() UTF8 fields > 85 chars
+#############################################################
+
+source include/master-slave.inc;
+source include/have_binlog_format_row.inc;
+
+connection master;
+CREATE TABLE char128_utf8 (
+ i1 INT NOT NULL,
+ c CHAR(128) CHARACTER SET utf8 NOT NULL,
+ i2 INT NOT NULL);
+
+INSERT INTO char128_utf8 VALUES ( 1, "123", 1 );
+
+SELECT * FROM char128_utf8;
+sync_slave_with_master;
+
+SELECT * FROM char128_utf8;
=== added file 'mysql-test/suite/ndb/r/ndb_dd_restore_compat.result'
--- a/mysql-test/suite/ndb/r/ndb_dd_restore_compat.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_dd_restore_compat.result 2008-08-12 18:56:42 +0000
@@ -0,0 +1,53 @@
+select * from information_schema.columns
+where table_name = "t1";
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT STORAGE FORMAT
+NULL test t1 a1 1 NULL NO smallint NULL NULL 5 0 NULL NULL smallint(6) PRI select,insert,update,references Default Default
+NULL test t1 a2 2 NULL NO int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references Default Default
+NULL test t1 a3 3 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references Default Default
+NULL test t1 a4 4 NULL YES char 10 10 NULL NULL latin1 latin1_swedish_ci char(10) select,insert,update,references Default Default
+NULL test t1 a5 5 NULL YES decimal NULL NULL 5 1 NULL NULL decimal(5,1) select,insert,update,references Default Default
+NULL test t1 a6 6 NULL YES time NULL NULL NULL NULL NULL NULL time select,insert,update,references Default Default
+NULL test t1 a7 7 NULL YES date NULL NULL NULL NULL NULL NULL date select,insert,update,references Default Default
+NULL test t1 a8 8 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references Default Default
+NULL test t1 a9 9 NULL YES varchar 255 255 NULL NULL latin1 latin1_swedish_ci varchar(255) select,insert,update,references Default Default
+NULL test t1 a10 10 NULL YES blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references Default Default
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a1` smallint(6) NOT NULL,
+ `a2` int(11) NOT NULL,
+ `a3` bigint(20) NOT NULL,
+ `a4` char(10) DEFAULT NULL,
+ `a5` decimal(5,1) DEFAULT NULL,
+ `a6` time DEFAULT NULL,
+ `a7` date DEFAULT NULL,
+ `a8` datetime DEFAULT NULL,
+ `a9` varchar(255) DEFAULT NULL,
+ `a10` blob,
+ PRIMARY KEY (`a1`)
+) /*!50100 TABLESPACE `ts` */ ENGINE=ndbcluster DEFAULT CHARSET=latin1
+a1 Smallint PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
+a2 Int NOT NULL AT=FIXED ST=DISK
+a3 Bigint NOT NULL AT=FIXED ST=DISK
+a4 Char(10;latin1_swedish_ci) NULL AT=FIXED ST=DISK
+a5 Decimal(5,1) NULL AT=FIXED ST=DISK
+a6 Time NULL AT=FIXED ST=DISK
+a7 Date NULL AT=FIXED ST=DISK
+a8 Datetime NULL AT=FIXED ST=DISK
+a9 Varchar(255;latin1_swedish_ci) NULL AT=FIXED ST=DISK
+a10 Blob(256,2000,16) NULL AT=FIXED ST=DISK BV=1
+select * from t1 order by a1;
+a1 a2 a3 a4 a5 a6 a7 a8 a9 a10
+1 2 2000000001 aaa1 34.2 04:03:02 2006-01-01 1971-05-28 16:55:03 bbbbbbbbbbbbb1 binary data
+2 3 2000000002 aaa2 34.2 04:03:02 2006-01-01 1971-05-28 16:55:03 bbbbbbbbbbbbb2 binary data
+3 4 2000000003 aaa3 34.2 04:03:02 2006-01-01 1971-05-28 16:55:03 bbbbbbbbbbbbb3 binary data
+4 5 2000000004 aaa4 34.2 04:03:02 2006-01-01 1971-05-28 16:55:03 bbbbbbbbbbbbb4 binary data
+5 6 2000000005 aaa5 34.2 04:03:02 2006-01-01 1971-05-28 16:55:03 bbbbbbbbbbbbb5 binary data
+drop table t1;
+ALTER TABLESPACE ts
+DROP DATAFILE 'datafile.dat'
+ENGINE NDB;
+drop tablespace ts
+engine ndb;
+drop logfile group lg
+engine ndb;
=== modified file 'mysql-test/suite/ndb/r/ndb_multi_row.result'
--- a/mysql-test/suite/ndb/r/ndb_multi_row.result 2007-11-01 14:08:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_multi_row.result 2008-08-07 05:29:44 +0000
@@ -63,6 +63,6 @@ t4
drop table t1, t2, t3, t4;
drop table if exists t1, t3, t4;
Warnings:
-Error 155 Table 'test.t1' doesn't exist
-Error 155 Table 'test.t3' doesn't exist
-Error 155 Table 'test.t4' doesn't exist
+Note 1051 Unknown table 't1'
+Note 1051 Unknown table 't3'
+Note 1051 Unknown table 't4'
=== modified file 'mysql-test/suite/ndb/r/ndb_restore.result'
--- a/mysql-test/suite/ndb/r/ndb_restore.result 2008-03-12 13:13:49 +0000
+++ b/mysql-test/suite/ndb/r/ndb_restore.result 2008-08-12 18:56:42 +0000
@@ -505,8 +505,29 @@ SELECT @the_backup_id:=backup_id FROM te
@the_backup_id:=backup_id
<the_backup_id>
DROP TABLE test.backup_info;
+CREATE TABLE t11_c (
+c1 int primary key, c2 char(10), c3 varchar(10)
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
+CREATE TABLE t12_c (
+c1 int primary key, c2 char(10), c3 varchar(10)
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
+INSERT INTO t11_c VALUES(1, "aaaaa", "bbbbb"), (2, "ccccc", "ddddd"), (3, "eeeee","fffff");
+INSERT INTO t12_c VALUES(4, "ggggg", "hhhhh"), (5, "iiiii", "jjjjj"), (6, "kkkkk","lllll");
+CREATE TEMPORARY TABLE IF NOT EXISTS test.backup_info (id INT, backup_id INT) ENGINE = HEAP;
+DELETE FROM test.backup_info;
+LOAD DATA INFILE '../tmp.dat' INTO TABLE test.backup_info FIELDS TERMINATED BY ',';
+SELECT @the_backup_id:=backup_id FROM test.backup_info;
+@the_backup_id:=backup_id
+<the_backup_id>
+DROP TABLE test.backup_info;
+drop table t2_c,t11_c,t12_c;
+SELECT * FROM t11_c ORDER BY c1;
+c1 c2 c3
+1 aaaaa bbbbb
+2 ccccc ddddd
+3 eeeee fffff
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
-drop table if exists t2_c;
+drop table if exists t2_c,t11_c,t12_c;
520093696,<the_backup_id>
select epoch from mysql.ndb_apply_status where server_id=0;
epoch
=== modified file 'mysql-test/suite/ndb/r/ndb_trigger.result'
--- a/mysql-test/suite/ndb/r/ndb_trigger.result 2007-07-04 20:38:53 +0000
+++ b/mysql-test/suite/ndb/r/ndb_trigger.result 2008-08-07 05:29:44 +0000
@@ -1,4 +1,7 @@
drop table if exists t1, t2, t3, t4, t5;
+flush status;
+drop table if exists t1, t2, t3, t4, t5;
+flush status;
create table t1 (id int primary key, a int not null, b decimal (63,30) default 0) engine=ndb;
create table t2 (op char(1), a int not null, b decimal (63,30)) engine=ndb;
create table t3 engine=ndb select 1 as i;
@@ -312,4 +315,29 @@ id xy
DROP TRIGGER t1_delete;
DROP TRIGGER t4_delete;
DROP TABLE t1, t2, t3, t4, t5;
+create table t1(a int, b varchar(10), c date) engine=ndb;
+CREATE TRIGGER trg1 BEFORE UPDATE ON t1 FOR EACH ROW BEGIN
+SET new.c = date(now());
+End //
+select trigger_name,event_object_table from information_schema.triggers where
+trigger_name='trg1';
+trigger_name event_object_table
+trg1 t1
+CREATE TRIGGER trg1 BEFORE UPDATE ON t1 FOR EACH ROW BEGIN
+SET new.c = date(now());
+End //
+select trigger_name,event_object_table from information_schema.triggers where
+trigger_name='trg1';
+trigger_name event_object_table
+trg1 t1
+rename table t1 to t2;
+select trigger_name,event_object_table from information_schema.triggers where
+trigger_name='trg1';
+trigger_name event_object_table
+trg1 t2
+select trigger_name,event_object_table from information_schema.triggers where
+trigger_name='trg1';
+trigger_name event_object_table
+trg1 t2
+drop table t2;
End of 5.1 tests
=== added file 'mysql-test/suite/ndb/t/ndb_dd_restore_compat.test'
--- a/mysql-test/suite/ndb/t/ndb_dd_restore_compat.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_dd_restore_compat.test 2007-08-21 15:24:09 +0000
@@ -0,0 +1,22 @@
+-- source include/have_ndb.inc
+-- source include/not_embedded.inc
+
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 1 -p 1 -m -r $MYSQL_TEST_DIR/std_data/ndb_backup51_dd >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -e -b 1 -n 2 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup51_dd >> $NDB_TOOLS_OUTPUT
+
+select * from information_schema.columns
+where table_name = "t1";
+show create table t1;
+--exec $NDB_TOOLS_DIR/ndb_desc --no-defaults -d test t1 | grep 'ST='
+select * from t1 order by a1;
+drop table t1;
+
+ALTER TABLESPACE ts
+DROP DATAFILE 'datafile.dat'
+ENGINE NDB;
+
+drop tablespace ts
+engine ndb;
+
+drop logfile group lg
+engine ndb;
=== modified file 'mysql-test/suite/ndb/t/ndb_restore.test'
--- a/mysql-test/suite/ndb/t/ndb_restore.test 2008-03-12 13:13:49 +0000
+++ b/mysql-test/suite/ndb/t/ndb_restore.test 2008-08-12 18:56:42 +0000
@@ -395,13 +395,31 @@ drop table t1_c,t3_c,t4_c,t5_c,t6_c,t7_c
--source include/ndb_backup.inc
--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults --core=0 -b $the_backup_id -n 1 -m -r --ndb-nodegroup_map '(0,1)' $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id 2>&1 | grep Translate || true
+CREATE TABLE t11_c (
+ c1 int primary key, c2 char(10), c3 varchar(10)
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
+
+CREATE TABLE t12_c (
+ c1 int primary key, c2 char(10), c3 varchar(10)
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
+
+INSERT INTO t11_c VALUES(1, "aaaaa", "bbbbb"), (2, "ccccc", "ddddd"), (3, "eeeee","fffff");
+INSERT INTO t12_c VALUES(4, "ggggg", "hhhhh"), (5, "iiiii", "jjjjj"), (6, "kkkkk","lllll");
+--source include/ndb_backup.inc
+drop table t2_c,t11_c,t12_c;
+# Only part of tables is restored, it should work
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 1 -m -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id test t11_c >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 2 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id test t11_c >> $NDB_TOOLS_OUTPUT
+#Should only t11_c is restored
+SELECT * FROM t11_c ORDER BY c1;
+
#
# Cleanup
#
--disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
-drop table if exists t2_c;
+drop table if exists t2_c,t11_c,t12_c;
--enable_warnings
#
=== modified file 'mysql-test/suite/ndb/t/ndb_trigger.test'
--- a/mysql-test/suite/ndb/t/ndb_trigger.test 2007-07-04 20:38:53 +0000
+++ b/mysql-test/suite/ndb/t/ndb_trigger.test 2008-08-07 05:29:44 +0000
@@ -1,5 +1,5 @@
# Tests which involve triggers and NDB storage engine
---source include/have_ndb.inc
+--source include/have_multi_ndb.inc
--source include/not_embedded.inc
#
@@ -14,7 +14,12 @@
#
--disable_warnings
+connection server2;
drop table if exists t1, t2, t3, t4, t5;
+flush status;
+connection server1;
+drop table if exists t1, t2, t3, t4, t5;
+flush status;
--enable_warnings
create table t1 (id int primary key, a int not null, b decimal (63,30) default 0) engine=ndb;
@@ -218,4 +223,39 @@ DROP TRIGGER t1_delete;
DROP TRIGGER t4_delete;
DROP TABLE t1, t2, t3, t4, t5;
+# Test for bug#36658
+# Verify that rename table
+# doesn't remove triggers
+
+connection server1;
+create table t1(a int, b varchar(10), c date) engine=ndb;
+delimiter //;
+CREATE TRIGGER trg1 BEFORE UPDATE ON t1 FOR EACH ROW BEGIN
+ SET new.c = date(now());
+End //
+delimiter ;//
+select trigger_name,event_object_table from information_schema.triggers where
+trigger_name='trg1';
+
+connection server2;
+delimiter //;
+CREATE TRIGGER trg1 BEFORE UPDATE ON t1 FOR EACH ROW BEGIN
+ SET new.c = date(now());
+End //
+delimiter ;//
+select trigger_name,event_object_table from information_schema.triggers where
+trigger_name='trg1';
+
+connection server1;
+rename table t1 to t2;
+select trigger_name,event_object_table from information_schema.triggers where
+trigger_name='trg1';
+
+connection server2;
+select trigger_name,event_object_table from information_schema.triggers where
+trigger_name='trg1';
+
+connection server1;
+drop table t2;
+
--echo End of 5.1 tests
=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result 2008-03-12 13:13:49 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result 2008-08-12 18:56:42 +0000
@@ -33,11 +33,11 @@ drop table mysqltest.t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 102 # ALTER DATABASE mysqltest CHARACTER SET latin1
-master-bin.000001 # Query 102 # use `mysqltest`; drop table `t1`
+master-bin.000001 # Query 102 # use `mysqltest`; drop table `mysqltest`.`t1`
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 102 # ALTER DATABASE mysqltest CHARACTER SET latin1
-master-bin.000001 # Query 102 # use `mysqltest`; drop table `t1`
+master-bin.000001 # Query 102 # use `mysqltest`; drop table `mysqltest`.`t1`
reset master;
reset master;
use test;
@@ -161,10 +161,10 @@ Log_name Pos Event_type Server_id End_lo
master-bin1.000001 # Query 1 # use `test`; create table t1 (a int key) engine=ndb
master-bin1.000001 # Query 1 # use `test`; create table t2 (a int key) engine=ndb
master-bin1.000001 # Query 1 # use `test`; create table t3 (a int key) engine=ndb
-master-bin1.000001 # Query 1 # use `test`; rename table `test.t3` to `test.t4`
-master-bin1.000001 # Query 1 # use `test`; rename table `test.t2` to `test.t3`
-master-bin1.000001 # Query 1 # use `test`; rename table `test.t1` to `test.t2`
-master-bin1.000001 # Query 1 # use `test`; rename table `test.t4` to `test.t1`
+master-bin1.000001 # Query 1 # use `test`; rename table `test`.`t3` to `test`.`t4`
+master-bin1.000001 # Query 1 # use `test`; rename table `test`.`t2` to `test`.`t3`
+master-bin1.000001 # Query 1 # use `test`; rename table `test`.`t1` to `test`.`t2`
+master-bin1.000001 # Query 1 # use `test`; rename table `test`.`t4` to `test`.`t1`
drop table t1;
drop table t2;
drop table t3;
@@ -188,7 +188,7 @@ master-bin1.000001 # Table_map 102 # tab
master-bin1.000001 # Write_rows 102 # table_id: #
master-bin1.000001 # Write_rows 102 # table_id: # flags: STMT_END_F
master-bin1.000001 # Query 102 # COMMIT
-master-bin1.000001 # Query 1 # use `test`; rename table `test.t1` to `test.t2`
+master-bin1.000001 # Query 1 # use `test`; rename table `test`.`t1` to `test`.`t2`
master-bin1.000001 # Query 102 # BEGIN
master-bin1.000001 # Table_map 102 # table_id: # (test.t2)
master-bin1.000001 # Table_map 102 # table_id: # (mysql.ndb_apply_status)
=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_format.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_format.result 2008-03-27 08:28:03 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_format.result 2008-08-12 18:56:42 +0000
@@ -24,9 +24,4 @@ master-bin.000001 # Query # # use `test`
master-bin.000001 # Query # # use `test`; UPDATE t1, t3 SET m = 2, e = 3 WHERE n = f
master-bin.000001 # Query # # use `test`; UPDATE t3, t2 SET e = 2, b = 3 WHERE f = c
master-bin.000001 # Query # # use `test`; COMMIT
-master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Table_map # # table_id: # (test.t3)
-master-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
-master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
DROP TABLE t1, t2, t3;
=== modified file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result 2008-03-12 13:13:49 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result 2008-08-12 18:56:42 +0000
@@ -13,22 +13,12 @@ Warnings:
Warning 1478 Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query 1 # BEGIN
-master-bin.000001 # Table_map 1 # table_id: # (mysqltest.t1)
-master-bin.000001 # Table_map 1 # table_id: # (mysql.ndb_apply_status)
-master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
-master-bin.000001 # Query 1 # COMMIT
reset master;
use mysqltest;
insert into t2 values (1,1);
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin1.000001 # Query 102 # BEGIN
-master-bin1.000001 # Table_map 102 # table_id: # (mysqltest.t1)
-master-bin1.000001 # Table_map 102 # table_id: # (mysql.ndb_apply_status)
-master-bin1.000001 # Write_rows 102 # table_id: # flags: STMT_END_F
-master-bin1.000001 # Query 102 # COMMIT
-master-bin1.000001 # Query 102 # BEGIN
master-bin1.000001 # Table_map 102 # table_id: # (mysqltest.t2)
master-bin1.000001 # Table_map 102 # table_id: # (mysql.ndb_apply_status)
master-bin1.000001 # Write_rows 102 # table_id: #
@@ -63,8 +53,8 @@ use mysqltest;
insert into t2 values (1,1);
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin1.000001 # Query 1 # use `mysqltest`; drop table `t1`
-master-bin1.000001 # Query 1 # use `mysqltest`; drop table `t2`
+master-bin1.000001 # Query 1 # use `mysqltest`; drop table `mysqltest`.`t1`
+master-bin1.000001 # Query 1 # use `mysqltest`; drop table `mysqltest`.`t2`
master-bin1.000001 # Query 1 # use `mysqltest`; create table t1 (d int key, e int) engine=ndb
master-bin1.000001 # Query 1 # use `mysqltest`; create table t2 (d int key, e int) engine=ndb
master-bin1.000001 # Query 102 # BEGIN
=== added file 'mysql-test/suite/ndb_binlog/r/ndb_binlog_restore.result'
--- a/mysql-test/suite/ndb_binlog/r/ndb_binlog_restore.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_restore.result 2008-06-18 15:03:43 +0000
@@ -0,0 +1,101 @@
+drop table if exists t1;
+#
+# create a table with some data with and without binlogging
+#
+create table t1 (a int key, b int) engine ndb;
+insert into t1 values (1,1);
+@the_backup_id:=backup_id
+<the_backup_id>
+#
+# extra table to be used to ensure data has arrived to binlog
+create table t2 (a int key, b int) engine ndb;
+#
+# reset and restore schema
+drop table t1;
+reset master;
+show tables;
+Tables_in_test
+t2
+t1
+#
+# restore and _no_ binlog
+#
+# check the binlog, should be empty
+# extra insert (not logged) to ensure data has arrived to binlog
+set SQL_LOG_BIN=0;
+insert into t2 values (1,1);
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+#
+# reset and restore schema again
+drop table t1;
+reset master;
+show tables;
+Tables_in_test
+t2
+t1
+#
+# restore and binlog should now happen
+#
+# check the binlog, should contain data
+# extra insert (not logged) to ensure data has arrived to binlog
+set SQL_LOG_BIN=0;
+insert into t2 values (2,2);
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # BEGIN
+master-bin.000001 # Table_map 1 # table_id: # (test.t1)
+master-bin.000001 # Table_map 1 # table_id: # (mysql.ndb_apply_status)
+master-bin.000001 # Write_rows 1 # table_id: #
+master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
+master-bin.000001 # Query 1 # COMMIT
+drop table t1, t2;
+#
+# Now more complex using "BANK schema" including restore of log
+#
+CREATE DATABASE IF NOT EXISTS BANK;
+DROP DATABASE BANK;
+CREATE DATABASE BANK default charset=latin1 default collate=latin1_bin;
+USE BANK;
+CREATE TABLE GL ( TIME BIGINT UNSIGNED NOT NULL,
+ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+BALANCE INT UNSIGNED NOT NULL,
+DEPOSIT_COUNT INT UNSIGNED NOT NULL,
+DEPOSIT_SUM INT UNSIGNED NOT NULL,
+WITHDRAWAL_COUNT INT UNSIGNED NOT NULL,
+WITHDRAWAL_SUM INT UNSIGNED NOT NULL,
+PURGED INT UNSIGNED NOT NULL,
+PRIMARY KEY USING HASH (TIME,ACCOUNT_TYPE))
+ENGINE = NDB;
+CREATE TABLE ACCOUNT ( ACCOUNT_ID INT UNSIGNED NOT NULL,
+OWNER INT UNSIGNED NOT NULL,
+BALANCE INT UNSIGNED NOT NULL,
+ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+PRIMARY KEY USING HASH (ACCOUNT_ID))
+ENGINE = NDB;
+CREATE TABLE TRANSACTION ( TRANSACTION_ID BIGINT UNSIGNED NOT NULL,
+ACCOUNT INT UNSIGNED NOT NULL,
+ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+OTHER_ACCOUNT INT UNSIGNED NOT NULL,
+TRANSACTION_TYPE INT UNSIGNED NOT NULL,
+TIME BIGINT UNSIGNED NOT NULL,
+AMOUNT INT UNSIGNED NOT NULL,
+PRIMARY KEY USING HASH (TRANSACTION_ID,ACCOUNT))
+ENGINE = NDB;
+CREATE TABLE SYSTEM_VALUES ( SYSTEM_VALUES_ID INT UNSIGNED NOT NULL,
+VALUE BIGINT UNSIGNED NOT NULL,
+PRIMARY KEY USING HASH (SYSTEM_VALUES_ID))
+ENGINE = NDB;
+CREATE TABLE ACCOUNT_TYPE ( ACCOUNT_TYPE_ID INT UNSIGNED NOT NULL,
+DESCRIPTION CHAR(64) NOT NULL,
+PRIMARY KEY USING HASH (ACCOUNT_TYPE_ID))
+ENGINE = NDB;
+#
+# reset, restore and binlog should _not_ happen
+reset master;
+select count(*) from TRANSACTION;
+count(*)
+3444
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+DROP DATABASE BANK;
=== added file 'mysql-test/suite/ndb_binlog/t/ndb_binlog_restore.test'
--- a/mysql-test/suite/ndb_binlog/t/ndb_binlog_restore.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_binlog/t/ndb_binlog_restore.test 2008-06-18 15:03:43 +0000
@@ -0,0 +1,126 @@
+-- source include/have_ndb.inc
+-- source include/have_binlog_format_mixed_or_row.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+--echo #
+--echo # create a table with some data with and without binlogging
+--echo #
+create table t1 (a int key, b int) engine ndb;
+insert into t1 values (1,1);
+
+# backup and drop data
+--disable_query_log
+--source include/ndb_backup.inc
+--enable_query_log
+
+--echo #
+--echo # extra table to be used to ensure data has arrived to binlog
+create table t2 (a int key, b int) engine ndb;
+
+--echo #
+--echo # reset and restore schema
+drop table t1;
+reset master;
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 1 -m --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+show tables;
+
+--echo #
+--echo # restore and _no_ binlog
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults --no-binlog -b $the_backup_id -n 1 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults --no-binlog -b $the_backup_id -n 2 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+
+--echo #
+--echo # check the binlog, should be empty
+--echo # extra insert (not logged) to ensure data has arrived to binlog
+set SQL_LOG_BIN=0;
+insert into t2 values (1,1);
+--source include/show_binlog_events2.inc
+
+--echo #
+--echo # reset and restore schema again
+drop table t1;
+reset master;
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 1 -m --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+show tables;
+
+--echo #
+--echo # restore and binlog should now happen
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 1 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 2 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+
+--echo #
+--echo # check the binlog, should contain data
+--echo # extra insert (not logged) to ensure data has arrived to binlog
+set SQL_LOG_BIN=0;
+insert into t2 values (2,2);
+--source include/show_binlog_events2.inc
+
+drop table t1, t2;
+
+
+
+--echo #
+--echo # Now more complex using "BANK schema" including restore of log
+--echo #
+--disable_warnings
+CREATE DATABASE IF NOT EXISTS BANK;
+DROP DATABASE BANK;
+--enable_warnings
+CREATE DATABASE BANK default charset=latin1 default collate=latin1_bin;
+
+#
+# These tables should correspond to the table definitions in
+# storage/ndb/test/src/NDBT_Tables.cpp
+#
+USE BANK;
+CREATE TABLE GL ( TIME BIGINT UNSIGNED NOT NULL,
+ ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+ BALANCE INT UNSIGNED NOT NULL,
+ DEPOSIT_COUNT INT UNSIGNED NOT NULL,
+ DEPOSIT_SUM INT UNSIGNED NOT NULL,
+ WITHDRAWAL_COUNT INT UNSIGNED NOT NULL,
+ WITHDRAWAL_SUM INT UNSIGNED NOT NULL,
+ PURGED INT UNSIGNED NOT NULL,
+ PRIMARY KEY USING HASH (TIME,ACCOUNT_TYPE))
+ ENGINE = NDB;
+
+CREATE TABLE ACCOUNT ( ACCOUNT_ID INT UNSIGNED NOT NULL,
+ OWNER INT UNSIGNED NOT NULL,
+ BALANCE INT UNSIGNED NOT NULL,
+ ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+ PRIMARY KEY USING HASH (ACCOUNT_ID))
+ ENGINE = NDB;
+
+CREATE TABLE TRANSACTION ( TRANSACTION_ID BIGINT UNSIGNED NOT NULL,
+ ACCOUNT INT UNSIGNED NOT NULL,
+ ACCOUNT_TYPE INT UNSIGNED NOT NULL,
+ OTHER_ACCOUNT INT UNSIGNED NOT NULL,
+ TRANSACTION_TYPE INT UNSIGNED NOT NULL,
+ TIME BIGINT UNSIGNED NOT NULL,
+ AMOUNT INT UNSIGNED NOT NULL,
+ PRIMARY KEY USING HASH (TRANSACTION_ID,ACCOUNT))
+ ENGINE = NDB;
+
+CREATE TABLE SYSTEM_VALUES ( SYSTEM_VALUES_ID INT UNSIGNED NOT NULL,
+ VALUE BIGINT UNSIGNED NOT NULL,
+ PRIMARY KEY USING HASH (SYSTEM_VALUES_ID))
+ ENGINE = NDB;
+
+CREATE TABLE ACCOUNT_TYPE ( ACCOUNT_TYPE_ID INT UNSIGNED NOT NULL,
+ DESCRIPTION CHAR(64) NOT NULL,
+ PRIMARY KEY USING HASH (ACCOUNT_TYPE_ID))
+ ENGINE = NDB;
+
+--echo #
+--echo # reset, restore and binlog should _not_ happen
+reset master;
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults --no-binlog -b 1 -n 1 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults --no-binlog -b 1 -n 2 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT
+
+select count(*) from TRANSACTION;
+--source include/show_binlog_events2.inc
+
+DROP DATABASE BANK;
=== modified file 'mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result'
--- a/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result 2007-12-12 19:12:29 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result 2008-08-12 18:56:42 +0000
@@ -437,7 +437,76 @@ SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
COUNT(*) 0
set @@global.slave_exec_mode= default;
Last_SQL_Error
-0
+
SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
COUNT(*) 0
DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE t1 (i INT NOT NULL,
+c CHAR(16) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'MYISAM' ;
+CREATE TABLE t2 (i INT NOT NULL,
+c CHAR(16) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'MYISAM' ;
+ALTER TABLE t2 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t3 (i INT NOT NULL,
+c CHAR(128) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'MYISAM' ;
+ALTER TABLE t3 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t4 (i INT NOT NULL,
+c CHAR(128) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'MYISAM' ;
+CREATE TABLE t5 (i INT NOT NULL,
+c CHAR(255) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'MYISAM' ;
+ALTER TABLE t5 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t6 (i INT NOT NULL,
+c CHAR(255) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'MYISAM' ;
+ALTER TABLE t6 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t7 (i INT NOT NULL,
+c CHAR(255) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'MYISAM' ;
+[expecting slave to replicate correctly]
+INSERT INTO t1 VALUES (1, "", 1);
+INSERT INTO t1 VALUES (2, repeat(_utf8'a', 16), 2);
+Comparing tables master:test.t1 and slave:test.t1
+[expecting slave to replicate correctly]
+INSERT INTO t2 VALUES (1, "", 1);
+INSERT INTO t2 VALUES (2, repeat(_utf8'a', 16), 2);
+Comparing tables master:test.t2 and slave:test.t2
+[expecting slave to stop]
+INSERT INTO t3 VALUES (1, "", 1);
+INSERT INTO t3 VALUES (2, repeat(_utf8'a', 128), 2);
+Last_SQL_Error
+Table definition on master and slave does not match: Column 1 size mismatch - master has size 512, test.t3 on slave has size 65. Master's column size should be <= the slave's column size.
+RESET MASTER;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+[expecting slave to replicate correctly]
+INSERT INTO t4 VALUES (1, "", 1);
+INSERT INTO t4 VALUES (2, repeat(_utf8'a', 128), 2);
+Comparing tables master:test.t4 and slave:test.t4
+[expecting slave to stop]
+INSERT INTO t5 VALUES (1, "", 1);
+INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2);
+Last_SQL_Error
+Table definition on master and slave does not match: Column 1 size mismatch - master has size 1020, test.t5 on slave has size 65. Master's column size should be <= the slave's column size.
+RESET MASTER;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+[expecting slave to stop]
+INSERT INTO t6 VALUES (1, "", 1);
+INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2);
+Last_SQL_Error
+Table definition on master and slave does not match: Column 1 size mismatch - master has size 1020, test.t6 on slave has size 513. Master's column size should be <= the slave's column size.
+RESET MASTER;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+[expecting slave to replicate correctly]
+INSERT INTO t7 VALUES (1, "", 1);
+INSERT INTO t7 VALUES (2, repeat(_utf8'a', 255), 2);
+Comparing tables master:test.t7 and slave:test.t7
+drop table t1, t2, t3, t4, t5, t6, t7;
=== modified file 'mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result'
--- a/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result 2007-12-12 19:12:29 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result 2008-08-12 18:56:42 +0000
@@ -437,7 +437,76 @@ SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
COUNT(*) 0
set @@global.slave_exec_mode= default;
Last_SQL_Error
-0
+
SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
COUNT(*) 0
DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE t1 (i INT NOT NULL,
+c CHAR(16) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'INNODB' ;
+CREATE TABLE t2 (i INT NOT NULL,
+c CHAR(16) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'INNODB' ;
+ALTER TABLE t2 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t3 (i INT NOT NULL,
+c CHAR(128) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'INNODB' ;
+ALTER TABLE t3 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t4 (i INT NOT NULL,
+c CHAR(128) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'INNODB' ;
+CREATE TABLE t5 (i INT NOT NULL,
+c CHAR(255) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'INNODB' ;
+ALTER TABLE t5 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t6 (i INT NOT NULL,
+c CHAR(255) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'INNODB' ;
+ALTER TABLE t6 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t7 (i INT NOT NULL,
+c CHAR(255) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'INNODB' ;
+[expecting slave to replicate correctly]
+INSERT INTO t1 VALUES (1, "", 1);
+INSERT INTO t1 VALUES (2, repeat(_utf8'a', 16), 2);
+Comparing tables master:test.t1 and slave:test.t1
+[expecting slave to replicate correctly]
+INSERT INTO t2 VALUES (1, "", 1);
+INSERT INTO t2 VALUES (2, repeat(_utf8'a', 16), 2);
+Comparing tables master:test.t2 and slave:test.t2
+[expecting slave to stop]
+INSERT INTO t3 VALUES (1, "", 1);
+INSERT INTO t3 VALUES (2, repeat(_utf8'a', 128), 2);
+Last_SQL_Error
+Table definition on master and slave does not match: Column 1 size mismatch - master has size 512, test.t3 on slave has size 65. Master's column size should be <= the slave's column size.
+RESET MASTER;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+[expecting slave to replicate correctly]
+INSERT INTO t4 VALUES (1, "", 1);
+INSERT INTO t4 VALUES (2, repeat(_utf8'a', 128), 2);
+Comparing tables master:test.t4 and slave:test.t4
+[expecting slave to stop]
+INSERT INTO t5 VALUES (1, "", 1);
+INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2);
+Last_SQL_Error
+Table definition on master and slave does not match: Column 1 size mismatch - master has size 1020, test.t5 on slave has size 65. Master's column size should be <= the slave's column size.
+RESET MASTER;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+[expecting slave to stop]
+INSERT INTO t6 VALUES (1, "", 1);
+INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2);
+Last_SQL_Error
+Table definition on master and slave does not match: Column 1 size mismatch - master has size 1020, test.t6 on slave has size 513. Master's column size should be <= the slave's column size.
+RESET MASTER;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+[expecting slave to replicate correctly]
+INSERT INTO t7 VALUES (1, "", 1);
+INSERT INTO t7 VALUES (2, repeat(_utf8'a', 255), 2);
+Comparing tables master:test.t7 and slave:test.t7
+drop table t1, t2, t3, t4, t5, t6, t7;
=== modified file 'mysql-test/suite/rpl/t/disabled.def'
--- a/mysql-test/suite/rpl/t/disabled.def 2008-05-19 08:32:08 +0000
+++ b/mysql-test/suite/rpl/t/disabled.def 2008-08-12 18:56:42 +0000
@@ -29,4 +29,4 @@ rpl_log_pos : Bug#8693 Te
rpl_row_basic_7ndb : BUG#33360 2007-12-19 mats rpl_ndb_idempotent fails due to null field for table on slave side
rpl_redirect : Failure is sporadic and and the test is superfluous (mats)
rpl_innodb_bug28430 : Failure on Solaris Bug #36793
-
+rpl_server_id1 : Bug #36818 rpl_server_id1 fails expecting slave has stopped (azundris)
=== modified file 'mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result 2008-02-11 16:11:22 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result 2008-08-12 18:56:42 +0000
@@ -437,7 +437,76 @@ SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
COUNT(*) 0
set @@global.slave_exec_mode= default;
Last_SQL_Error
-0
+
SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
COUNT(*) 0
DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE t1 (i INT NOT NULL,
+c CHAR(16) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'NDB' ;
+CREATE TABLE t2 (i INT NOT NULL,
+c CHAR(16) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'NDB' ;
+ALTER TABLE t2 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t3 (i INT NOT NULL,
+c CHAR(128) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'NDB' ;
+ALTER TABLE t3 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t4 (i INT NOT NULL,
+c CHAR(128) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'NDB' ;
+CREATE TABLE t5 (i INT NOT NULL,
+c CHAR(255) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'NDB' ;
+ALTER TABLE t5 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t6 (i INT NOT NULL,
+c CHAR(255) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'NDB' ;
+ALTER TABLE t6 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
+CREATE TABLE t7 (i INT NOT NULL,
+c CHAR(255) CHARACTER SET utf8 NOT NULL,
+j INT NOT NULL) ENGINE = 'NDB' ;
+[expecting slave to replicate correctly]
+INSERT INTO t1 VALUES (1, "", 1);
+INSERT INTO t1 VALUES (2, repeat(_utf8'a', 16), 2);
+Comparing tables master:test.t1 and slave:test.t1
+[expecting slave to replicate correctly]
+INSERT INTO t2 VALUES (1, "", 1);
+INSERT INTO t2 VALUES (2, repeat(_utf8'a', 16), 2);
+Comparing tables master:test.t2 and slave:test.t2
+[expecting slave to stop]
+INSERT INTO t3 VALUES (1, "", 1);
+INSERT INTO t3 VALUES (2, repeat(_utf8'a', 128), 2);
+Last_SQL_Error
+Table definition on master and slave does not match: Column 1 size mismatch - master has size 512, test.t3 on slave has size 65. Master's column size should be <= the slave's column size.
+RESET MASTER;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+[expecting slave to replicate correctly]
+INSERT INTO t4 VALUES (1, "", 1);
+INSERT INTO t4 VALUES (2, repeat(_utf8'a', 128), 2);
+Comparing tables master:test.t4 and slave:test.t4
+[expecting slave to stop]
+INSERT INTO t5 VALUES (1, "", 1);
+INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2);
+Last_SQL_Error
+Table definition on master and slave does not match: Column 1 size mismatch - master has size 1020, test.t5 on slave has size 65. Master's column size should be <= the slave's column size.
+RESET MASTER;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+[expecting slave to stop]
+INSERT INTO t6 VALUES (1, "", 1);
+INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2);
+Last_SQL_Error
+Table definition on master and slave does not match: Column 1 size mismatch - master has size 1020, test.t6 on slave has size 513. Master's column size should be <= the slave's column size.
+RESET MASTER;
+STOP SLAVE;
+RESET SLAVE;
+START SLAVE;
+[expecting slave to replicate correctly]
+INSERT INTO t7 VALUES (1, "", 1);
+INSERT INTO t7 VALUES (2, repeat(_utf8'a', 255), 2);
+Comparing tables master:test.t7 and slave:test.t7
+drop table t1, t2, t3, t4, t5, t6, t7;
=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def 2008-08-08 09:40:47 +0000
+++ b/mysql-test/t/disabled.def 2008-08-12 18:56:42 +0000
@@ -30,16 +30,92 @@ query_cache_wlock_invalidate_func: Bug#3
thread_cache_size_func: BUG#35988, BUG#36733 Due to not deterministic results
cast : Bug#35594 2008-03-27 main.cast fails on Windows2003-64
subselect_notembedded : Bug#35803, Bug#33506 2008-Apr-03 subselect_notembedded crashes the server
-user_limits : Bug#23921 random failure of user_limits.test
-key_buffer_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
-rpl_recovery_rank_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
-sort_buffer_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
log_output_basic : Bug#34820 log_output can be set to illegal value
-query_cache_size_basic_32 : Bug#36747: Allocating a large query cache is not deterministic
-query_cache_size_basic_64 : Bug#36747: Allocating a large query cache is not deterministic
wait_timeout_func : Bug #36873 wait_timeout_func.test fails randomly
slow_launch_time_func : Bug #36874 main.slow_launch_time_func test fails randomly
-sort_buffer_size_basic_32 : Bug#36875 main.sort_buffer_size_basic_32 fails on some systems
-key_buffer_size_basic_32 : Bug#36876 main.key_buffer_size_basic_32 fails on some systems
-max_heap_table_size_basic_32 : Bug#36877 main.max_heap_table_size_basic_32 fails on some systems
-tmp_table_size_basic_32 : Bug#36878 main.tmp_table_size_basic_32 fails on some systems
+thread_cache_size_func : Bug#36733 main.thread_cache_size_func fails randomly
+binlog_cache_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+bulk_insert_buffer_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+delayed_insert_limit_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+delayed_queue_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+innodb_concurrency_tickets_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+innodb_max_purge_lag_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+innodb_sync_spin_loops_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+join_buffer_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+key_buffer_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+key_cache_age_threshold_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+key_cache_block_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+key_cache_division_limit_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+log_warnings_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_binlog_cache_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_connect_errors_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_heap_table_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_seeks_for_key_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_tmp_tables_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_write_lock_count_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+min_examined_row_limit_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+multi_range_count_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+myisam_max_sort_file_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+myisam_repair_threads_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+myisam_sort_buffer_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+net_retry_count_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_alloc_block_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_cache_limit_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_cache_min_res_unit_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_cache_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_prealloc_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+range_alloc_block_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+rpl_recovery_rank_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+server_id_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+slave_transaction_retries_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+sort_buffer_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+sync_binlog_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+timestamp_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+tmp_table_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+transaction_alloc_block_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+transaction_prealloc_size_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+wait_timeout_basic_32 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+binlog_cache_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+bulk_insert_buffer_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+delayed_insert_limit_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+delayed_queue_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+innodb_concurrency_tickets_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+innodb_max_purge_lag_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+innodb_sync_spin_loops_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+join_buffer_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+key_buffer_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+key_cache_age_threshold_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+key_cache_block_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+key_cache_division_limit_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+log_warnings_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_binlog_cache_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_connect_errors_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_heap_table_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_seeks_for_key_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_tmp_tables_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+max_write_lock_count_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+min_examined_row_limit_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+multi_range_count_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+myisam_max_sort_file_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+myisam_repair_threads_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+myisam_sort_buffer_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+net_retry_count_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_alloc_block_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_cache_limit_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_cache_min_res_unit_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_cache_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+query_prealloc_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+range_alloc_block_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+rpl_recovery_rank_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+server_id_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+slave_transaction_retries_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+sort_buffer_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+sync_binlog_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+timestamp_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+tmp_table_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+transaction_alloc_block_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+transaction_prealloc_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+wait_timeout_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+log_tables.test : Bug #37798: main.log_tables fails randomly on powermacg5 and windows
+slow_query_log_func.test : Bug #37962: *_func tests containing sleeps/race conditions
+
=== modified file 'mysql-test/t/status.test'
--- a/mysql-test/t/status.test 2008-05-27 14:51:23 +0000
+++ b/mysql-test/t/status.test 2008-08-12 18:56:42 +0000
@@ -258,7 +258,6 @@ create function f1 (x INTEGER) returns i
DELIMITER ;//
drop function f1;
-
show status like 'Com%function';
# End of 5.1 tests
=== modified file 'mysql-test/t/subselect.test'
--- a/mysql-test/t/subselect.test 2008-05-22 18:40:15 +0000
+++ b/mysql-test/t/subselect.test 2008-08-12 18:56:42 +0000
@@ -3647,3 +3647,15 @@ SELECT * FROM t1 WHERE EXISTS ( SELECT 1
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
DROP TABLE t1, t2;
+
+#
+# Bug #37004: NOT IN subquery with MAX over an empty set
+#
+CREATE TABLE t1(c int, KEY(c));
+CREATE TABLE t2(a int, b int);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+
+DROP TABLE t1,t2;
=== modified file 'scripts/make_binary_distribution.sh'
--- a/scripts/make_binary_distribution.sh 2008-08-08 09:40:47 +0000
+++ b/scripts/make_binary_distribution.sh 2008-08-12 18:56:42 +0000
@@ -92,6 +92,7 @@ if [ x"$PLATFORM" = x"" ] ; then
system=`echo $system | sed -e 's/darwin6.*/osx10.2/g'`
system=`echo $system | sed -e 's/darwin7.*/osx10.3/g'`
system=`echo $system | sed -e 's/darwin8.*/osx10.4/g'`
+ system=`echo $system | sed -e 's/darwin9.*/osx10.5/g'`
system=`echo $system | sed -e 's/\(aix4.3\).*/\1/g'`
system=`echo $system | sed -e 's/\(aix5.1\).*/\1/g'`
system=`echo $system | sed -e 's/\(aix5.2\).*/\1/g'`
=== added directory 'server-tools'
=== added directory 'server-tools/instance-manager'
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2008-08-08 09:40:47 +0000
+++ b/sql/field.cc 2008-08-12 18:56:42 +0000
@@ -27,6 +27,8 @@
#include "mysql_priv.h"
#include "sql_select.h"
+#include "rpl_rli.h" // Pull in Relay_log_info
+#include "slave.h" // Pull in rpl_master_has_bug()
#include <m_ctype.h>
#include <errno.h>
#ifdef HAVE_FCONVERT
@@ -1375,7 +1377,8 @@ bool Field::send_binary(Protocol *protoc
@retval 0 if this field's size is < the source field's size
@retval 1 if this field's size is >= the source field's size
*/
-int Field::compatible_field_size(uint field_metadata)
+int Field::compatible_field_size(uint field_metadata,
+ const Relay_log_info *rli_arg __attribute__((unused)))
{
uint const source_size= pack_length_from_metadata(field_metadata);
uint const destination_size= row_pack_length();
@@ -2820,7 +2823,8 @@ uint Field_new_decimal::pack_length_from
@retval 0 if this field's size is < the source field's size
@retval 1 if this field's size is >= the source field's size
*/
-int Field_new_decimal::compatible_field_size(uint field_metadata)
+int Field_new_decimal::compatible_field_size(uint field_metadata,
+ const Relay_log_info * __attribute__((unused)))
{
int compatible= 0;
uint const source_precision= (field_metadata >> 8U) & 0x00ff;
@@ -4020,7 +4024,6 @@ Field_real::pack(uchar *to, const uchar
{
DBUG_ENTER("Field_real::pack");
DBUG_ASSERT(max_length >= pack_length());
- DBUG_PRINT("debug", ("pack_length(): %u", pack_length()));
#ifdef WORDS_BIGENDIAN
if (low_byte_first != table->s->db_low_byte_first)
{
@@ -4039,7 +4042,6 @@ Field_real::unpack(uchar *to, const ucha
uint param_data, bool low_byte_first)
{
DBUG_ENTER("Field_real::unpack");
- DBUG_PRINT("debug", ("pack_length(): %u", pack_length()));
#ifdef WORDS_BIGENDIAN
if (low_byte_first != table->s->db_low_byte_first)
{
@@ -6458,6 +6460,37 @@ my_decimal *Field_string::val_decimal(my
}
+struct Check_field_param {
+ Field *field;
+};
+
+#ifdef HAVE_REPLICATION
+static bool
+check_field_for_37426(const void *param_arg)
+{
+ Check_field_param *param= (Check_field_param*) param_arg;
+ DBUG_ASSERT(param->field->real_type() == MYSQL_TYPE_STRING);
+ DBUG_PRINT("debug", ("Field %s - type: %d, size: %d",
+ param->field->field_name,
+ param->field->real_type(),
+ param->field->row_pack_length()));
+ return param->field->row_pack_length() > 255;
+}
+#endif
+
+int Field_string::compatible_field_size(uint field_metadata,
+ const Relay_log_info *rli_arg)
+{
+#ifdef HAVE_REPLICATION
+ const Check_field_param check_param = { this };
+ if (rpl_master_has_bug(rli_arg, 37426, TRUE,
+ check_field_for_37426, &check_param))
+ return FALSE; // Not compatible field sizes
+#endif
+ return Field::compatible_field_size(field_metadata, rli_arg);
+}
+
+
int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
uint a_len, b_len;
@@ -6544,6 +6577,9 @@ uchar *Field_string::pack(uchar *to, con
@c param_data argument contains the result of field->real_type() from
the master.
+ @note For information about how the length is packed, see @c
+ Field_string::do_save_field_metadata
+
@param to Destination of the data
@param from Source of the data
@param param_data Real type (upper) and length (lower) values
@@ -6556,10 +6592,24 @@ Field_string::unpack(uchar *to,
uint param_data,
bool low_byte_first __attribute__((unused)))
{
- uint from_length=
- param_data ? min(param_data & 0x00ff, field_length) : field_length;
- uint length;
+ uint from_length, length;
+
+ /*
+ Compute the declared length of the field on the master. This is
+ used to decide if one or two bytes should be read as length.
+ */
+ if (param_data)
+ from_length= (((param_data >> 4) & 0x300) ^ 0x300) + (param_data & 0x00ff);
+ else
+ from_length= field_length;
+ DBUG_PRINT("debug",
+ ("param_data: 0x%x, field_length: %u, from_length: %u",
+ param_data, field_length, from_length));
+ /*
+ Compute the actual length of the data by reading one or two bits
+ (depending on the declared field length on the master).
+ */
if (from_length > 255)
{
length= uint2korr(from);
@@ -6582,14 +6632,37 @@ Field_string::unpack(uchar *to,
second byte of the field metadata array at index of *metadata_ptr and
*(metadata_ptr + 1).
+ @note In order to be able to handle lengths exceeding 255 and be
+ backwards-compatible with pre-5.1.26 servers, an extra two bits of
+ the length has been added to the metadata in such a way that if
+ they are set, a new unrecognized type is generated. This will
+ cause pre-5.1-26 servers to stop due to a field type mismatch,
+ while new servers will be able to extract the extra bits. If the
+ length is <256, there will be no difference and both a new and an
+ old server will be able to handle it.
+
+ @note The extra two bits are added to bits 13 and 14 of the
+ parameter data (with 1 being the least siginficant bit and 16 the
+ most significant bit of the word) by xoring the extra length bits
+ with the real type. Since all allowable types have 0xF as most
+ significant bits of the metadata word, lengths <256 will not affect
+ the real type at all, while all other values will result in a
+ non-existant type in the range 17-244.
+
+ @see Field_string::unpack
+
@param metadata_ptr First byte of field metadata
@returns number of bytes written to metadata_ptr
*/
int Field_string::do_save_field_metadata(uchar *metadata_ptr)
{
- *metadata_ptr= real_type();
- *(metadata_ptr + 1)= field_length;
+ DBUG_ASSERT(field_length < 1024);
+ DBUG_ASSERT((real_type() & 0xF0) == 0xF0);
+ DBUG_PRINT("debug", ("field_length: %u, real_type: %u",
+ field_length, real_type()));
+ *metadata_ptr= (real_type() ^ ((field_length & 0x300) >> 4));
+ *(metadata_ptr + 1)= field_length & 0xFF;
return 2;
}
@@ -8943,7 +9016,8 @@ uint Field_bit::pack_length_from_metadat
@retval 0 if this field's size is < the source field's size
@retval 1 if this field's size is >= the source field's size
*/
-int Field_bit::compatible_field_size(uint field_metadata)
+int Field_bit::compatible_field_size(uint field_metadata,
+ const Relay_log_info * __attribute__((unused)))
{
int compatible= 0;
uint const source_size= pack_length_from_metadata(field_metadata);
=== modified file 'sql/field.h'
--- a/sql/field.h 2008-08-08 09:40:47 +0000
+++ b/sql/field.h 2008-08-12 18:56:42 +0000
@@ -29,6 +29,8 @@ const uint32 max_field_size= (uint32) 42
class Send_field;
class Protocol;
class Create_field;
+class Relay_log_info;
+
struct st_cache_field;
int field_conv(Field *to,Field *from);
@@ -161,7 +163,8 @@ public:
table, which is located on disk).
*/
virtual uint32 pack_length_in_rec() const { return pack_length(); }
- virtual int compatible_field_size(uint field_metadata);
+ virtual int compatible_field_size(uint field_metadata,
+ const Relay_log_info *);
virtual uint pack_length_from_metadata(uint field_metadata)
{ return field_metadata; }
/*
@@ -753,7 +756,8 @@ public:
uint32 pack_length() const { return (uint32) bin_size; }
uint pack_length_from_metadata(uint field_metadata);
uint row_pack_length() { return pack_length(); }
- int compatible_field_size(uint field_metadata);
+ int compatible_field_size(uint field_metadata,
+ const Relay_log_info *rli);
uint is_equal(Create_field *new_field);
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
@@ -1462,7 +1466,14 @@ public:
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
uint pack_length_from_metadata(uint field_metadata)
- { return (field_metadata & 0x00ff); }
+ {
+ DBUG_PRINT("debug", ("field_metadata: 0x%04x", field_metadata));
+ if (field_metadata == 0)
+ return row_pack_length();
+ return (((field_metadata >> 4) & 0x300) ^ 0x300) + (field_metadata & 0x00ff);
+ }
+ int compatible_field_size(uint field_metadata,
+ const Relay_log_info *rli);
uint row_pack_length() { return (field_length + 1); }
int pack_cmp(const uchar *a,const uchar *b,uint key_length,
my_bool insert_or_update);
@@ -1916,7 +1927,8 @@ public:
uint pack_length_from_metadata(uint field_metadata);
uint row_pack_length()
{ return (bytes_in_rec + ((bit_len > 0) ? 1 : 0)); }
- int compatible_field_size(uint field_metadata);
+ int compatible_field_size(uint field_metadata,
+ const Relay_log_info *rli);
void sql_type(String &str) const;
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first);
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2008-08-08 09:40:47 +0000
+++ b/sql/ha_ndbcluster.cc 2008-08-12 18:56:42 +0000
@@ -152,6 +152,7 @@ static int ndb_get_table_statistics(ha_n
static int ndb_get_table_statistics(ha_ndbcluster*, bool, Ndb*,
const NdbRecord *, struct Ndb_statistics *);
+THD *injector_thd= 0;
// Util thread variables
pthread_t ndb_util_thread;
@@ -5964,6 +5965,17 @@ int ha_ndbcluster::rename_table(const ch
DBUG_ENTER("ha_ndbcluster::rename_table");
DBUG_PRINT("info", ("Renaming %s to %s", from, to));
+
+ if (thd == injector_thd)
+ {
+ /*
+ Table was renamed remotely is already
+ renamed inside ndb.
+ Just rename .ndb file.
+ */
+ DBUG_RETURN(handler::rename_table(from, to));
+ }
+
set_dbname(from, old_dbname);
set_dbname(to, new_dbname);
set_tabname(from);
@@ -6038,7 +6050,7 @@ int ha_ndbcluster::rename_table(const ch
#endif
ERR_RETURN(ndb_error);
}
-
+
// Rename .ndb file
if ((result= handler::rename_table(from, to)))
{
@@ -6344,6 +6356,17 @@ int ha_ndbcluster::delete_table(const ch
int error= 0;
DBUG_ENTER("ha_ndbcluster::delete_table");
DBUG_PRINT("enter", ("name: %s", name));
+
+ if (thd == injector_thd)
+ {
+ /*
+ Table was dropped remotely is already
+ dropped inside ndb.
+ Just drop local files.
+ */
+ DBUG_RETURN(handler::delete_table(name));
+ }
+
set_dbname(name);
set_tabname(name);
=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc 2008-08-08 09:40:47 +0000
+++ b/sql/ha_ndbcluster_binlog.cc 2008-08-12 18:56:42 +0000
@@ -72,7 +72,7 @@ my_bool ndb_binlog_is_ready= FALSE;
Has one sole purpose, for setting the in_use table member variable
in get_share(...)
*/
-THD *injector_thd= 0;
+extern THD * injector_thd; // Declared in ha_ndbcluster.cc
/*
Global reference to ndb injector thd object.
@@ -141,12 +141,6 @@ static void ndb_free_schema_object(NDB_S
bool have_lock);
/*
- Global variables for holding the ndb_binlog_index table reference
-*/
-static TABLE *ndb_binlog_index= 0;
-static TABLE_LIST binlog_tables;
-
-/*
Helper functions
*/
@@ -309,15 +303,6 @@ static void run_query(THD *thd, char *bu
thd->transaction.all= save_thd_transaction_all;
thd->transaction.stmt= save_thd_transaction_stmt;
thd->net= save_thd_net;
-
- if (thd == injector_thd)
- {
- /*
- running the query will close all tables, including the ndb_binlog_index
- used in injector_thd
- */
- ndb_binlog_index= 0;
- }
}
static void
@@ -1304,8 +1289,9 @@ int ndbcluster_log_schema_op(THD *thd,
DBUG_RETURN(0);
/* redo the drop table query as is may contain several tables */
query= tmp_buf2;
- query_length= (uint) (strxmov(tmp_buf2, "drop table `",
- table_name, "`", NullS) - tmp_buf2);
+ query_length= (uint) (strxmov(tmp_buf2, "drop table ",
+ "`", db, "`", ".",
+ "`", table_name, "`", NullS) - tmp_buf2);
type_str= "drop table";
break;
case SOT_RENAME_TABLE_PREPARE:
@@ -1315,9 +1301,11 @@ int ndbcluster_log_schema_op(THD *thd,
case SOT_RENAME_TABLE:
/* redo the rename table query as is may contain several tables */
query= tmp_buf2;
- query_length= (uint) (strxmov(tmp_buf2, "rename table `",
- db, ".", table_name, "` to `",
- new_db, ".", new_table_name, "`", NullS) - tmp_buf2);
+ query_length= (uint) (strxmov(tmp_buf2, "rename table ",
+ "`", db, "`", ".",
+ "`", table_name, "` to ",
+ "`", new_db, "`", ".",
+ "`", new_table_name, "`", NullS) - tmp_buf2);
type_str= "rename table";
break;
case SOT_CREATE_TABLE:
@@ -1858,17 +1846,53 @@ ndb_binlog_thread_handle_schema_event(TH
if (schema->node_id != node_id)
{
int log_query= 0, post_epoch_unlock= 0;
+ char errmsg[MYSQL_ERRMSG_SIZE];
+
switch (schema_type)
{
- case SOT_DROP_TABLE:
- // fall through
case SOT_RENAME_TABLE:
// fall through
case SOT_RENAME_TABLE_NEW:
- post_epoch_log_list->push_back(schema, mem_root);
- /* acknowledge this query _after_ epoch completion */
- post_epoch_unlock= 1;
- break;
+ {
+ uint end= snprintf(&errmsg[0], MYSQL_ERRMSG_SIZE,
+ "NDB Binlog: Skipping renaming locally defined table '%s.%s' from binlog schema event '%s' from node %d. ",
+ schema->db, schema->name, schema->query,
+ schema->node_id);
+
+ errmsg[end]= '\0';
+ }
+ // fall through
+ case SOT_DROP_TABLE:
+ if (schema_type == SOT_DROP_TABLE)
+ {
+ uint end= snprintf(&errmsg[0], MYSQL_ERRMSG_SIZE,
+ "NDB Binlog: Skipping dropping locally defined table '%s.%s' from binlog schema event '%s' from node %d. ",
+ schema->db, schema->name, schema->query,
+ schema->node_id);
+ errmsg[end]= '\0';
+ }
+ if (! ndbcluster_check_if_local_table(schema->db, schema->name))
+ {
+ const int no_print_error[1]=
+ {ER_BAD_TABLE_ERROR}; /* ignore missing table */
+ run_query(thd, schema->query,
+ schema->query + schema->query_length,
+ no_print_error, // /* don't print error */
+ TRUE); // /* don't binlog the query */
+
+ /* binlog dropping table after any table operations */
+ post_epoch_log_list->push_back(schema, mem_root);
+ /* acknowledge this query _after_ epoch completion */
+ post_epoch_unlock= 1;
+ }
+ else
+ {
+ /* Tables exists as a local table, leave it */
+ DBUG_PRINT("info", ((const char *) errmsg));
+ sql_print_error((const char *) errmsg);
+ log_query= 1;
+ }
+ // Fall through
case SOT_TRUNCATE_TABLE:
{
char key[FN_REFLEN];
@@ -1904,6 +1928,8 @@ ndb_binlog_thread_handle_schema_event(TH
free_share(&share);
}
}
+ if (schema_type != SOT_TRUNCATE_TABLE)
+ break;
// fall through
case SOT_CREATE_TABLE:
pthread_mutex_lock(&LOCK_open);
@@ -2526,8 +2552,8 @@ struct ndb_binlog_index_row {
/*
Open the ndb_binlog_index table
*/
-static int open_ndb_binlog_index(THD *thd, TABLE_LIST *tables,
- TABLE **ndb_binlog_index)
+static int open_and_lock_ndb_binlog_index(THD *thd, TABLE_LIST *tables,
+ TABLE **ndb_binlog_index)
{
static char repdb[]= NDB_REP_DB;
static char reptable[]= NDB_REP_TABLE;
@@ -2539,9 +2565,8 @@ static int open_ndb_binlog_index(THD *th
tables->lock_type= TL_WRITE;
THD_SET_PROC_INFO(thd, "Opening " NDB_REP_DB "." NDB_REP_TABLE);
tables->required_type= FRMTYPE_TABLE;
- uint counter;
thd->clear_error();
- if (open_tables(thd, &tables, &counter, MYSQL_LOCK_IGNORE_FLUSH))
+ if (simple_open_n_lock_tables(thd, tables))
{
if (thd->killed)
sql_print_error("NDB Binlog: Opening ndb_binlog_index: killed");
@@ -2558,32 +2583,6 @@ static int open_ndb_binlog_index(THD *th
return 0;
}
-
-/*
- Check if ndb_binlog_index is lockable, if not close, to free for
- other threads use
-*/
-
-static void
-ndb_check_ndb_binlog_index(THD *thd)
-{
- if (!ndb_binlog_index)
- return;
-
- bool need_reopen;
- if (lock_tables(thd, &binlog_tables, 1, &need_reopen))
- {
- ndb_binlog_index= 0;
- close_thread_tables(thd);
- ndb_binlog_index= 0;
- return;
- }
-
- mysql_unlock_tables(thd, thd->lock);
- thd->lock= 0;
- return;
-}
-
/*
Insert one row in the ndb_binlog_index
*/
@@ -2592,8 +2591,10 @@ static int
ndb_add_ndb_binlog_index(THD *thd, ndb_binlog_index_row *row)
{
int error= 0;
- bool need_reopen;
ndb_binlog_index_row *first= row;
+ TABLE *ndb_binlog_index= 0;
+ TABLE_LIST binlog_tables;
+
/*
Turn of binlogging to prevent the table changes to be written to
the binary log.
@@ -2601,28 +2602,12 @@ ndb_add_ndb_binlog_index(THD *thd, ndb_b
ulong saved_options= thd->options;
thd->options&= ~(OPTION_BIN_LOG);
- for ( ; ; ) /* loop for need_reopen */
- {
- if (!ndb_binlog_index && open_ndb_binlog_index(thd, &binlog_tables, &ndb_binlog_index))
- {
- error= -1;
- goto add_ndb_binlog_index_err;
- }
- if (lock_tables(thd, &binlog_tables, 1, &need_reopen))
- {
- if (need_reopen)
- {
- TABLE_LIST *p_binlog_tables= &binlog_tables;
- close_tables_for_reopen(thd, &p_binlog_tables);
- ndb_binlog_index= 0;
- continue;
- }
- sql_print_error("NDB Binlog: Unable to lock table ndb_binlog_index");
- error= -1;
- goto add_ndb_binlog_index_err;
- }
- break;
+ if (open_and_lock_ndb_binlog_index(thd, &binlog_tables, &ndb_binlog_index))
+ {
+ sql_print_error("NDB Binlog: Unable to lock table ndb_binlog_index");
+ error= -1;
+ goto add_ndb_binlog_index_err;
}
/*
@@ -2671,13 +2656,8 @@ ndb_add_ndb_binlog_index(THD *thd, ndb_b
}
} while (row);
- mysql_unlock_tables(thd, thd->lock);
- thd->lock= 0;
- thd->options= saved_options;
- return 0;
add_ndb_binlog_index_err:
close_thread_tables(thd);
- ndb_binlog_index= 0;
thd->options= saved_options;
return error;
}
@@ -3885,7 +3865,8 @@ ndb_find_binlog_index_row(ndb_binlog_ind
static int
ndb_binlog_thread_handle_data_event(Ndb *ndb, NdbEventOperation *pOp,
ndb_binlog_index_row **rows,
- injector::transaction &trans)
+ injector::transaction &trans,
+ unsigned &trans_row_count)
{
Ndb_event_data *event_data= (Ndb_event_data *) pOp->getCustomData();
TABLE *table= event_data->table;
@@ -3982,6 +3963,7 @@ ndb_binlog_thread_handle_data_event(Ndb
{
case NDBEVENT::TE_INSERT:
row->n_inserts++;
+ trans_row_count++;
DBUG_PRINT("info", ("INSERT INTO %s.%s",
table->s->db.str, table->s->table_name.str));
{
@@ -4004,6 +3986,7 @@ ndb_binlog_thread_handle_data_event(Ndb
break;
case NDBEVENT::TE_DELETE:
row->n_deletes++;
+ trans_row_count++;
DBUG_PRINT("info",("DELETE FROM %s.%s",
table->s->db.str, table->s->table_name.str));
{
@@ -4044,6 +4027,7 @@ ndb_binlog_thread_handle_data_event(Ndb
break;
case NDBEVENT::TE_UPDATE:
row->n_updates++;
+ trans_row_count++;
DBUG_PRINT("info", ("UPDATE %s.%s",
table->s->db.str, table->s->table_name.str));
{
@@ -4579,15 +4563,6 @@ restart:
!ndb_binlog_running))
break; /* Shutting down server */
- if (ndb_binlog_index && ndb_binlog_index->s->version < refresh_version)
- {
- if (ndb_binlog_index->s->version < refresh_version)
- {
- close_thread_tables(thd);
- ndb_binlog_index= 0;
- }
- }
-
MEM_ROOT **root_ptr=
my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC);
MEM_ROOT *old_root= *root_ptr;
@@ -4645,17 +4620,8 @@ restart:
}
}
- /*
- For each epoch atleast one check should be made to see if ndb_binlog_index
- table is lockable. Variable 'do_check_ndb_binlog_index' is used as a flag
- to signal if a check is needed for current epoch.
- */
- int do_check_ndb_binlog_index= 1;
-
if (res > 0)
{
- do_check_ndb_binlog_index= 1;
-
DBUG_PRINT("info", ("pollEvents res: %d", res));
THD_SET_PROC_INFO(thd, "Processing events");
NdbEventOperation *pOp= i_ndb->nextEvent();
@@ -4686,6 +4652,7 @@ restart:
bzero((char*) &_row, sizeof(_row));
thd->variables.character_set_client= &my_charset_latin1;
injector::transaction trans;
+ unsigned trans_row_count= 0;
// pass table map before epoch
{
Uint32 iter= 0;
@@ -4852,7 +4819,7 @@ restart:
#endif
if ((unsigned) pOp->getEventType() <
(unsigned) NDBEVENT::TE_FIRST_NON_DATA_EVENT)
- ndb_binlog_thread_handle_data_event(i_ndb, pOp, &rows, trans);
+ ndb_binlog_thread_handle_data_event(i_ndb, pOp, &rows, trans, trans_row_count);
else
{
// set injector_ndb database/schema from table internal name
@@ -4895,9 +4862,20 @@ restart:
write_timer.stop();
#endif
- if (trans.good())
+ while (trans.good())
{
- //DBUG_ASSERT(row.n_inserts || row.n_updates || row.n_deletes);
+ if (trans_row_count == 0)
+ {
+ /* nothing to commit, rollback instead */
+ if (int r= trans.rollback())
+ {
+ sql_print_error("NDB Binlog: "
+ "Error during ROLLBACK of GCI %u/%u. Error: %d",
+ uint(gci >> 32), uint(gci), r);
+ /* TODO: Further handling? */
+ }
+ break;
+ }
THD_SET_PROC_INFO(thd, "Committing events to binlog");
injector::transaction::binlog_pos start= trans.start_pos();
if (int r= trans.commit())
@@ -4916,18 +4894,12 @@ restart:
if (ndb_update_ndb_binlog_index)
{
ndb_add_ndb_binlog_index(thd, rows);
- do_check_ndb_binlog_index= 0;
}
ndb_latest_applied_binlog_epoch= gci;
+ break;
}
ndb_latest_handled_binlog_epoch= gci;
- if (do_check_ndb_binlog_index)
- {
- ndb_check_ndb_binlog_index(thd);
- do_check_ndb_binlog_index= 0;
- }
-
#ifdef RUN_NDB_BINLOG_TIMER
gci_timer.stop();
sql_print_information("gci %ld event_count %d write time "
@@ -4960,25 +4932,16 @@ restart:
free_root(&mem_root, MYF(0));
*root_ptr= old_root;
ndb_latest_handled_binlog_epoch= ndb_latest_received_binlog_epoch;
-
- if (do_check_ndb_binlog_index)
- {
- ndb_check_ndb_binlog_index(thd);
- do_check_ndb_binlog_index= 0;
- }
}
if (do_ndbcluster_binlog_close_connection == BCCC_restart)
{
ndb_binlog_tables_inited= FALSE;
- close_thread_tables(thd);
- ndb_binlog_index= 0;
goto restart;
}
err:
sql_print_information("Stopping Cluster Binlog");
DBUG_PRINT("info",("Shutting down cluster binlog thread"));
THD_SET_PROC_INFO(thd, "Shutting down");
- close_thread_tables(thd);
pthread_mutex_lock(&injector_mutex);
/* don't mess with the injector_ndb anymore from other threads */
injector_thd= 0;
=== modified file 'sql/rpl_injector.cc'
--- a/sql/rpl_injector.cc 2008-03-03 21:12:44 +0000
+++ b/sql/rpl_injector.cc 2008-08-12 18:56:42 +0000
@@ -86,6 +86,14 @@ int injector::transaction::commit()
DBUG_RETURN(0);
}
+int injector::transaction::rollback()
+{
+ DBUG_ENTER("injector::transaction::rollback()");
+ ha_autocommit_or_rollback(m_thd, 1 /* error to get rollback */);
+ end_trans(m_thd, ROLLBACK);
+ DBUG_RETURN(0);
+}
+
int injector::transaction::use_table(server_id_type sid, table tbl)
{
DBUG_ENTER("injector::transaction::use_table");
=== modified file 'sql/rpl_injector.h'
--- a/sql/rpl_injector.h 2008-02-11 10:16:47 +0000
+++ b/sql/rpl_injector.h 2008-08-12 18:56:42 +0000
@@ -238,6 +238,14 @@ public:
int commit();
/*
+ Rollback a transaction.
+
+ This member function will clean up after a sequence of *_row calls by,
+ for example, releasing resource and unlocking files.
+ */
+ int rollback();
+
+ /*
Get the position for the start of the transaction.
Returns the position in the binary log of the first event in this
=== modified file 'sql/rpl_utility.cc'
--- a/sql/rpl_utility.cc 2008-02-12 10:27:52 +0000
+++ b/sql/rpl_utility.cc 2008-08-12 18:56:42 +0000
@@ -188,7 +188,8 @@ table_def::compatible_with(Relay_log_inf
for (uint col= 0 ; col < cols_to_check ; ++col)
{
- if (table->field[col]->type() != type(col))
+ Field *const field= table->field[col];
+ if (field->type() != type(col))
{
DBUG_ASSERT(col < size() && col < tsh->fields);
DBUG_ASSERT(tsh->db.str && tsh->table_name.str);
@@ -197,15 +198,15 @@ table_def::compatible_with(Relay_log_inf
my_snprintf(buf, sizeof(buf), "Column %d type mismatch - "
"received type %d, %s.%s has type %d",
col, type(col), tsh->db.str, tsh->table_name.str,
- table->field[col]->type());
+ field->type());
rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF,
ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf);
}
/*
Check the slave's field size against that of the master.
*/
- if (!error &&
- !table->field[col]->compatible_field_size(field_metadata(col)))
+ if (!error &&
+ !field->compatible_field_size(field_metadata(col), rli_arg))
{
error= 1;
char buf[256];
@@ -213,10 +214,9 @@ table_def::compatible_with(Relay_log_inf
"master has size %d, %s.%s on slave has size %d."
" Master's column size should be <= the slave's "
"column size.", col,
- table->field[col]->pack_length_from_metadata(
- m_field_metadata[col]),
- tsh->db.str, tsh->table_name.str,
- table->field[col]->row_pack_length());
+ field->pack_length_from_metadata(m_field_metadata[col]),
+ tsh->db.str, tsh->table_name.str,
+ field->row_pack_length());
rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF,
ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf);
}
=== modified file 'sql/slave.cc'
--- a/sql/slave.cc 2008-08-08 09:40:47 +0000
+++ b/sql/slave.cc 2008-08-12 18:56:42 +0000
@@ -3945,9 +3945,17 @@ end:
@param rli Relay_log_info which tells the master's version
@param bug_id Number of the bug as found in bugs.mysql.com
@param report bool report error message, default TRUE
+
+ @param pred Predicate function that will be called with @c param to
+ check for the bug. If the function return @c true, the bug is present,
+ otherwise, it is not.
+
+ @param param State passed to @c pred function.
+
@return TRUE if master has the bug, FALSE if it does not.
*/
-bool rpl_master_has_bug(Relay_log_info *rli, uint bug_id, bool report)
+bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report,
+ bool (*pred)(const void *), const void *param)
{
struct st_version_range_for_one_bug {
uint bug_id;
@@ -3960,6 +3968,7 @@ bool rpl_master_has_bug(Relay_log_info *
{24432, { 5, 1, 12 }, { 5, 1, 17 } },
{33029, { 5, 0, 0 }, { 5, 0, 58 } },
{33029, { 5, 1, 0 }, { 5, 1, 12 } },
+ {37426, { 5, 1, 0 }, { 5, 1, 26 } },
};
const uchar *master_ver=
rli->relay_log.description_event_for_exec->server_version_split;
@@ -3973,11 +3982,11 @@ bool rpl_master_has_bug(Relay_log_info *
*fixed_in= versions_for_all_bugs[i].fixed_in;
if ((versions_for_all_bugs[i].bug_id == bug_id) &&
(memcmp(introduced_in, master_ver, 3) <= 0) &&
- (memcmp(fixed_in, master_ver, 3) > 0))
+ (memcmp(fixed_in, master_ver, 3) > 0) &&
+ (pred == NULL || (*pred)(param)))
{
if (!report)
return TRUE;
-
// a short message for SHOW SLAVE STATUS (message length constraints)
my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from"
" http://bugs.mysql.com/bug.php?id=%u"
@@ -4024,7 +4033,8 @@ bool rpl_master_erroneous_autoinc(THD *t
if (active_mi && active_mi->rli.sql_thd == thd)
{
Relay_log_info *rli= &active_mi->rli;
- return rpl_master_has_bug(rli, 33029, FALSE);
+ DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;);
+ return rpl_master_has_bug(rli, 33029, FALSE, NULL, NULL);
}
return FALSE;
}
=== modified file 'sql/slave.h'
--- a/sql/slave.h 2008-05-16 08:56:03 +0000
+++ b/sql/slave.h 2008-08-12 18:56:42 +0000
@@ -175,7 +175,8 @@ int fetch_master_table(THD* thd, const c
bool show_master_info(THD* thd, Master_info* mi);
bool show_binlog_info(THD* thd);
-bool rpl_master_has_bug(Relay_log_info *rli, uint bug_id, bool report=TRUE);
+bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report,
+ bool (*pred)(const void *), const void *param);
bool rpl_master_erroneous_autoinc(THD* thd);
const char *print_slave_db_safe(const char *db);
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2008-08-08 09:40:47 +0000
+++ b/sql/sql_class.cc 2008-08-12 18:56:42 +0000
@@ -2948,8 +2948,8 @@ void THD::reset_sub_statement_state(Sub_
*/
if (rpl_master_erroneous_autoinc(this))
{
- backup->auto_inc_intervals_forced= auto_inc_intervals_forced;
- auto_inc_intervals_forced.empty();
+ DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
+ auto_inc_intervals_forced.swap(&backup->auto_inc_intervals_forced);
}
#endif
@@ -2997,8 +2997,8 @@ void THD::restore_sub_statement_state(Su
*/
if (rpl_master_erroneous_autoinc(this))
{
- auto_inc_intervals_forced= backup->auto_inc_intervals_forced;
- backup->auto_inc_intervals_forced.empty();
+ backup->auto_inc_intervals_forced.swap(&auto_inc_intervals_forced);
+ DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
}
#endif
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2008-05-16 08:56:03 +0000
+++ b/sql/sql_insert.cc 2008-08-12 18:56:42 +0000
@@ -702,7 +702,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
if (thd->slave_thread &&
(info.handle_duplicates == DUP_UPDATE) &&
(table->next_number_field != NULL) &&
- rpl_master_has_bug(&active_mi->rli, 24432))
+ rpl_master_has_bug(&active_mi->rli, 24432, TRUE, NULL, NULL))
goto abort;
#endif
@@ -2972,7 +2972,7 @@ select_insert::prepare(List<Item> &value
if (thd->slave_thread &&
(info.handle_duplicates == DUP_UPDATE) &&
(table->next_number_field != NULL) &&
- rpl_master_has_bug(&active_mi->rli, 24432))
+ rpl_master_has_bug(&active_mi->rli, 24432, TRUE, NULL, NULL))
DBUG_RETURN(1);
#endif
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2008-08-08 09:40:47 +0000
+++ b/sql/sql_select.cc 2008-08-12 18:56:42 +0000
@@ -1479,6 +1479,7 @@ JOIN::optimize()
{
DBUG_PRINT("info",("No matching min/max row"));
zero_result_cause= "No matching min/max row";
+ tables= 0;
error=0;
DBUG_RETURN(0);
}
@@ -1492,6 +1493,7 @@ JOIN::optimize()
{
DBUG_PRINT("info",("No matching min/max row"));
zero_result_cause= "No matching min/max row";
+ tables= 0;
error=0;
DBUG_RETURN(0);
}
=== modified file 'sql/structs.h'
--- a/sql/structs.h 2008-08-08 09:40:47 +0000
+++ b/sql/structs.h 2008-08-12 18:56:42 +0000
@@ -320,31 +320,22 @@ private:
*/
Discrete_interval *current;
uint elements; // number of elements
-
- /* helper function for copy construct and assignment operator */
- void copy_(const Discrete_intervals_list& from)
- {
- for (Discrete_interval *i= from.head; i; i= i->next)
- {
- Discrete_interval j= *i;
- append(&j);
- }
+ void set_members(Discrete_interval *h, Discrete_interval *t,
+ Discrete_interval *c, uint el)
+ {
+ head= h;
+ tail= t;
+ current= c;
+ elements= el;
}
+ void operator=(Discrete_intervals_list &); /* prevent use of these */
+ Discrete_intervals_list(const Discrete_intervals_list &);
+
public:
Discrete_intervals_list() : head(NULL), current(NULL), elements(0) {};
- Discrete_intervals_list(const Discrete_intervals_list& from)
- {
- copy_(from);
- }
- void operator=(const Discrete_intervals_list& from)
- {
- empty();
- copy_(from);
- }
void empty_no_free()
{
- head= current= NULL;
- elements= 0;
+ set_members(NULL, NULL, NULL, 0);
}
void empty()
{
@@ -356,7 +347,24 @@ public:
}
empty_no_free();
}
-
+ void copy_shallow(const Discrete_intervals_list * dli)
+ {
+ head= dli->get_head();
+ tail= dli->get_tail();
+ current= dli->get_current();
+ elements= dli->nb_elements();
+ }
+ void swap (Discrete_intervals_list * dli)
+ {
+ Discrete_interval *h, *t, *c;
+ uint el;
+ h= dli->get_head();
+ t= dli->get_tail();
+ c= dli->get_current();
+ el= dli->nb_elements();
+ dli->copy_shallow(this);
+ set_members(h, t, c, el);
+ }
const Discrete_interval* get_next()
{
Discrete_interval *tmp= current;
@@ -370,4 +378,7 @@ public:
ulonglong minimum() const { return (head ? head->minimum() : 0); };
ulonglong maximum() const { return (head ? tail->maximum() : 0); };
uint nb_elements() const { return elements; }
+ Discrete_interval* get_head() const { return head; };
+ Discrete_interval* get_tail() const { return tail; };
+ Discrete_interval* get_current() const { return current; };
};
=== modified file 'storage/ndb/include/kernel/signaldata/SumaImpl.hpp'
--- a/storage/ndb/include/kernel/signaldata/SumaImpl.hpp 2008-02-20 09:04:29 +0000
+++ b/storage/ndb/include/kernel/signaldata/SumaImpl.hpp 2008-06-16 06:25:29 +0000
@@ -39,7 +39,8 @@ struct SubCreateReq {
GetFlags = 0xff << 16,
RestartFlag = 0x2 << 16,
ReportAll = 0x4 << 16,
- ReportSubscribe= 0x8 << 16
+ ReportSubscribe= 0x8 << 16,
+ NR_Sub_Dropped = 0x1 << 24 // sub is dropped but needs to be copied
};
Uint32 senderRef;
=== modified file 'storage/ndb/include/mgmapi/mgmapi.h'
--- a/storage/ndb/include/mgmapi/mgmapi.h 2008-03-28 10:31:07 +0000
+++ b/storage/ndb/include/mgmapi/mgmapi.h 2008-08-07 03:44:29 +0000
@@ -444,10 +444,6 @@ extern "C" {
int ndb_mgm_number_of_mgmd_in_connect_string(NdbMgmHandle handle);
int ndb_mgm_set_configuration_nodeid(NdbMgmHandle handle, int nodeid);
- int ndb_mgm_get_configuration_nodeid(NdbMgmHandle handle);
- int ndb_mgm_get_connected_port(NdbMgmHandle handle);
- const char *ndb_mgm_get_connected_host(NdbMgmHandle handle);
- const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz);
/**
* Set local bindaddress
=== modified file 'storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp'
--- a/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp 2008-03-19 11:15:48 +0000
+++ b/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp 2008-08-12 18:56:42 +0000
@@ -317,6 +317,7 @@ int
NdbIndexScanOperation::setBound(const char* attr, int type, const void* value,
Uint32 len)
{
+ (void)len; // unused
return setBound(attr, type, value);
}
@@ -325,6 +326,7 @@ int
NdbIndexScanOperation::setBound(Uint32 anAttrId, int type, const void* value,
Uint32 len)
{
+ (void)len; // unused
return setBound(anAttrId, type, value);
}
=== modified file 'storage/ndb/include/ndbapi/NdbOperation.hpp'
--- a/storage/ndb/include/ndbapi/NdbOperation.hpp 2008-04-28 14:17:28 +0000
+++ b/storage/ndb/include/ndbapi/NdbOperation.hpp 2008-08-07 06:24:52 +0000
@@ -1447,6 +1447,9 @@ inline
int
NdbOperation::checkMagicNumber(bool b)
{
+#ifndef NDB_NO_DROPPED_SIGNAL
+ (void)b; // unused param in this context
+#endif
if (theMagicNumber != 0xABCDEF01){
#ifdef NDB_NO_DROPPED_SIGNAL
if(b) abort();
@@ -1566,8 +1569,10 @@ NdbOperation::NdbCon(NdbTransaction* aNd
inline
int
-NdbOperation::equal(const char* anAttrName, const char* aValue, Uint32 len)
+NdbOperation::equal(const char* anAttrName, const char* aValue,
+ Uint32 len)
{
+ (void)len; // unused
return equal(anAttrName, aValue);
}
@@ -1601,8 +1606,10 @@ NdbOperation::equal(const char* anAttrNa
inline
int
-NdbOperation::equal(Uint32 anAttrId, const char* aValue, Uint32 len)
+NdbOperation::equal(Uint32 anAttrId, const char* aValue,
+ Uint32 len)
{
+ (void)len; // unused
return equal(anAttrId, aValue);
}
@@ -1636,8 +1643,10 @@ NdbOperation::equal(Uint32 anAttrId, Uin
inline
int
-NdbOperation::setValue(const char* anAttrName, const char* aValue, Uint32 len)
+NdbOperation::setValue(const char* anAttrName, const char* aValue,
+ Uint32 len)
{
+ (void)len; // unused
return setValue(anAttrName, aValue);
}
@@ -1685,8 +1694,10 @@ NdbOperation::setValue(const char* anAtt
inline
int
-NdbOperation::setValue(Uint32 anAttrId, const char* aValue, Uint32 len)
+NdbOperation::setValue(Uint32 anAttrId, const char* aValue,
+ Uint32 len)
{
+ (void)len; // unused
return setValue(anAttrId, aValue);
}
=== modified file 'storage/ndb/include/ndbapi/NdbTransaction.hpp'
--- a/storage/ndb/include/ndbapi/NdbTransaction.hpp 2008-02-19 15:00:29 +0000
+++ b/storage/ndb/include/ndbapi/NdbTransaction.hpp 2008-08-07 06:24:52 +0000
@@ -1093,6 +1093,7 @@ inline
void
NdbTransaction::set_send_size(Uint32 send_size)
{
+ (void)send_size; //unused
return;
}
=== modified file 'storage/ndb/src/common/logger/Logger.cpp'
--- a/storage/ndb/src/common/logger/Logger.cpp 2006-12-23 19:20:40 +0000
+++ b/storage/ndb/src/common/logger/Logger.cpp 2008-07-25 16:10:36 +0000
@@ -222,6 +222,7 @@ Logger::addHandler(const BaseString &log
*err= handler->getErrorCode();
if(handler->getErrorStr())
strncpy(errStr, handler->getErrorStr(), len);
+ delete handler;
DBUG_RETURN(false);
}
loghandlers.push_back(handler);
=== modified file 'storage/ndb/src/common/portlib/NdbCondition.c'
--- a/storage/ndb/src/common/portlib/NdbCondition.c 2006-12-23 19:20:40 +0000
+++ b/storage/ndb/src/common/portlib/NdbCondition.c 2008-06-09 11:57:17 +0000
@@ -26,7 +26,51 @@ struct NdbCondition
pthread_cond_t cond;
};
+#ifdef HAVE_CLOCK_GETTIME
+static int clock_id = CLOCK_REALTIME;
+#endif
+
+void
+NdbCondition_Init()
+{
+#if defined HAVE_CLOCK_GETTIME && defined HAVE_PTHREAD_CONDATTR_SETCLOCK && \
+ defined CLOCK_MONOTONIC
+
+ int res, init = 0;
+ pthread_cond_t tmp;
+ pthread_condattr_t attr;
+ if ((res = pthread_condattr_init(&attr)) != 0)
+ goto nogo;
+
+ init = 1;
+
+ if ((res = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) != 0)
+ goto nogo;
+
+ if ((res = pthread_cond_init(&tmp, &attr)) != 0)
+ goto nogo;
+ pthread_condattr_destroy(&attr);
+ pthread_cond_destroy(&tmp);
+
+ clock_id = CLOCK_MONOTONIC;
+
+ return;
+
+nogo:
+ if (init)
+ {
+ pthread_condattr_destroy(&attr);
+ }
+
+ clock_id = CLOCK_REALTIME;
+ fprintf(stderr,
+ "Failed to use CLOCK_MONOTONIC for pthread_condition res: %u\n",
+ res);
+ fflush(stderr);
+ return;
+#endif
+}
struct NdbCondition*
NdbCondition_Create(void)
@@ -38,8 +82,24 @@ NdbCondition_Create(void)
if (tmpCond == NULL)
return NULL;
-
+
+#if defined HAVE_CLOCK_GETTIME && defined HAVE_PTHREAD_CONDATTR_SETCLOCK && \
+ defined CLOCK_MONOTONIC
+ if (clock_id == CLOCK_MONOTONIC)
+ {
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ result = pthread_cond_init(&tmpCond->cond, &attr);
+ pthread_condattr_destroy(&attr);
+ }
+ else
+ {
+ result = pthread_cond_init(&tmpCond->cond, NULL);
+ }
+#else
result = pthread_cond_init(&tmpCond->cond, NULL);
+#endif
assert(result==0);
return tmpCond;
@@ -73,7 +133,7 @@ NdbCondition_WaitTimeout(struct NdbCondi
return 1;
#ifdef HAVE_CLOCK_GETTIME
- clock_gettime(CLOCK_REALTIME, &abstime);
+ clock_gettime(clock_id, &abstime);
#else
{
struct timeval tick_time;
=== modified file 'storage/ndb/src/common/portlib/NdbTick.c'
--- a/storage/ndb/src/common/portlib/NdbTick.c 2007-06-05 16:00:42 +0000
+++ b/storage/ndb/src/common/portlib/NdbTick.c 2008-06-09 11:57:17 +0000
@@ -23,12 +23,18 @@
#define MICROSEC_PER_MILLISEC 1000
#define MILLISEC_PER_NANOSEC 1000000
-
#ifdef HAVE_CLOCK_GETTIME
+
+#ifdef CLOCK_MONOTONIC
+#define CLOCK CLOCK_MONOTONIC
+#else
+#define CLOCK CLOCK_REALTIME
+#endif
+
NDB_TICKS NdbTick_CurrentMillisecond(void)
{
struct timespec tick_time;
- clock_gettime(CLOCK_REALTIME, &tick_time);
+ clock_gettime(CLOCK, &tick_time);
return
((NDB_TICKS)tick_time.tv_sec) * ((NDB_TICKS)MILLISEC_PER_SEC) +
@@ -38,7 +44,7 @@ NDB_TICKS NdbTick_CurrentMillisecond(voi
int
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros){
struct timespec t;
- int res = clock_gettime(CLOCK_REALTIME, &t);
+ int res = clock_gettime(CLOCK, &t);
* secs = t.tv_sec;
* micros = t.tv_nsec / 1000;
return res;
=== modified file 'storage/ndb/src/common/transporter/TransporterRegistry.cpp'
--- a/storage/ndb/src/common/transporter/TransporterRegistry.cpp 2008-04-25 09:17:15 +0000
+++ b/storage/ndb/src/common/transporter/TransporterRegistry.cpp 2008-06-11 09:28:40 +0000
@@ -1165,6 +1165,17 @@ TransporterRegistry::start_clients_threa
if(t->isConnected())
t->doDisconnect();
break;
+ case DISCONNECTED:
+ {
+ if (t->isConnected())
+ {
+ g_eventLogger->warning("Found connection to %u in state DISCONNECTED "
+ " while being connected, disconnecting!",
+ t->getRemoteNodeId());
+ t->doDisconnect();
+ }
+ break;
+ }
default:
break;
}
=== modified file 'storage/ndb/src/common/util/Makefile.am'
--- a/storage/ndb/src/common/util/Makefile.am 2008-05-09 17:53:25 +0000
+++ b/storage/ndb/src/common/util/Makefile.am 2008-08-08 05:18:53 +0000
@@ -36,13 +36,13 @@ testBitmask_LDFLAGS = @ndb_bin_am_ldflag
$(top_builddir)/strings/libmystringslt.la
#noinst_PROGRAMS = ndb_show_compat
-ndb_show_compat_SOURCES = ndb_show_compat.cc
-ndb_show_compat_LDADD = \
- $(builddir)libgeneral.la \
- $(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
- $(top_builddir)/dbug/libdbuglt.la \
- $(top_builddir)/mysys/libmysyslt.la \
- $(top_builddir)/strings/libmystringslt.la
+#ndb_show_compat_SOURCES = ndb_show_compat.cpp
+#ndb_show_compat_LDADD = \
+# $(top_builddir)/storage/ndb/src/common/util/libgeneral.la \
+# $(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
+# $(top_builddir)/dbug/libdbuglt.la \
+# $(top_builddir)/mysys/libmysyslt.la \
+# $(top_builddir)/strings/libmystringslt.la
testBitmask.cpp : Bitmask.cpp
rm -f testBitmask.cpp
=== modified file 'storage/ndb/src/common/util/ndb_init.cpp'
--- a/storage/ndb/src/common/util/ndb_init.cpp 2008-04-22 19:36:05 +0000
+++ b/storage/ndb/src/common/util/ndb_init.cpp 2008-06-09 11:57:17 +0000
@@ -26,6 +26,8 @@ extern void destroy_event_logger(class E
static int ndb_init_called = 0;
+extern "C" void NdbCondition_Init();
+
extern "C"
{
@@ -44,6 +46,8 @@ ndb_init_internal()
exit(1);
}
}
+
+ NdbCondition_Init();
}
int
=== renamed file 'storage/ndb/src/common/util/ndb_show_compat.cc' => 'storage/ndb/src/common/util/ndb_show_compat.cpp'
=== modified file 'storage/ndb/src/kernel/blocks/backup/Backup.cpp'
--- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp 2008-05-16 13:08:36 +0000
+++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp 2008-06-09 11:57:17 +0000
@@ -2367,9 +2367,8 @@ Backup::stopBackupReply(Signal* signal,
void
Backup::initReportStatus(Signal *signal, BackupRecordPtr ptr)
{
- struct timeval the_time;
- gettimeofday(&the_time, 0);
- ptr.p->m_next_report = the_time.tv_sec + m_backup_report_frequency;
+ Uint64 now = NdbTick_CurrentMillisecond() / 1000;
+ ptr.p->m_next_report = now + m_backup_report_frequency;
}
void
@@ -2378,12 +2377,11 @@ Backup::checkReportStatus(Signal *signal
if (m_backup_report_frequency == 0)
return;
- struct timeval the_time;
- gettimeofday(&the_time, 0);
- if (the_time.tv_sec > ptr.p->m_next_report)
+ Uint64 now = NdbTick_CurrentMillisecond() / 1000;
+ if (now > ptr.p->m_next_report)
{
reportStatus(signal, ptr);
- ptr.p->m_next_report = the_time.tv_sec + m_backup_report_frequency;
+ ptr.p->m_next_report = now + m_backup_report_frequency;
}
}
=== modified file 'storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp 2008-04-23 14:29:01 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp 2008-06-09 10:04:48 +0000
@@ -12107,6 +12107,8 @@ void Dbdih::checkGcpStopLab(Signal* sign
*/
void Dbdih::crashSystemAtGcpStop(Signal* signal, bool local)
{
+ Uint32 save_counter = m_gcp_monitor.m_gcp_save.m_counter;
+ Uint32 micro_counter = m_gcp_monitor.m_micro_gcp.m_counter;
m_gcp_monitor.m_gcp_save.m_counter = 0;
m_gcp_monitor.m_micro_gcp.m_counter = 0;
@@ -12131,7 +12133,7 @@ void Dbdih::crashSystemAtGcpStop(Signal*
return;
}
- if (m_gcp_monitor.m_gcp_save.m_counter == m_gcp_monitor.m_gcp_save.m_max_lag)
+ if (save_counter == m_gcp_monitor.m_gcp_save.m_max_lag)
{
switch(m_gcp_save.m_master.m_state){
case GcpSave::GCP_SAVE_IDLE:
@@ -12195,7 +12197,7 @@ void Dbdih::crashSystemAtGcpStop(Signal*
}
}
- if (m_gcp_monitor.m_micro_gcp.m_counter==m_gcp_monitor.m_micro_gcp.m_max_lag)
+ if (micro_counter == m_gcp_monitor.m_micro_gcp.m_max_lag)
{
switch(m_micro_gcp.m_master.m_state){
case MicroGcp::M_GCP_IDLE:
=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2008-05-30 06:33:46 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2008-07-23 11:15:31 +0000
@@ -8955,7 +8955,7 @@ Dblqh::copy_bounds(Uint32 * dst, TcConne
if(len < left)
{
- offset = len;
+ offset = tcPtrP->m_offset_current_keybuf + len;
}
else
{
=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2008-03-26 23:22:46 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2008-08-12 18:56:42 +0000
@@ -1845,7 +1845,11 @@ int Dbtup::interpreterStartLab(Signal* s
Uint32 RattroutCounter= 0;
Uint32 RinstructionCounter= 5;
- Uint32 RlogSize= 0;
+
+ /* All information to be logged/propagated to replicas
+ * is generated from here on so reset the log word count
+ */
+ Uint32 RlogSize= req_struct->log_size= 0;
if (((RtotalLen + 5) == RattrinbufLen) &&
(RattrinbufLen >= 5) &&
(RattrinbufLen < ZATTR_BUFFER_SIZE)) {
@@ -1951,7 +1955,12 @@ int Dbtup::interpreterStartLab(Signal* s
return -1;
}
}
- req_struct->log_size= RlogSize;
+ /* Add log words explicitly generated here to existing log size
+ * - readAttributes can generate log for ANYVALUE column
+ * It adds the words directly to req_struct->log_size
+ * This is used for ANYVALUE and interpreted delete.
+ */
+ req_struct->log_size+= RlogSize;
req_struct->read_length= RattroutCounter;
sendReadAttrinfo(signal, req_struct, RattroutCounter, regOperPtr);
if (RlogSize > 0) {
=== modified file 'storage/ndb/src/kernel/blocks/suma/Suma.cpp'
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp 2008-05-21 07:18:45 +0000
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp 2008-06-17 08:49:39 +0000
@@ -733,6 +733,7 @@ void Suma::execAPI_FAILREQ(Signal* signa
c_failedApiNodes.set(failedApiNode);
c_subscriber_nodes.clear(failedApiNode);
+ c_subscriber_per_node[failedApiNode] = 0;
check_start_handover(signal);
@@ -1470,6 +1471,16 @@ Suma::execSUB_CREATE_REQ(Signal* signal)
Subscription::REPORT_SUBSCRIBE : 0;
const Uint32 tableId = req.tableId;
+ bool subDropped = req.subscriptionType & SubCreateReq::NR_Sub_Dropped;
+
+ /**
+ * This 2 options are only allowed during NR
+ */
+ if (subDropped)
+ {
+ ndbrequire(refToNode(senderRef) == c_startup.m_restart_server_node_id);
+ }
+
Subscription key;
key.m_subscriptionId = subId;
key.m_subscriptionKey = subKey;
@@ -1551,6 +1562,12 @@ Suma::execSUB_CREATE_REQ(Signal* signal)
subOpPtr.p->m_senderRef = senderRef;
subOpPtr.p->m_senderData = senderData;
+ if (subDropped)
+ {
+ jam();
+ subPtr.p->m_options |= Subscription::MARKED_DROPPED;
+ }
+
TablePtr tabPtr;
if (found)
{
@@ -2343,11 +2360,6 @@ Suma::execSUB_START_REQ(Signal* signal){
case Subscription::UNDEFINED:
jam();
ndbrequire(false);
- case Subscription::DROPPED:
- jam();
- sendSubStartRef(signal,
- senderRef, senderData, SubStartRef::Dropped);
- return;
case Subscription::DEFINING:
jam();
sendSubStartRef(signal,
@@ -2357,6 +2369,23 @@ Suma::execSUB_START_REQ(Signal* signal){
break;
}
+ if (subPtr.p->m_options & Subscription::MARKED_DROPPED)
+ {
+ jam();
+ if (c_startup.m_restart_server_node_id == 0)
+ {
+ sendSubStartRef(signal,
+ senderRef, senderData, SubStartRef::Dropped);
+ return;
+ }
+ else
+ {
+ /**
+ * Allow SUB_START_REQ from peer node
+ */
+ }
+ }
+
if (subPtr.p->m_trigger_state == Subscription::T_ERROR)
{
jam();
@@ -2435,7 +2464,6 @@ Suma::execSUB_START_REQ(Signal* signal){
break;
case Subscription::T_DEFINED:{
jam();
-
report_sub_start_conf(signal, subPtr);
return;
}
@@ -2629,8 +2657,6 @@ Suma::report_sub_start_conf(Signal* sign
Uint32 senderData = subOpPtr.p->m_senderData;
c_subscriberPool.getPtr(ptr, subOpPtr.p->m_subscriberRef);
- Uint32 nodeId = refToNode(ptr.p->m_senderRef);
-
if (check_sub_start(ptr.p->m_senderRef))
{
SubStartConf* conf = (SubStartConf*)signal->getDataPtrSend();
@@ -2654,6 +2680,7 @@ Suma::report_sub_start_conf(Signal* sign
list.add(ptr);
c_subscriber_nodes.set(refToNode(ptr.p->m_senderRef));
+ c_subscriber_per_node[refToNode(ptr.p->m_senderRef)]++;
}
else
{
@@ -2715,27 +2742,40 @@ Suma::drop_triggers(Signal* signal, Subs
jam();
subPtr.p->m_outstanding_trigger = 0;
- for(Uint32 j = 0; j<3; j++)
+
+ Ptr<Table> tabPtr;
+ c_tablePool.getPtr(tabPtr, subPtr.p->m_table_ptrI);
+ if (tabPtr.p->m_state == Table::DROPPED)
{
- Uint32 triggerId = subPtr.p->m_triggers[j];
- if (triggerId != ILLEGAL_TRIGGER_ID)
+ jam();
+ subPtr.p->m_triggers[0] = ILLEGAL_TRIGGER_ID;
+ subPtr.p->m_triggers[1] = ILLEGAL_TRIGGER_ID;
+ subPtr.p->m_triggers[2] = ILLEGAL_TRIGGER_ID;
+ }
+ else
+ {
+ for(Uint32 j = 0; j<3; j++)
{
- jam();
- subPtr.p->m_outstanding_trigger++;
- DropTrigReq * const req = (DropTrigReq*)signal->getDataPtrSend();
- req->setConnectionPtr(subPtr.i);
- req->setUserRef(SUMA_REF);
- req->setRequestType(DropTrigReq::RT_USER);
- req->setTriggerType(TriggerType::SUBSCRIPTION_BEFORE);
- req->setTriggerActionTime(TriggerActionTime::TA_DETACHED);
- req->setIndexId(RNIL);
-
- req->setTableId(subPtr.p->m_tableId);
- req->setTriggerId(triggerId);
- req->setTriggerEvent((TriggerEvent::Value)j);
+ Uint32 triggerId = subPtr.p->m_triggers[j];
+ if (triggerId != ILLEGAL_TRIGGER_ID)
+ {
+ jam();
+ subPtr.p->m_outstanding_trigger++;
+ DropTrigReq * const req = (DropTrigReq*)signal->getDataPtrSend();
+ req->setConnectionPtr(subPtr.i);
+ req->setUserRef(SUMA_REF);
+ req->setRequestType(DropTrigReq::RT_USER);
+ req->setTriggerType(TriggerType::SUBSCRIPTION_BEFORE);
+ req->setTriggerActionTime(TriggerActionTime::TA_DETACHED);
+ req->setIndexId(RNIL);
+
+ req->setTableId(subPtr.p->m_tableId);
+ req->setTriggerId(triggerId);
+ req->setTriggerEvent((TriggerEvent::Value)j);
- sendSignal(DBTUP_REF, GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
+ sendSignal(DBTUP_REF, GSN_DROP_TRIG_REQ,
+ signal, DropTrigReq::SignalLength, JBB);
+ }
}
}
@@ -2905,9 +2945,6 @@ Suma::execSUB_STOP_REQ(Signal* signal){
sendSubStopRef(signal,
senderRef, senderData, SubStopRef::Defining);
return;
- case Subscription::DROPPED:
- jam();
- break;
case Subscription::DEFINED:
jam();
break;
@@ -3121,6 +3158,17 @@ Suma::report_sub_stop_conf(Signal* signa
conf->senderData= senderData;
sendSignal(senderRef, GSN_SUB_STOP_CONF, signal,
SubStopConf::SignalLength, JBB);
+
+ Uint32 nodeId = refToNode(ptr.p->m_senderRef);
+ if (c_subscriber_per_node[nodeId])
+ {
+ c_subscriber_per_node[nodeId]--;
+ if (c_subscriber_per_node[nodeId] == 0)
+ {
+ jam();
+ c_subscriber_nodes.clear(nodeId);
+ }
+ }
}
void
@@ -3760,7 +3808,7 @@ Suma::execSUB_GCP_COMPLETE_REP(Signal* s
if(m_gcp_complete_rep_count && !c_subscriber_nodes.isclear())
{
CRASH_INSERTION(13033);
-
+
NodeReceiverGroup rg(API_CLUSTERMGR, c_subscriber_nodes);
sendSignal(rg, GSN_SUB_GCP_COMPLETE_REP, signal,
SubGcpCompleteRep::SignalLength, JBB);
@@ -3783,12 +3831,13 @@ Suma::execSUB_GCP_COMPLETE_REP(Signal* s
/**
* Add GCP COMPLETE REP to buffer
*/
+ bool subscribers = !c_subscriber_nodes.isclear();
for(Uint32 i = 0; i<c_no_of_buckets; i++)
{
if(m_active_buckets.get(i))
continue;
- if (!c_subscriber_nodes.isclear())
+ if (subscribers || (c_buckets[i].m_state & Bucket::BUCKET_RESEND))
{
//Uint32* dst;
get_buffer_ptr(signal, i, gci, 0);
@@ -3834,6 +3883,14 @@ Suma::execDROP_TAB_CONF(Signal *signal)
tabPtr.p->m_state = Table::DROPPED;
c_tables.remove(tabPtr);
+ if (tabPtr.p->m_subscriptions.isEmpty())
+ {
+ jam();
+ tabPtr.p->release(* this);
+ c_tablePool.release(tabPtr);
+ return;
+ }
+
if (senderRef == 0)
{
jam();
@@ -3984,8 +4041,10 @@ Suma::execSUB_GCP_COMPLETE_ACK(Signal* s
return;
}
- if (refToBlock(senderRef) == SUMA) {
+ if (refToBlock(senderRef) == SUMA)
+ {
jam();
+
// Ack from other SUMA
Uint32 nodeId= refToNode(senderRef);
for(Uint32 i = 0; i<c_no_of_buckets; i++)
@@ -4099,18 +4158,20 @@ Suma::execSUB_REMOVE_REQ(Signal* signal)
case Subscription::DEFINING:
jam();
ndbrequire(false);
- case Subscription::DROPPED:
- /**
- * already dropped
- */
- jam();
- sendSubRemoveRef(signal, req, SubRemoveRef::AlreadyDropped);
- return;
case Subscription::DEFINED:
+ if (subPtr.p->m_options & Subscription::MARKED_DROPPED)
+ {
+ /**
+ * already dropped
+ */
+ jam();
+ sendSubRemoveRef(signal, req, SubRemoveRef::AlreadyDropped);
+ return;
+ }
break;
}
- subPtr.p->m_state = Subscription::DROPPED;
+ subPtr.p->m_options |= Subscription::MARKED_DROPPED;
check_release_subscription(signal, subPtr);
SubRemoveConf * const conf = (SubRemoveConf*)signal->getDataPtrSend();
@@ -4182,10 +4243,10 @@ do_release:
if (tabPtr.p->m_state == Table::DROPPED)
{
jam();
- subPtr.p->m_state = Subscription::DROPPED;
+ subPtr.p->m_options |= Subscription::MARKED_DROPPED;
}
- if (subPtr.p->m_state != Subscription::DROPPED)
+ if ((subPtr.p->m_options & Subscription::MARKED_DROPPED) == 0)
{
jam();
return;
@@ -4376,32 +4437,35 @@ Suma::sendSubCreateReq(Signal* signal, P
return;
}
- Ptr<Table> tabPtr;
- c_tablePool.getPtr(tabPtr, subPtr.p->m_table_ptrI);
+ c_restart.m_waiting_on_self = 0;
+ SubCreateReq * req = (SubCreateReq *)signal->getDataPtrSend();
+ req->senderRef = reference();
+ req->senderData = subPtr.i;
+ req->subscriptionId = subPtr.p->m_subscriptionId;
+ req->subscriptionKey = subPtr.p->m_subscriptionKey;
+ req->subscriptionType = subPtr.p->m_subscriptionType;
+ req->tableId = subPtr.p->m_tableId;
- if (subPtr.p->m_state != Subscription::DROPPED &&
- tabPtr.p->m_state != Table::DROPPED)
+ if (subPtr.p->m_options & Subscription::REPORT_ALL)
{
- jam();
- c_restart.m_waiting_on_self = 0;
- SubCreateReq * req = (SubCreateReq *)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = subPtr.i;
- req->subscriptionId = subPtr.p->m_subscriptionId;
- req->subscriptionKey = subPtr.p->m_subscriptionKey;
- req->subscriptionType = subPtr.p->m_subscriptionType;
- req->tableId = subPtr.p->m_tableId;
+ req->subscriptionType |= SubCreateReq::ReportAll;
+ }
- if (subPtr.p->m_options & Subscription::REPORT_ALL)
- {
- req->subscriptionType |= SubCreateReq::ReportAll;
- }
+ if (subPtr.p->m_options & Subscription::REPORT_SUBSCRIBE)
+ {
+ req->subscriptionType |= SubCreateReq::ReportSubscribe;
+ }
- if (subPtr.p->m_options & Subscription::REPORT_SUBSCRIBE)
- {
- req->subscriptionType |= SubCreateReq::ReportSubscribe;
- }
+ if (subPtr.p->m_options & Subscription::MARKED_DROPPED)
+ {
+ req->subscriptionType |= SubCreateReq::NR_Sub_Dropped;
+ ndbout_c("copying dropped sub: %u", subPtr.i);
+ }
+ Ptr<Table> tabPtr;
+ c_tablePool.getPtr(tabPtr, subPtr.p->m_table_ptrI);
+ if (tabPtr.p->m_state != Table::DROPPED)
+ {
if (!ndbd_suma_dictlock(getNodeInfo(refToNode(c_restart.m_ref)).m_version))
{
jam();
@@ -4414,16 +4478,17 @@ Suma::sendSubCreateReq(Signal* signal, P
* Thank you Ms. Fortuna
*/
}
-
+
sendSignal(c_restart.m_ref, GSN_SUB_CREATE_REQ, signal,
SubCreateReq::SignalLength, JBB);
}
else
{
- /**
- * No need to copy DROPPED subscription...
- * but this introduces a real time break
- */
+ jam();
+ ndbout_c("not copying sub %u with dropped table: %u/%u",
+ subPtr.i,
+ tabPtr.p->m_tableId, tabPtr.i);
+
c_restart.m_waiting_on_self = 1;
SubCreateConf * conf = (SubCreateConf *)signal->getDataPtrSend();
conf->senderRef = reference();
@@ -4476,16 +4541,23 @@ Suma::execSUB_CREATE_CONF(Signal* signal
abort_start_me(signal, subPtr, true);
return;
}
+
+ Ptr<Table> tabPtr;
+ c_tablePool.getPtr(tabPtr, subPtr.p->m_table_ptrI);
Ptr<Subscriber> ptr;
- if (subPtr.p->m_state != Subscription::DROPPED)
+ if (tabPtr.p->m_state != Table::DROPPED)
{
+ jam();
LocalDLList<Subscriber> list(c_subscriberPool, subPtr.p->m_subscribers);
list.first(ptr);
}
else
{
+ jam();
ptr.setNull();
+ ndbout_c("not copying subscribers on sub: %u with dropped table %u/%u",
+ subPtr.i, tabPtr.p->m_tableId, tabPtr.i);
}
copySubscriber(signal, subPtr, ptr);
@@ -4905,7 +4977,8 @@ Suma::release_gci(Signal* signal, Uint32
if(unlikely(bucket->m_state & mask))
{
jam();
- ndbout_c("release_gci(%d, %llu) -> node failure -> abort", buck, gci);
+ ndbout_c("release_gci(%d, %llu) 0x%x-> node failure -> abort",
+ buck, gci, bucket->m_state);
return;
}
@@ -5012,7 +5085,7 @@ Suma::start_resend(Signal* signal, Uint3
}
Uint64 min= bucket->m_max_acked_gci + 1;
- Uint64 max = pos.m_max_gci;
+ Uint64 max = m_max_seen_gci;
ndbrequire(max <= m_max_seen_gci);
@@ -5021,7 +5094,9 @@ Suma::start_resend(Signal* signal, Uint3
ndbrequire(pos.m_page_id == bucket->m_buffer_tail);
m_active_buckets.set(buck);
m_gcp_complete_rep_count ++;
- ndbout_c("empty bucket -> active");
+ ndbout_c("empty bucket (%u/%u %u/%u) -> active",
+ Uint32(min >> 32), Uint32(min),
+ Uint32(max >> 32), Uint32(max));
return;
}
=== modified file 'storage/ndb/src/kernel/blocks/suma/Suma.hpp'
--- a/storage/ndb/src/kernel/blocks/suma/Suma.hpp 2008-05-21 07:18:45 +0000
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.hpp 2008-06-17 08:49:39 +0000
@@ -228,13 +228,13 @@ public:
enum Options {
REPORT_ALL = 0x1,
- REPORT_SUBSCRIBE = 0x2
+ REPORT_SUBSCRIBE = 0x2,
+ MARKED_DROPPED = 0x4
};
enum State {
UNDEFINED,
DEFINED,
- DROPPED,
DEFINING
};
@@ -578,7 +578,8 @@ private:
STATIC_CONST( NO_OF_BUCKETS = 24 ); // 24 = 4*3*2*1!
Uint32 c_no_of_buckets;
struct Bucket c_buckets[NO_OF_BUCKETS];
-
+ Uint32 c_subscriber_per_node[MAX_NODES];
+
STATIC_CONST( BUCKET_MASK_SIZE = (((NO_OF_BUCKETS+31)>> 5)) );
typedef Bitmask<BUCKET_MASK_SIZE> Bucket_mask;
Bucket_mask m_active_buckets;
=== modified file 'storage/ndb/src/kernel/blocks/suma/SumaInit.cpp'
--- a/storage/ndb/src/kernel/blocks/suma/SumaInit.cpp 2008-02-20 09:04:29 +0000
+++ b/storage/ndb/src/kernel/blocks/suma/SumaInit.cpp 2008-06-17 08:49:39 +0000
@@ -124,6 +124,7 @@ Suma::Suma(Block_context& ctx) :
m_gcp_monitor = 0;
#endif
m_missing_data = false;
+ bzero(c_subscriber_per_node, sizeof(c_subscriber_per_node));
}
Suma::~Suma()
=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2008-04-22 19:36:05 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2008-07-29 09:39:57 +0000
@@ -908,12 +908,14 @@ int MgmtSrvr::sendStopMgmd(NodeId nodeId
if(ndb_mgm_connect(h,1,0,0))
{
DBUG_PRINT("info",("failed ndb_mgm_connect"));
+ ndb_mgm_destroy_handle(&h);
return SEND_OR_RECEIVE_FAILED;
}
if(!restart)
{
if(ndb_mgm_stop(h, 1, (const int*)&nodeId) < 0)
{
+ ndb_mgm_destroy_handle(&h);
return SEND_OR_RECEIVE_FAILED;
}
}
@@ -923,6 +925,7 @@ int MgmtSrvr::sendStopMgmd(NodeId nodeId
nodes[0]= (int)nodeId;
if(ndb_mgm_restart2(h, 1, nodes, initialStart, nostart, abort) < 0)
{
+ ndb_mgm_destroy_handle(&h);
return SEND_OR_RECEIVE_FAILED;
}
}
=== modified file 'storage/ndb/src/ndbapi/Ndb.cpp'
--- a/storage/ndb/src/ndbapi/Ndb.cpp 2008-08-08 09:40:47 +0000
+++ b/storage/ndb/src/ndbapi/Ndb.cpp 2008-08-12 18:56:42 +0000
@@ -1894,11 +1894,9 @@ Uint64 Ndb::getLatestGCI()
void Ndb::setReportThreshEventGCISlip(unsigned thresh)
{
- if (theEventBuffer->m_free_thresh != thresh)
+ if (theEventBuffer->m_gci_slip_thresh != thresh)
{
- theEventBuffer->m_free_thresh= thresh;
- theEventBuffer->m_min_free_thresh= thresh;
- theEventBuffer->m_max_free_thresh= 100;
+ theEventBuffer->m_gci_slip_thresh= thresh;
}
}
=== modified file 'storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp 2008-08-08 09:40:47 +0000
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp 2008-08-12 18:56:42 +0000
@@ -1046,10 +1046,10 @@ NdbEventBuffer::NdbEventBuffer(Ndb *ndb)
m_ndb(ndb),
m_latestGCI(0), m_latest_complete_GCI(0),
m_total_alloc(0),
- m_free_thresh(10),
- m_min_free_thresh(10),
- m_max_free_thresh(100),
- m_gci_slip_thresh(3),
+ m_free_thresh(0),
+ m_min_free_thresh(0),
+ m_max_free_thresh(0),
+ m_gci_slip_thresh(0),
m_dropped_ev_op(0),
m_active_op_count(0),
m_add_drop_mutex(0)
@@ -1957,14 +1957,14 @@ NdbEventBuffer::complete_outof_order_gci
Uint64 stop_gci = m_latest_complete_GCI;
Uint64 start_gci = array[minpos];
- g_eventLogger->info("complete_outof_order_gcis from: %u/%u to: %u/%u",
- Uint32(start_gci >> 32), Uint32(start_gci),
- Uint32(stop_gci >> 32), Uint32(stop_gci));
+ g_eventLogger->info("complete_outof_order_gcis from: %u/%u(%u) to: %u/%u(%u)",
+ Uint32(start_gci >> 32), Uint32(start_gci), minpos,
+ Uint32(stop_gci >> 32), Uint32(stop_gci), maxpos);
assert(start_gci <= stop_gci);
do
{
- Uint64 start_gci = array[minpos];
+ start_gci = array[minpos];
Gci_container* bucket = find_bucket(start_gci);
assert(bucket);
assert(maxpos == m_max_gci_index);
@@ -1978,10 +1978,10 @@ NdbEventBuffer::complete_outof_order_gci
#ifdef VM_TRACE
ndbout_c("complete_outof_order_gcis - completing %u/%u rows: %u",
- Uint32(start_gci), Uint32(start_gci), bucket->m_data.m_count);
+ Uint32(start_gci >> 32), Uint32(start_gci), bucket->m_data.m_count);
#else
ndbout_c("complete_outof_order_gcis - completing %u/%u",
- Uint32(start_gci), Uint32(start_gci));
+ Uint32(start_gci >> 32), Uint32(start_gci));
#endif
complete_bucket(bucket);
@@ -3277,28 +3277,32 @@ NdbEventBuffer::reportStatus()
else
apply_gci= latest_gci;
- if (100*(Uint64)m_free_data_sz < m_min_free_thresh*(Uint64)m_total_alloc &&
- m_total_alloc > 1024*1024)
+ if (m_free_thresh)
{
- /* report less free buffer than m_free_thresh,
- next report when more free than 2 * m_free_thresh
- */
- m_min_free_thresh= 0;
- m_max_free_thresh= 2 * m_free_thresh;
- goto send_report;
- }
+ if (100*(Uint64)m_free_data_sz < m_min_free_thresh*(Uint64)m_total_alloc &&
+ m_total_alloc > 1024*1024)
+ {
+ /* report less free buffer than m_free_thresh,
+ next report when more free than 2 * m_free_thresh
+ */
+ m_min_free_thresh= 0;
+ m_max_free_thresh= 2 * m_free_thresh;
+ goto send_report;
+ }
- if (100*(Uint64)m_free_data_sz > m_max_free_thresh*(Uint64)m_total_alloc &&
- m_total_alloc > 1024*1024)
- {
- /* report more free than 2 * m_free_thresh
- next report when less free than m_free_thresh
- */
- m_min_free_thresh= m_free_thresh;
- m_max_free_thresh= 100;
- goto send_report;
+ if (100*(Uint64)m_free_data_sz > m_max_free_thresh*(Uint64)m_total_alloc &&
+ m_total_alloc > 1024*1024)
+ {
+ /* report more free than 2 * m_free_thresh
+ next report when less free than m_free_thresh
+ */
+ m_min_free_thresh= m_free_thresh;
+ m_max_free_thresh= 100;
+ goto send_report;
+ }
}
- if (latest_gci-apply_gci >= m_gci_slip_thresh)
+ if (m_gci_slip_thresh &&
+ (latest_gci-apply_gci >= m_gci_slip_thresh))
{
goto send_report;
}
=== modified file 'storage/ndb/src/ndbapi/NdbOperationExec.cpp'
--- a/storage/ndb/src/ndbapi/NdbOperationExec.cpp 2008-06-03 10:00:31 +0000
+++ b/storage/ndb/src/ndbapi/NdbOperationExec.cpp 2008-08-04 15:49:01 +0000
@@ -795,6 +795,28 @@ NdbOperation::buildSignalsNdbRecord(Uint
}
}
+ if (m_use_any_value &&
+ (tOpType == DeleteRequest))
+ {
+ /* Special hack for delete and ANYVALUE pseudo-column
+ * We want to be able set the ANYVALUE pseudo-column as
+ * part of a delete, but deletes don't allow updates
+ * So we perform a 'read' of the column, passing a value.
+ * Code in TUP which handles this 'read' will set the
+ * value when the read is processed.
+ */
+ res= insertATTRINFOHdr_NdbRecord(aTC_ConnectPtr, aTransId,
+ AttributeHeader::ANY_VALUE, 4,
+ &attrInfoPtr, &remain);
+ if(res)
+ return res;
+ res= insertATTRINFOData_NdbRecord(aTC_ConnectPtr, aTransId,
+ (const char *)(&m_any_value), 4,
+ &attrInfoPtr, &remain);
+ if(res)
+ return res;
+ }
+
/* Interpreted program main signal words */
if (code)
{
@@ -977,10 +999,9 @@ NdbOperation::buildSignalsNdbRecord(Uint
if ((tOpType == InsertRequest) ||
(tOpType == WriteRequest) ||
- (tOpType == UpdateRequest) ||
- (tOpType == DeleteRequest))
+ (tOpType == UpdateRequest))
{
- /* Handle any setAnyValue(). */
+ /* Handle setAnyValue() for all cases except delete */
if (m_use_any_value)
{
res= insertATTRINFOHdr_NdbRecord(aTC_ConnectPtr, aTransId,
=== modified file 'storage/ndb/src/ndbapi/NdbScanFilter.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanFilter.cpp 2008-04-07 09:56:30 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanFilter.cpp 2008-08-06 15:33:19 +0000
@@ -75,7 +75,11 @@ public:
m_code= code;
m_associated_op= NULL;
- m_error.code = 0;
+ if (code == NULL)
+ /* NdbInterpretedCode not supported for operation type */
+ m_error.code = 4539;
+ else
+ m_error.code = 0;
};
/* This method propagates an error code from NdbInterpretedCode
@@ -136,13 +140,22 @@ NdbScanFilter::NdbScanFilter(class NdbOp
{
DBUG_ENTER("NdbScanFilter::NdbScanFilter(NdbOperation)");
- /* We ask the NdbScanOperation to allocate an InterpretedCode
- * object for us. It will look after freeing it when
- * necessary. This allows the InterpretedCode object to
- * survive after the NdbScanFilter has gone out of scope
+ NdbInterpretedCode* code= NULL;
+ NdbOperation::Type opType= op->getType();
+
+ /* If the operation is not of the correct type then
+ * m_impl.init() will set an error on the scan filter
*/
- NdbInterpretedCode* code=
- ((NdbScanOperation *)op)->allocInterpretedCodeOldApi();
+ if (likely((opType == NdbOperation::TableScan) ||
+ (opType == NdbOperation::OrderedIndexScan)))
+ {
+ /* We ask the NdbScanOperation to allocate an InterpretedCode
+ * object for us. It will look after freeing it when
+ * necessary. This allows the InterpretedCode object to
+ * survive after the NdbScanFilter has gone out of scope
+ */
+ code= ((NdbScanOperation *)op)->allocInterpretedCodeOldApi();
+ }
m_impl.init(code);
@@ -158,6 +171,8 @@ NdbScanFilter::~NdbScanFilter()
int
NdbScanFilter::begin(Group group){
+ if (m_impl.m_error.code != 0) return -1;
+
if (m_impl.m_stack2.push_back(m_impl.m_negative))
{
/* Memory allocation problem */
@@ -244,6 +259,8 @@ NdbScanFilter::begin(Group group){
int
NdbScanFilter::end(){
+ if (m_impl.m_error.code != 0) return -1;
+
if(m_impl.m_stack2.size() == 0){
/* Invalid set of range scan bounds */
m_impl.m_error.code= 4259;
@@ -353,6 +370,8 @@ NdbScanFilter::end(){
int
NdbScanFilter::istrue(){
+ if(m_impl.m_error.code != 0) return -1;
+
if(m_impl.m_current.m_group < NdbScanFilter::AND ||
m_impl.m_current.m_group > NdbScanFilter::NOR){
/* Operator is not defined in NdbScanFilter::Group */
@@ -373,6 +392,7 @@ NdbScanFilter::istrue(){
int
NdbScanFilter::isfalse(){
+ if (m_impl.m_error.code != 0) return -1;
if(m_impl.m_current.m_group < NdbScanFilter::AND ||
m_impl.m_current.m_group > NdbScanFilter::NOR){
/* Operator is not defined in NdbScanFilter::Group */
@@ -436,6 +456,8 @@ const int tab2_sz = sizeof(table2)/sizeo
int
NdbScanFilterImpl::cond_col(Interpreter::UnaryCondition op, Uint32 AttrId){
+ if (m_error.code != 0) return -1;
+
if(op < 0 || op >= tab2_sz){
/* Condition is out of bounds */
m_error.code= 4262;
@@ -458,6 +480,8 @@ NdbScanFilterImpl::cond_col(Interpreter:
int
NdbScanFilter::isnull(int AttrId){
+ if (m_impl.m_error.code != 0) return -1;
+
if(m_impl.m_negative == 1)
return m_impl.cond_col(Interpreter::IS_NOT_NULL, AttrId);
else
@@ -466,6 +490,8 @@ NdbScanFilter::isnull(int AttrId){
int
NdbScanFilter::isnotnull(int AttrId){
+ if (m_impl.m_error.code != 0) return -1;
+
if(m_impl.m_negative == 1)
return m_impl.cond_col(Interpreter::IS_NULL, AttrId);
else
@@ -568,6 +594,8 @@ int
NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op,
Uint32 AttrId,
const void * value, Uint32 len){
+ if (m_error.code != 0) return -1;
+
if(op < 0 || op >= tab3_sz){
/* Condition is out of bounds */
m_error.code= 4262;
=== modified file 'storage/ndb/src/ndbapi/NdbScanOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2008-08-08 09:40:47 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2008-08-12 18:56:42 +0000
@@ -53,7 +53,7 @@ NdbScanOperation::NdbScanOperation(Ndb*
theSCAN_TABREQ = 0;
m_executed = false;
m_scan_buffer= NULL;
- m_scanUsingOldApi= false;
+ m_scanUsingOldApi= true;
m_interpretedCodeOldApi= NULL;
}
@@ -119,7 +119,7 @@ NdbScanOperation::init(const NdbTableImp
m_descending= false;
m_read_range_no = 0;
m_executed = false;
- m_scanUsingOldApi= false;
+ m_scanUsingOldApi= true;
m_interpretedCodeOldApi= NULL;
m_api_receivers_count = 0;
@@ -951,16 +951,14 @@ NdbScanOperation::readTuples(NdbScanOper
Uint32 parallel,
Uint32 batch)
{
- // It is only possible to call readTuples if
- // 1. the scan transaction doesn't already contain another scan operation
- // 2. We have not already defined an old Api scan operation.
- if (theNdbCon->theScanningOp != NULL ||
- m_scanUsingOldApi ){
+ // It is only possible to call readTuples if the scan transaction
+ // doesn't already contain a scan operation
+ if (theNdbCon->theScanningOp != NULL)
+ {
setErrorCode(4605);
return -1;
}
-
- m_scanUsingOldApi= true;
+
/* Save parameters for later */
m_savedLockModeOldApi= lm;
m_savedScanFlagsOldApi= scan_flags;
=== modified file 'storage/ndb/src/ndbapi/NdbTransaction.cpp'
--- a/storage/ndb/src/ndbapi/NdbTransaction.cpp 2008-08-08 09:40:47 +0000
+++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp 2008-08-12 18:56:42 +0000
@@ -1926,28 +1926,24 @@ from other transactions.
tGCI_lo = 0;
}
Uint64 tGCI = Uint64(tGCI_lo) | (Uint64(tGCI_hi) << 32);
- if (tCommitFlag == 1) {
+ if (tCommitFlag == 1)
+ {
theCommitStatus = Committed;
theGlobalCheckpointId = tGCI;
if (tGCI) // Read(dirty) only transaction doesnt get GCI
{
*p_latest_trans_gci = tGCI;
}
- } else if ((tNoComp >= tNoSent) &&
- (theLastExecOpInList->theCommitIndicator == 1)){
-
-
-/**********************************************************************/
-// We sent the transaction with Commit flag set and received a CONF with
-// no Commit flag set. This is clearly an anomaly.
-/**********************************************************************/
- theError.code = 4011;
- theCompletionStatus = CompletedFailure;
- theReturnStatus = NdbTransaction::ReturnFailure;
- theCommitStatus = Aborted;
- return 0;
+ }
+ else if (theLastExecOpInList->theCommitIndicator == 1)
+ {
+ /**
+ * We're waiting for a commit reply...
+ */
+ return -1;
}//if
- if (tNoComp >= tNoSent) {
+ if (tNoComp >= tNoSent)
+ {
return 0; // No more operations to wait for
}//if
// Not completed the reception yet.
@@ -2107,27 +2103,25 @@ NdbTransaction::receiveTCINDXCONF(const
Uint64 tGCI = Uint64(tGCI_lo) | (Uint64(tGCI_hi) << 32);
theNoOfOpCompleted = tNoComp;
- if (tCommitFlag == 1) {
+ if (tCommitFlag == 1)
+ {
theCommitStatus = Committed;
theGlobalCheckpointId = tGCI;
if (tGCI) // Read(dirty) only transaction doesnt get GCI
{
*p_latest_trans_gci = tGCI;
}
- } else if ((tNoComp >= tNoSent) &&
- (theLastExecOpInList->theCommitIndicator == 1)){
-
- /**********************************************************************/
- // We sent the transaction with Commit flag set and received a CONF with
- // no Commit flag set. This is clearly an anomaly.
- /**********************************************************************/
- theError.code = 4011;
- theCompletionStatus = NdbTransaction::CompletedFailure;
- theCommitStatus = NdbTransaction::Aborted;
- theReturnStatus = NdbTransaction::ReturnFailure;
- return 0;
+ }
+ else if (theLastExecOpInList->theCommitIndicator == 1)
+ {
+ /**
+ * We're waiting for a commit reply...
+ */
+ return -1;
}//if
- if (tNoComp >= tNoSent) {
+
+ if (tNoComp >= tNoSent)
+ {
return 0; // No more operations to wait for
}//if
// Not completed the reception yet.
@@ -2589,6 +2583,8 @@ NdbTransaction::scanTable(const NdbRecor
DBUG_RETURN(NULL);
}
+ op_idx->m_scanUsingOldApi= false;
+
/* The real work is done in NdbScanOperation */
if (op_idx->scanTableImpl(result_record,
lock_mode,
@@ -2628,6 +2624,8 @@ NdbTransaction::scanIndex(const NdbRecor
return NULL;
}
+ op->m_scanUsingOldApi= false;
+
/* Defer the rest of the work to NdbIndexScanOperation */
if (op->scanIndexImpl(key_record,
result_record,
=== modified file 'storage/ndb/test/ndbapi/testInterpreter.cpp'
--- a/storage/ndb/test/ndbapi/testInterpreter.cpp 2008-05-23 09:07:58 +0000
+++ b/storage/ndb/test/ndbapi/testInterpreter.cpp 2008-06-18 14:55:21 +0000
@@ -206,8 +206,9 @@ int runTestBug19537(NDBT_Context* ctx, N
// Load 64-bit constant into register 1 and
// write from register 1 to 32-bit column KOL2
const Uint64 reg_val = 0x0102030405060708ULL;
-
- const Uint32* reg_ptr32 = (const Uint32*)®_val;
+ Uint32 reg_ptr32[2];
+ memcpy(reg_ptr32+0, (Uint8*)®_val, sizeof(Uint32));
+ memcpy(reg_ptr32+1, ((Uint8*)®_val)+4, sizeof(Uint32));
if (reg_ptr32[0] == 0x05060708 && reg_ptr32[1] == 0x01020304) {
g_err << "runTestBug19537: platform is LITTLE endian" << endl;
} else if (reg_ptr32[0] == 0x01020304 && reg_ptr32[1] == 0x05060708) {
=== modified file 'storage/ndb/test/ndbapi/testNdbApi.cpp'
--- a/storage/ndb/test/ndbapi/testNdbApi.cpp 2007-07-02 17:08:02 +0000
+++ b/storage/ndb/test/ndbapi/testNdbApi.cpp 2008-06-03 12:37:17 +0000
@@ -1674,6 +1674,60 @@ done:
return result;
}
+int
+runBug37158(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result = NDBT_OK;
+ Ndb* pNdb = GETNDB(step);
+
+ for (Uint32 i = 0; i<ctx->getNumLoops(); i++)
+ {
+ HugoOperations hugoOps(*ctx->getTab());
+ hugoOps.startTransaction(pNdb);
+ if (hugoOps.pkWriteRecord(pNdb, 0) != 0)
+ {
+ result = NDBT_FAILED;
+ goto done;
+ }
+
+
+ if (hugoOps.pkWritePartialRecord(pNdb, 1) != 0)
+ {
+ result = NDBT_FAILED;
+ goto done;
+ }
+
+ if (hugoOps.pkWriteRecord(pNdb, 2) != 0)
+ {
+ result = NDBT_FAILED;
+ goto done;
+ }
+
+ if (hugoOps.pkUpdateRecord(pNdb, 0) != 0)
+ {
+ result = NDBT_FAILED;
+ goto done;
+ }
+
+ if (hugoOps.execute_Commit(pNdb, AO_IgnoreError) == 4011)
+ {
+ result = NDBT_FAILED;
+ goto done;
+ }
+ hugoOps.closeTransaction(pNdb);
+
+ if (runClearTable(ctx, step) != 0)
+ {
+ result = NDBT_FAILED;
+ goto done;
+ }
+ }
+
+done:
+
+ return result;
+}
+
NDBT_TESTSUITE(testNdbApi);
TESTCASE("MaxNdb",
"Create Ndb objects until no more can be created\n"){
@@ -1782,6 +1836,10 @@ TESTCASE("Bug28443",
""){
INITIALIZER(runBug28443);
}
+TESTCASE("Bug37158",
+ ""){
+ INITIALIZER(runBug37158);
+}
NDBT_TESTSUITE_END(testNdbApi);
int main(int argc, const char** argv){
=== modified file 'storage/ndb/test/ndbapi/testOIBasic.cpp'
--- a/storage/ndb/test/ndbapi/testOIBasic.cpp 2008-08-08 09:40:47 +0000
+++ b/storage/ndb/test/ndbapi/testOIBasic.cpp 2008-08-12 18:56:42 +0000
@@ -616,6 +616,10 @@ getcs(Par par)
uint n = urandom(maxcsnumber);
cs = get_charset(n, MYF(0));
if (cs != 0) {
+ // avoid dodgy internal character sets
+ // see bug# 37554
+ if (cs->state & MY_CS_HIDDEN)
+ continue;
// prefer complex charsets
if (cs->mbmaxlen != 1 || urandom(5) == 0)
break;
=== modified file 'storage/ndb/test/ndbapi/testScanFilter.cpp'
--- a/storage/ndb/test/ndbapi/testScanFilter.cpp 2008-02-19 15:00:29 +0000
+++ b/storage/ndb/test/ndbapi/testScanFilter.cpp 2008-08-06 15:33:19 +0000
@@ -894,6 +894,132 @@ int runMaxScanFilterSize(NDBT_Context* c
return NDBT_OK;
}
+
+int runScanFilterConstructorFail(NDBT_Context* ctx, NDBT_Step* step)
+{
+ /* We test that failures in the ScanFilter constructor can be
+ * detected by the various ScanFilter methods without
+ * issues
+ */
+ Ndb *myNdb = GETNDB(step);
+ const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
+ const NdbDictionary::Table *myTable= myDict->getTable(TABLE_NAME);
+ if(myTable == NULL)
+ APIERROR(myDict->getNdbError());
+
+ NdbTransaction* trans=myNdb->startTransaction();
+
+ if (trans == NULL)
+ {
+ APIERROR(trans->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ /* Create an NdbRecord scan operation */
+ const NdbScanOperation* tabScan=
+ trans->scanTable(myTable->getDefaultRecord());
+
+ if (tabScan==NULL)
+ {
+ APIERROR(trans->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ /* Now we hackily try to add a ScanFilter after the operation
+ * is defined. This will cause a failure within the
+ * constructor
+ */
+ NdbScanFilter brokenSf((NdbScanOperation*) tabScan);
+
+ /* Scan operation should have an error */
+ if (tabScan->getNdbError().code != 4536)
+ {
+ ndbout << "Expected error 4536, had error " <<
+ tabScan->getNdbError().code << " instead" << endl;
+ return NDBT_FAILED;
+ }
+
+ /* ScanFilter should have an error */
+ if (brokenSf.getNdbError().code != 4539)
+ {
+ ndbout << "Expected error 4539, had error " <<
+ brokenSf.getNdbError().code << " instead" << endl;
+ return NDBT_FAILED;
+ }
+
+ if (brokenSf.begin() != -1)
+ { ndbout << "Bad rc from begin" << endl; return NDBT_FAILED; }
+
+ if (brokenSf.istrue() != -1)
+ { ndbout << "Bad rc from istrue" << endl; return NDBT_FAILED; }
+
+ if (brokenSf.isfalse() != -1)
+ { ndbout << "Bad rc from isfalse" << endl; return NDBT_FAILED; }
+
+ if (brokenSf.isnull(0) != -1)
+ { ndbout << "Bad rc from isnull" << endl; return NDBT_FAILED; }
+
+ if (brokenSf.isnotnull(0) != -1)
+ { ndbout << "Bad rc from isnotnull" << endl; return NDBT_FAILED; }
+
+ if (brokenSf.cmp(NdbScanFilter::COND_EQ, 0, NULL, 0) != -1)
+ { ndbout << "Bad rc from cmp" << endl; return NDBT_FAILED; }
+
+ if (brokenSf.end() != -1)
+ { ndbout << "Bad rc from begin" << endl; return NDBT_FAILED; }
+
+ trans->close();
+
+ /* Now we check that we can define a ScanFilter before
+ * calling readTuples() for a scan operation
+ */
+ trans= myNdb->startTransaction();
+
+ if (trans == NULL)
+ {
+ APIERROR(trans->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ /* Get an old Api table scan operation */
+ NdbScanOperation* tabScanOp=
+ trans->getNdbScanOperation(myTable);
+
+ if (tabScanOp==NULL)
+ {
+ APIERROR(trans->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ /* Attempt to define a ScanFilter before calling readTuples() */
+ NdbScanFilter sf(tabScanOp);
+
+ /* Should be no problem ... */
+ if (sf.getNdbError().code != 0)
+ { APIERROR(sf.getNdbError()); return NDBT_FAILED; };
+
+
+ /* Ok, now attempt to define a ScanFilter against a primary key op */
+ NdbOperation* pkOp= trans->getNdbOperation(myTable);
+
+ if (pkOp == NULL)
+ {
+ APIERROR(trans->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ NdbScanFilter sf2(pkOp);
+
+ if (sf2.getNdbError().code != 4539)
+ {
+ ndbout << "Error, expected 4539" << endl;
+ APIERROR(sf2.getNdbError());
+ return NDBT_FAILED;
+ }
+
+ return NDBT_OK;
+}
+
NDBT_TESTSUITE(testScanFilter);
TESTCASE(TEST_NAME,
"Scan table TABLE_NAME for the records which accord with \
@@ -903,6 +1029,7 @@ TESTCASE(TEST_NAME,
INITIALIZER(runPopulate);
INITIALIZER(runScanRandomFilterTest);
INITIALIZER(runMaxScanFilterSize);
+ INITIALIZER(runScanFilterConstructorFail);
FINALIZER(runDropTables);
}
=== modified file 'storage/ndb/test/ndbapi/testSystemRestart.cpp'
--- a/storage/ndb/test/ndbapi/testSystemRestart.cpp 2008-03-25 15:46:12 +0000
+++ b/storage/ndb/test/ndbapi/testSystemRestart.cpp 2008-06-18 14:50:56 +0000
@@ -1276,7 +1276,7 @@ runBug29167(NDBT_Context* ctx, NDBT_Step
Ndb* pNdb = GETNDB(step);
const Uint32 nodeCount = restarter.getNumDbNodes();
- if (nodeCount < 2)
+ if (nodeCount < 4)
return NDBT_OK;
int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_CHECKPOINT, 0 };
=== modified file 'storage/ndb/test/ndbapi/test_event.cpp'
--- a/storage/ndb/test/ndbapi/test_event.cpp 2008-04-25 09:17:15 +0000
+++ b/storage/ndb/test/ndbapi/test_event.cpp 2008-08-04 15:49:01 +0000
@@ -25,14 +25,13 @@
#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
-static int createEvent(Ndb *pNdb,
+static int createEvent(Ndb *pNdb,
const NdbDictionary::Table &tab,
- NDBT_Context* ctx)
+ bool merge_events,
+ bool report)
{
char eventName[1024];
sprintf(eventName,"%s_EVENT",tab.getName());
- bool merge_events = ctx->getProperty("MergeEvents");
- bool report = ctx->getProperty("ReportSubscribe");
NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
@@ -89,6 +88,16 @@ static int createEvent(Ndb *pNdb,
return NDBT_OK;
}
+static int createEvent(Ndb *pNdb,
+ const NdbDictionary::Table &tab,
+ NDBT_Context* ctx)
+{
+ bool merge_events = ctx->getProperty("MergeEvents");
+ bool report = ctx->getProperty("ReportSubscribe");
+
+ return createEvent(pNdb, tab, merge_events, report);
+}
+
static int dropEvent(Ndb *pNdb, const NdbDictionary::Table &tab)
{
char eventName[1024];
@@ -1806,7 +1815,6 @@ runBug31701(NDBT_Context* ctx, NDBT_Step
int records = ctx->getNumRecords();
HugoTransactions hugoTrans(*ctx->getTab());
- if(ctx->getPropertyWait("LastGCI", ~(Uint32)0))
if(ctx->getPropertyWait("LastGCI_hi", ~(Uint32)0))
{
g_err << "FAIL " << __LINE__ << endl;
@@ -2515,6 +2523,522 @@ err:
/** Telco 6.3 **/
+int
+runBug37279(NDBT_Context* ctx, NDBT_Step* step)
+{
+ NdbRestarter res;
+ if (res.getNumDbNodes() < 2)
+ {
+ ctx->stopTest();
+ return NDBT_OK;
+ }
+
+ if (runCreateEvent(ctx, step))
+ {
+ return NDBT_FAILED;
+ }
+
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* dict = pNdb->getDictionary();
+
+ const NdbDictionary::Table* tab = dict->getTable(ctx->getTab()->getName());
+ const NdbDictionary::Table* org = tab;
+ NdbEventOperation* pOp0 = createEventOperation(pNdb, *tab);
+
+ if (pOp0 == 0)
+ {
+ return NDBT_FAILED;
+ }
+
+ {
+ Ndb* ndb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
+ if (ndb->init() != 0)
+ {
+ delete ndb;
+ ndbout_c("here: %u", __LINE__);
+ return NDBT_FAILED;
+ }
+
+ if (ndb->waitUntilReady(30) != 0)
+ {
+ delete ndb;
+ ndbout_c("here: %u", __LINE__);
+ return NDBT_FAILED;
+ }
+
+ ndb->getDictionary()->dropTable(tab->getName());
+ delete ndb;
+ }
+
+ int nodeId = res.getDbNodeId(rand() % res.getNumDbNodes());
+ ndbout_c("stopping %u", nodeId);
+ res.restartOneDbNode(nodeId,
+ /** initial */ false,
+ /** nostart */ false,
+ /** abort */ true);
+ if (res.waitClusterStarted())
+ {
+ return NDBT_FAILED;
+ }
+
+ pNdb->dropEventOperation(pOp0);
+ runDropEvent(ctx, step);
+
+ return NDBT_OK;
+}
+
+int
+runBug37338(NDBT_Context* ctx, NDBT_Step* step)
+{
+ NdbRestarter res;
+ if (res.getNumDbNodes() < 2)
+ {
+ ctx->stopTest();
+ return NDBT_OK;
+ }
+
+ int nodeId = res.getDbNodeId(rand() % res.getNumDbNodes());
+
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* dict = pNdb->getDictionary();
+ const NdbDictionary::Table* tab = dict->getTable(ctx->getTab()->getName());
+
+ const char * name = "BugXXX";
+ NdbDictionary::Table copy = * tab;
+ copy.setName(name);
+ dict->dropTable(name);
+
+ for (int i = 0; i<ctx->getNumLoops(); i++)
+ {
+ Ndb* ndb0;
+ Ndb_cluster_connection *con0;
+ NdbEventOperation* pOp0;
+ NdbDictionary::Dictionary * dict0;
+
+ cc(&con0, &ndb0);
+ dict0 = ndb0->getDictionary();
+ if (dict0->createTable(copy) != 0)
+ {
+ ndbout << dict0->getNdbError() << endl;
+ return NDBT_FAILED;
+ }
+
+ const NdbDictionary::Table * copyptr = dict0->getTable(name);
+ if (copyptr == 0)
+ {
+ return NDBT_FAILED;
+ }
+ createEvent(ndb0, *copyptr, ctx);
+ pOp0 = createEventOperation(ndb0, *copyptr);
+ dict0 = ndb0->getDictionary();dict->dropTable(name);
+
+ res.restartOneDbNode(nodeId,
+ /** initial */ false,
+ /** nostart */ true,
+ /** abort */ true);
+
+ res.waitNodesNoStart(&nodeId, 1);
+ res.startNodes(&nodeId, 1);
+ if (res.waitClusterStarted())
+ {
+ return NDBT_FAILED;
+ }
+
+ ndb0->dropEventOperation(pOp0);
+
+ delete ndb0;
+ delete con0;
+ }
+
+ return NDBT_OK;
+}
+
+int
+runBug37442(NDBT_Context* ctx, NDBT_Step* step)
+{
+ NdbRestarter res;
+ if (res.getNumDbNodes() < 2)
+ {
+ ctx->stopTest();
+ return NDBT_OK;
+ }
+
+ int nodeId = res.getDbNodeId(rand() % res.getNumDbNodes());
+
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary* dict = pNdb->getDictionary();
+ const NdbDictionary::Table* tab = dict->getTable(ctx->getTab()->getName());
+
+ if (runCreateEvent(ctx, step))
+ {
+ return NDBT_FAILED;
+ }
+
+ for (int i = 0; i<ctx->getNumLoops(); i++)
+ {
+ NdbEventOperation * pOp = createEventOperation(GETNDB(step), *tab);
+
+ res.restartOneDbNode(nodeId,
+ /** initial */ false,
+ /** nostart */ true,
+ /** abort */ true);
+
+ res.waitNodesNoStart(&nodeId, 1);
+
+ GETNDB(step)->dropEventOperation(pOp);
+
+ res.startNodes(&nodeId, 1);
+ if (res.waitClusterStarted())
+ {
+ return NDBT_FAILED;
+ }
+ }
+
+ runDropEvent(ctx, step);
+
+ return NDBT_OK;
+}
+
+const NdbDictionary::Table* createBoringTable(const char* name, Ndb* pNdb)
+{
+ NdbDictionary::Table tab;
+
+ tab.setName(name);
+
+ NdbDictionary::Column pk;
+ pk.setName("Key");
+ pk.setType(NdbDictionary::Column::Unsigned);
+ pk.setLength(1);
+ pk.setNullable(false);
+ pk.setPrimaryKey(true);
+ tab.addColumn(pk);
+
+ NdbDictionary::Column attr;
+ attr.setName("Attr");
+ attr.setType(NdbDictionary::Column::Unsigned);
+ attr.setLength(1);
+ attr.setNullable(true);
+ attr.setPrimaryKey(false);
+ tab.addColumn(attr);
+
+ pNdb->getDictionary()->dropTable(tab.getName());
+ if(pNdb->getDictionary()->createTable(tab) == 0)
+ {
+ ndbout << (NDBT_Table&)tab << endl;
+ return pNdb->getDictionary()->getTable(tab.getName());
+ }
+
+ ndbout << "Table create failed, err : " <<
+ pNdb->getDictionary()->getNdbError().code << endl;
+
+ return NULL;
+}
+
+/* Types of operation which can be tagged via 'setAnyValue */
+enum OpTypes {Insert, Update, Write, Delete, EndOfOpTypes};
+
+/**
+ * executeOps
+ * Generate a number of PK operations of the supplied type
+ * using the passed operation options and setting the
+ * anyValue tag
+ */
+int
+executeOps(Ndb* pNdb,
+ const NdbDictionary::Table* tab,
+ OpTypes op,
+ Uint32 rowCount,
+ Uint32 keyOffset,
+ Uint32 anyValueOffset,
+ NdbOperation::OperationOptions opts)
+{
+ NdbTransaction* trans= pNdb->startTransaction();
+ const NdbRecord* record= tab->getDefaultRecord();
+
+ char RowBuf[16];
+ Uint32* keyPtr= (Uint32*) NdbDictionary::getValuePtr(record,
+ RowBuf,
+ 0);
+ Uint32* attrPtr= (Uint32*) NdbDictionary::getValuePtr(record,
+ RowBuf,
+ 1);
+
+ for (Uint32 i=keyOffset; i < (keyOffset + rowCount); i++)
+ {
+ *keyPtr= *attrPtr= i;
+ opts.optionsPresent |= NdbOperation::OperationOptions::OO_ANYVALUE;
+ opts.anyValue= anyValueOffset + i;
+ bool allowInterpreted=
+ (op == Update) ||
+ (op == Delete);
+
+ if (!allowInterpreted)
+ opts.optionsPresent &=
+ ~ (Uint64) NdbOperation::OperationOptions::OO_INTERPRETED;
+
+ switch (op) {
+ case Insert :
+ if (trans->insertTuple(record,
+ RowBuf,
+ NULL,
+ &opts,
+ sizeof(opts)) == NULL)
+ {
+ g_err << "Can't create operation : " <<
+ trans->getNdbError().code << endl;
+ return NDBT_FAILED;
+ }
+ break;
+ case Update :
+ if (trans->updateTuple(record,
+ RowBuf,
+ record,
+ RowBuf,
+ NULL,
+ &opts,
+ sizeof(opts)) == NULL)
+ {
+ g_err << "Can't create operation : " <<
+ trans->getNdbError().code << endl;
+ return NDBT_FAILED;
+ }
+ break;
+ case Write :
+ if (trans->writeTuple(record,
+ RowBuf,
+ record,
+ RowBuf,
+ NULL,
+ &opts,
+ sizeof(opts)) == NULL)
+ {
+ g_err << "Can't create operation : " <<
+ trans->getNdbError().code << endl;
+ return NDBT_FAILED;
+ }
+ break;
+ case Delete :
+ if (trans->deleteTuple(record,
+ RowBuf,
+ record,
+ NULL,
+ NULL,
+ &opts,
+ sizeof(opts)) == NULL)
+ {
+ g_err << "Can't create operation : " <<
+ trans->getNdbError().code << endl;
+ return NDBT_FAILED;
+ }
+ break;
+ default:
+ g_err << "Bad operation type : " << op << endl;
+ return NDBT_FAILED;
+ }
+ }
+
+ trans->execute(Commit);
+
+ if (trans->getNdbError().code != 0)
+ {
+ g_err << "Error executing operations :" <<
+ trans->getNdbError().code << endl;
+ return NDBT_FAILED;
+ }
+
+ trans->close();
+
+ return NDBT_OK;
+}
+
+int
+checkAnyValueInEvent(Ndb* pNdb,
+ NdbRecAttr* preKey,
+ NdbRecAttr* postKey,
+ NdbRecAttr* preAttr,
+ NdbRecAttr* postAttr,
+ Uint32 num,
+ Uint32 anyValueOffset,
+ bool checkPre)
+{
+ Uint32 received= 0;
+
+ while (received < num)
+ {
+ int pollRc;
+
+ if ((pollRc= pNdb->pollEvents(10000)) < 0)
+ {
+ g_err << "Error while polling for events : " <<
+ pNdb->getNdbError().code;
+ return NDBT_FAILED;
+ }
+
+ if (pollRc == 0)
+ {
+ printf("No event, waiting...\n");
+ continue;
+ }
+
+ NdbEventOperation* event;
+ while((event= pNdb->nextEvent()) != NULL)
+ {
+// printf("Event is %p of type %u\n",
+// event, event->getEventType());
+// printf("Got event, prekey is %u predata is %u \n",
+// preKey->u_32_value(),
+// preAttr->u_32_value());
+// printf(" postkey is %u postdata is %u anyvalue is %u\n",
+// postKey->u_32_value(),
+// postAttr->u_32_value(),
+// event->getAnyValue());
+
+ received ++;
+ Uint32 keyVal= (checkPre?
+ preKey->u_32_value() :
+ postKey->u_32_value());
+
+ if (event->getAnyValue() !=
+ (anyValueOffset + keyVal))
+ {
+ g_err << "Error : Got event, key is " <<
+ keyVal << " anyValue is " <<
+ event->getAnyValue() <<
+ " expected " << (anyValueOffset + keyVal)
+ << endl;
+ return NDBT_FAILED;
+ }
+ }
+ }
+
+ return NDBT_OK;
+}
+
+
+
+int
+runBug37672(NDBT_Context* ctx, NDBT_Step* step)
+{
+ /* InterpretedDelete and setAnyValue failed */
+ /* Let's create a boring, known table for this since
+ * we don't yet have Hugo tools for NdbRecord
+ */
+ BaseString name;
+ name.assfmt("TAB_TESTEVENT%d", rand() & 65535);
+ Ndb* pNdb= GETNDB(step);
+
+ const NdbDictionary::Table* tab= createBoringTable(name.c_str(), pNdb);
+
+ if (tab == NULL)
+ return NDBT_FAILED;
+
+ /* Create an event to listen to events on the table */
+ char eventName[1024];
+ sprintf(eventName,"%s_EVENT", tab->getName());
+
+ if (createEvent(pNdb, *tab, false, true) != 0)
+ return NDBT_FAILED;
+
+ /* Now create the event operation to retrieve the events */
+ NdbEventOperation* eventOp;
+ eventOp= pNdb->createEventOperation(eventName);
+
+ if (eventOp == NULL)
+ {
+ g_err << "Failed to create event operation :" <<
+ pNdb->getNdbError().code << endl;
+ return NDBT_FAILED;
+ }
+
+ NdbRecAttr* eventKeyData= eventOp->getValue("Key");
+ NdbRecAttr* eventOldKeyData= eventOp->getPreValue("Key");
+ NdbRecAttr* eventAttrData= eventOp->getValue("Attr");
+ NdbRecAttr* eventOldAttrData= eventOp->getPreValue("Attr");
+
+ if ((eventKeyData == NULL) || (eventAttrData == NULL))
+ {
+ g_err << "Failed to get NdbRecAttrs for events" << endl;
+ return NDBT_FAILED;
+ };
+
+ if (eventOp->execute() != 0)
+ {
+ g_err << "Failed to execute event operation :" <<
+ eventOp->getNdbError().code << endl;
+ return NDBT_FAILED;
+ }
+
+ /* Perform some operations on the table, and check
+ * that we get the correct AnyValues propagated
+ * through
+ */
+ NdbOperation::OperationOptions opts;
+ opts.optionsPresent= 0;
+
+ NdbInterpretedCode nonsenseProgram;
+
+ nonsenseProgram.load_const_u32(0, 0);
+ nonsenseProgram.interpret_exit_ok();
+
+ nonsenseProgram.finalise();
+
+ const Uint32 rowCount= 1500;
+ Uint32 keyOffset= 0;
+ Uint32 anyValueOffset= 100;
+
+ printf ("Testing AnyValue with no interpreted program\n");
+ for (int variants= 0; variants < 2; variants ++)
+ {
+ for (int op= Insert; op < EndOfOpTypes; op++)
+ {
+ printf(" Testing opType %d (ko=%d, ao=%d)...",
+ op, keyOffset, anyValueOffset);
+
+ if (executeOps(pNdb,
+ tab,
+ (OpTypes)op,
+ rowCount,
+ keyOffset,
+ anyValueOffset,
+ opts))
+ return NDBT_FAILED;
+
+ if (checkAnyValueInEvent(pNdb,
+ eventOldKeyData, eventKeyData,
+ eventOldAttrData, eventAttrData,
+ rowCount,
+ anyValueOffset,
+ false // always use postKey data
+ ) != NDBT_OK)
+ return NDBT_FAILED;
+ printf("ok\n");
+ };
+
+ printf("Testing AnyValue with interpreted program\n");
+ opts.optionsPresent|= NdbOperation::OperationOptions::OO_INTERPRETED;
+ opts.interpretedCode= &nonsenseProgram;
+ }
+
+ if (dropEventOperations(pNdb) != 0)
+ {
+ g_err << "Dropping event operations failed : " <<
+ pNdb->getNdbError().code << endl;
+ return NDBT_FAILED;
+ }
+
+ if (dropEvent(pNdb, tab->getName()) != 0)
+ {
+ g_err << "Dropping event failed : " <<
+ pNdb->getDictionary()->getNdbError().code << endl;
+ return NDBT_FAILED;
+ }
+
+ pNdb->getDictionary()->dropTable(tab->getName());
+
+ return NDBT_OK;
+}
+
+
NDBT_TESTSUITE(test_event);
TESTCASE("BasicEventOperation",
"Verify that we can listen to Events"
@@ -2694,6 +3218,22 @@ TESTCASE("Bug35208", ""){
FINALIZER(runVerify);
FINALIZER(runDropShadowTable);
}
+TESTCASE("Bug37279", "")
+{
+ INITIALIZER(runBug37279);
+}
+TESTCASE("Bug37338", "")
+{
+ INITIALIZER(runBug37338);
+}
+TESTCASE("Bug37442", "")
+{
+ INITIALIZER(runBug37442);
+}
+TESTCASE("Bug37672", "NdbRecord option OO_ANYVALUE causes interpreted delete to abort.")
+{
+ INITIALIZER(runBug37672);
+}
NDBT_TESTSUITE_END(test_event);
int main(int argc, const char** argv){
=== modified file 'storage/ndb/test/run-test/autotest-boot.sh'
--- a/storage/ndb/test/run-test/autotest-boot.sh 2007-08-31 14:12:51 +0000
+++ b/storage/ndb/test/run-test/autotest-boot.sh 2008-06-08 05:21:05 +0000
@@ -78,7 +78,7 @@ fi
# Validate that all interesting
# variables where set in conf
###############################
-vars="src_clone_base install_dir build_dir"
+vars="src_clone_base install_dir build_dir bzr_src_base"
for i in $vars
do
t=`echo echo \\$$i`
@@ -103,7 +103,8 @@ fi
# Setup the clone source location #
####################################
-src_clone=${src_clone_base}${clone}
+#src_clone=${src_clone_base}/${clone}
+src_clone=${bzr_src_base}/${clone}
#######################################
# Check to see if the lock file exists#
@@ -152,12 +153,7 @@ fi
if [ "$do_clone" ]
then
rm -rf $dst_place
- if [ `echo $src_clone | grep -c 'file:\/\/'` = 1 ]
- then
- bk clone -l $extra_clone $src_clone $dst_place
- else
- bk clone $extra_clone $src_clone $dst_place
- fi
+ bzr export $dst_place $extra_clone $src_clone
fi
##########################################
=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt 2008-08-08 09:40:47 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt 2008-08-12 18:56:42 +0000
@@ -467,10 +467,6 @@ args: -n ScanReadWhileNodeIsDown D1 D2
max-time: 500
cmd: testScan
-args: -n ScanRestart T1 D1 D2
-
-max-time: 500
-cmd: testScan
args: -l 100 -n Scan-bug8262 T6 D1 D2
max-time: 500
@@ -1090,7 +1086,7 @@ max-time: 600
cmd: test_event
args: -l 1 -n SubscribeNR T1
-max-time: 300
+max-time: 600
cmd: testNodeRestart
args: -n Bug34702 T1
@@ -1098,6 +1094,18 @@ max-time: 600
cmd: test_event
args: -n Bug35208 T1
+max-time: 300
+cmd: test_event
+args: -n Bug37279 T1
+
+max-time: 300
+cmd: test_event
+args: -n Bug37338 T1
+
+max-time: 300
+cmd: test_event
+args: -n Bug37442 T1
+
# 2008-04-22
max-time: 1500
cmd: testNodeRestart
@@ -1135,3 +1143,21 @@ cmd: testDict
args: -l 1 -n FailAddFragment
# EOF 2008-05-29
+# 2008-06-03
+max-time: 1200
+cmd: testNdbApi
+args: -l 100 -n Bug37158
+
+# EOF 2008-06-03
+
+max-time: 500
+cmd: test_event
+args -n bug37672 T1
+
+#EOF 2008-07-04
+
+max-time: 500
+cmd: testScanFilter
+args:
+
+#EOF 2008-07-09
=== modified file 'storage/ndb/tools/restore/Restore.cpp'
--- a/storage/ndb/tools/restore/Restore.cpp 2008-03-20 09:20:09 +0000
+++ b/storage/ndb/tools/restore/Restore.cpp 2008-08-12 18:56:42 +0000
@@ -1002,13 +1002,19 @@ bool RestoreDataIterator::readFragmentHe
if (Header.SectionType == BackupFormat::EMPTY_ENTRY)
{
void *tmp;
- buffer_get_ptr(&tmp, Header.SectionLength*4-8, 1);
+ if (Header.SectionLength < 2)
+ {
+ err << "getFragmentFooter:Error reading fragment footer" << endl;
+ return false;
+ }
+ if (Header.SectionLength > 2)
+ buffer_get_ptr(&tmp, Header.SectionLength*4-8, 1);
continue;
}
break;
}
/* read rest of header */
- if (buffer_read(((char*)&Header)+8, sizeof(Header)-8, 1) != 1)
+ if (buffer_read(((char*)&Header)+8, Header.SectionLength*4-8, 1) != 1)
{
ret = 0;
return false;
=== modified file 'storage/ndb/tools/restore/consumer_restore.cpp'
--- a/storage/ndb/tools/restore/consumer_restore.cpp 2007-12-20 15:36:18 +0000
+++ b/storage/ndb/tools/restore/consumer_restore.cpp 2008-06-18 15:03:43 +0000
@@ -21,6 +21,8 @@
#include <ndb_internal.hpp>
#include <ndb_logevent.h>
+#define NDB_ANYVALUE_FOR_NOLOGGING 0xFFFFFFFF
+
extern my_bool opt_core;
extern FilteredNdbOut err;
@@ -34,6 +36,8 @@ static Uint32 get_part_id(const NdbDicti
extern const char * g_connect_string;
extern BaseString g_options;
+extern unsigned int opt_no_binlog;
+
bool
BackupRestore::init()
{
@@ -1314,6 +1318,11 @@ void BackupRestore::tuple_a(restore_call
exitHandler();
}
+ if (opt_no_binlog)
+ {
+ op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
+ }
+
// Prepare transaction (the transaction is NOT yet sent to NDB)
cb->n_bytes= n_bytes;
cb->connection->executeAsynchPrepare(NdbTransaction::Commit,
@@ -1562,6 +1571,10 @@ BackupRestore::logEntry(const LogEntry &
} // if
}
+ if (opt_no_binlog)
+ {
+ op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
+ }
const int ret = trans->execute(NdbTransaction::Commit);
if (ret != 0)
{
=== modified file 'storage/ndb/tools/restore/restore_main.cpp'
--- a/storage/ndb/tools/restore/restore_main.cpp 2007-09-12 12:35:51 +0000
+++ b/storage/ndb/tools/restore/restore_main.cpp 2008-08-12 18:56:42 +0000
@@ -55,6 +55,7 @@ unsigned int g_report_next;
Vector<BaseString> g_databases;
Vector<BaseString> g_tables;
NdbRecordPrintFormat g_ndbrecord_print_format;
+unsigned int opt_no_binlog;
NDB_STD_OPTS_VARS;
@@ -89,6 +90,7 @@ enum ndb_restore_options {
OPT_LINES_TERMINATED_BY,
OPT_APPEND,
OPT_PROGRESS_FREQUENCY,
+ OPT_NO_BINLOG,
OPT_VERBOSE
};
static const char *opt_fields_enclosed_by= NULL;
@@ -197,6 +199,10 @@ static struct my_option my_long_options[
"Print status uf restore periodically in given seconds",
(uchar**) &opt_progress_frequency, (uchar**) &opt_progress_frequency, 0,
GET_INT, REQUIRED_ARG, 0, 0, 65535, 0, 0, 0 },
+ { "no-binlog", OPT_NO_BINLOG,
+ "If a mysqld is connected and has binary log, do not log the restored data",
+ (uchar**) &opt_no_binlog, (uchar**) &opt_no_binlog, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ "verbose", OPT_VERBOSE,
"verbosity",
(uchar**) &opt_verbose, (uchar**) &opt_verbose, 0,
@@ -648,20 +654,20 @@ static void exitHandler(int code)
static void init_progress()
{
- struct timeval the_time;
- gettimeofday(&the_time, 0);
- g_report_next = the_time.tv_sec + opt_progress_frequency;
+ Uint64 now = NdbTick_CurrentMillisecond() / 1000;
+ g_report_next = now + opt_progress_frequency;
}
static int check_progress()
{
if (!opt_progress_frequency)
return 0;
- struct timeval the_time;
- gettimeofday(&the_time, 0);
- if (the_time.tv_sec >= g_report_next)
+
+ Uint64 now = NdbTick_CurrentMillisecond() / 1000;
+
+ if (now >= g_report_next)
{
- g_report_next = the_time.tv_sec + opt_progress_frequency;
+ g_report_next = now + opt_progress_frequency;
return 1;
}
return 0;
@@ -887,7 +893,8 @@ main(int argc, char** argv)
{
if (!ga_skip_table_check){
for(i=0; i < metaData.getNoOfTables(); i++){
- if (checkSysTable(metaData, i))
+ if (checkSysTable(metaData, i) &&
+ checkDbAndTableName(metaData[i]))
{
for(Uint32 j= 0; j < g_consumers.size(); j++)
if (!g_consumers[j]->table_equal(* metaData[i]))
=== modified file 'storage/ndb/tools/waiter.cpp'
--- a/storage/ndb/tools/waiter.cpp 2008-03-20 09:20:09 +0000
+++ b/storage/ndb/tools/waiter.cpp 2008-08-12 18:56:42 +0000
@@ -21,6 +21,7 @@
#include <NdbMain.h>
#include <NdbOut.hpp>
#include <NdbSleep.h>
+#include <NdbTick.h>
#include <NDBT.hpp>
@@ -214,12 +215,11 @@ waitClusterStatus(const char* _addr,
const int MAX_RESET_ATTEMPTS = 10;
bool allInState = false;
- struct timeval time_now;
- gettimeofday(&time_now, 0);
- Int64 timeout_time = time_now.tv_sec + _timeout;
+ Uint64 time_now = NdbTick_CurrentMillisecond();
+ Uint64 timeout_time = time_now + 1000 * _timeout;
while (allInState == false){
- if (_timeout > 0 && time_now.tv_sec > timeout_time){
+ if (_timeout > 0 && time_now > timeout_time){
/**
* Timeout has expired waiting for the nodes to enter
* the state we want
@@ -257,7 +257,7 @@ waitClusterStatus(const char* _addr,
<< " resetting timeout "
<< resetAttempts << endl;
- timeout_time = time_now.tv_sec + _timeout;
+ timeout_time = time_now + 1000 * _timeout;
resetAttempts++;
}
@@ -290,7 +290,8 @@ waitClusterStatus(const char* _addr,
}
attempts++;
- gettimeofday(&time_now, 0);
+
+ time_now = NdbTick_CurrentMillisecond();
}
return 0;
}
| Thread |
|---|
| • bzr push into mysql-6.0-ndb branch (jonas:2659) | jonas | 12 Aug |