#At file:///home/tomas/mysql_src/mysql-5.1-telco-6.2-merge2/
2663 Tomas Ulin 2008-08-07 [merge]
merge
added:
mysql-test/suite/ndb_binlog/r/ndb_binlog_restore.result
mysql-test/suite/ndb_binlog/t/ndb_binlog_restore.test
renamed:
storage/ndb/src/common/util/ndb_show_compat.cc =>
storage/ndb/src/common/util/ndb_show_compat.cpp
modified:
configure.in
mysql-test/suite/binlog/r/binlog_multi_engine.result
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
sql/ha_ndbcluster.cc
sql/ha_ndbcluster_binlog.cc
sql/rpl_injector.cc
sql/rpl_injector.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
=== modified file 'configure.in'
--- a/configure.in 2008-05-23 07:55:34 +0000
+++ b/configure.in 2008-08-07 12:53:02 +0000
@@ -2063,6 +2063,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)
@@ -2073,6 +2074,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 '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/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-02-11 12:30:36 +0000
+++ b/mysql-test/suite/ndb/r/ndb_restore.result 2008-07-24 09:23:05 +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
=== modified file 'mysql-test/suite/ndb/t/ndb_restore.test'
--- a/mysql-test/suite/ndb/t/ndb_restore.test 2008-02-11 12:30:36 +0000
+++ b/mysql-test/suite/ndb/t/ndb_restore.test 2008-07-24 09:23:05 +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;
@@ -217,5 +222,40 @@ SELECT * FROM t2 order by id;
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-02-25 13:50:20 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_ddl_multi.result 2008-08-07 05:29:44 +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-25 18:03:33 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_format.result 2008-06-19 07:18: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-02-25 13:50:20 +0000
+++ b/mysql-test/suite/ndb_binlog/r/ndb_binlog_log_bin.result 2008-08-07 05:29:44 +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 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2008-05-30 11:12:38 +0000
+++ b/sql/ha_ndbcluster.cc 2008-08-07 05:29:44 +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;
@@ -5953,6 +5954,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);
@@ -6027,7 +6039,7 @@ int ha_ndbcluster::rename_table(const ch
#endif
ERR_RETURN(ndb_error);
}
-
+
// Rename .ndb file
if ((result= handler::rename_table(from, to)))
{
@@ -6333,6 +6345,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-05-09 09:42:18 +0000
+++ b/sql/ha_ndbcluster_binlog.cc 2008-08-07 11:26:22 +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->proc_info= "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->proc_info= "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->proc_info= "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->proc_info= "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-02-19 11:43:01 +0000
+++ b/sql/rpl_injector.cc 2008-06-18 12:53: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 2007-05-10 09:59:39 +0000
+++ b/sql/rpl_injector.h 2008-06-18 12:53:42 +0000
@@ -210,6 +210,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 '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-02-19 15:00:29 +0000
+++ b/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp 2008-08-07 06:24:52 +0000
@@ -309,6 +309,7 @@ int
NdbIndexScanOperation::setBound(const char* attr, int type, const void* value,
Uint32 len)
{
+ (void)len; // unused
return setBound(attr, type, value);
}
@@ -317,6 +318,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-06-09 18:58:35 +0000
@@ -35,10 +35,10 @@ testBitmask_LDFLAGS = @ndb_bin_am_ldflag
$(top_builddir)/mysys/libmysyslt.la \
$(top_builddir)/strings/libmystringslt.la
-#noinst_PROGRAMS = ndb_show_compat
-ndb_show_compat_SOURCES = ndb_show_compat.cc
+noinst_PROGRAMS = ndb_show_compat
+ndb_show_compat_SOURCES = ndb_show_compat.cpp
ndb_show_compat_LDADD = \
- $(builddir)libgeneral.la \
+ libgeneral.la \
$(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
$(top_builddir)/dbug/libdbuglt.la \
$(top_builddir)/mysys/libmysyslt.la \
=== 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-25 16:49:01 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2008-08-04 15:49:01 +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-06-03 10:00:31 +0000
+++ b/storage/ndb/src/ndbapi/Ndb.cpp 2008-06-16 12:34:47 +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-04-22 19:36:05 +0000
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp 2008-06-25 12:49:13 +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-06-03 10:00:31 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2008-08-06 15:33:19 +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-05-21 16:39:51 +0000
+++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp 2008-08-06 15:33:19 +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,
@@ -2627,6 +2623,8 @@ NdbTransaction::scanIndex(const NdbRecor
setOperationErrorCodeAbort(4000);
return NULL;
}
+
+ op->m_scanUsingOldApi= false;
/* Defer the rest of the work to NdbIndexScanOperation */
if (op->scanIndexImpl(key_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"){
@@ -1781,6 +1835,10 @@ TESTCASE("ExecuteAsynch",
TESTCASE("Bug28443",
""){
INITIALIZER(runBug28443);
+}
+TESTCASE("Bug37158",
+ ""){
+ INITIALIZER(runBug37158);
}
NDBT_TESTSUITE_END(testNdbApi);
=== modified file 'storage/ndb/test/ndbapi/testOIBasic.cpp'
--- a/storage/ndb/test/ndbapi/testOIBasic.cpp 2008-04-10 13:08:05 +0000
+++ b/storage/ndb/test/ndbapi/testOIBasic.cpp 2008-07-23 11:15:31 +0000
@@ -612,6 +612,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"
@@ -2693,6 +3217,22 @@ TESTCASE("Bug35208", ""){
FINALIZER(runDropEvent);
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);
=== 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-05-29 15:58:58 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt 2008-08-06 15:33:19 +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-17 16:31:55 +0000
+++ b/storage/ndb/tools/restore/Restore.cpp 2008-08-05 14:08:40 +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:07:08 +0000
+++ b/storage/ndb/tools/restore/restore_main.cpp 2008-07-24 09:23:05 +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:18:53 +0000
+++ b/storage/ndb/tools/waiter.cpp 2008-06-09 18:40:45 +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 commit into mysql-5.1-telco-6.2-merge branch (tomas.ulin:2663) | Tomas Ulin | 7 Aug |