diff --git a/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test index cdd828305dc..efca53d5698 100644 --- a/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test +++ b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test @@ -973,14 +973,7 @@ SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; --echo --echo ** update from master ** connection master; -####################################### -# This test should be uncommented -# once bug30674 is patched -####################################### - -#*************************** -#UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; -#*************************** +UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; --replace_column 5 CURRENT_TIMESTAMP SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; diff --git a/mysql-test/include/have_multi_ndb.inc b/mysql-test/include/have_multi_ndb.inc index deda22b64c0..9779f181191 100644 --- a/mysql-test/include/have_multi_ndb.inc +++ b/mysql-test/include/have_multi_ndb.inc @@ -5,10 +5,6 @@ connect (server2,127.0.0.1,root,,test,$MASTER_MYPORT1,); # Check that server1 has NDB support connection server1; disable_query_log; ---disable_warnings -drop table if exists t1, t2; ---enable_warnings -flush tables; --require r/true.require select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster'; --source include/ndb_not_readonly.inc @@ -17,14 +13,32 @@ enable_query_log; # Check that server2 has NDB support connection server2; disable_query_log; ---disable_warnings -drop table if exists t1, t2; ---enable_warnings -flush tables; --require r/true.require select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster'; --source include/ndb_not_readonly.inc enable_query_log; -# Set the default connection to 'server1' +# cleanup + +connection server1; +disable_query_log; +disable_warnings; +--error 0,1051 +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; +flush tables; +flush status; +enable_warnings; +enable_query_log; + +connection server2; +disable_query_log; +disable_warnings; +--error 0,1051 +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; +flush tables; +flush status; +enable_warnings; +enable_query_log; + +# Set the default connection connection server1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 1a8c18f7d27..18633d095b0 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -129,7 +129,15 @@ our $opt_vs_config = $ENV{'MTR_VS_CONFIG'}; our $default_vardir; our $opt_usage; -our $opt_suites= "main,binlog,rpl,rpl_ndb,ndb"; # Default suites to run +our $opt_suites; +our $opt_suites_default= "main,binlog,rpl,rpl_ndb,ndb"; # Default suites to run +our @extra_suites= +( + ["mysql-5.1-new-ndb", "ndb_team"], + ["mysql-5.1-telco-6.2", "ndb_team"], + ["mysql-5.1-telco-6.3", "ndb_team"], +); + our $opt_script_debug= 0; # Script debugging, enable with --script-debug our $opt_verbose= 0; # Verbose output, enable with --verbose @@ -397,6 +405,20 @@ sub main () { else { # Figure out which tests we are going to run + if (!$opt_suites) + { + # use default and add any extra_suites as defined + $opt_suites= $opt_suites_default; + my $ddd= basename(dirname($glob_mysql_test_dir)); + foreach my $extra_suite (@extra_suites) + { + if ($extra_suite->[0] eq "$ddd") + { + $opt_suites= "$extra_suite->[1],$opt_suites"; + } + } + } + my $tests= collect_test_cases($opt_suites); # Turn off NDB and other similar options if no tests use it @@ -5195,7 +5217,7 @@ Options to control what test suites or cases to run start-from=PREFIX Run test cases starting from test prefixed with PREFIX suite[s]=NAME1,..,NAMEN Collect tests in suites from the comma separated list of suite names. - The default is: "$opt_suites" + The default is: "$opt_suites_default" skip-rpl Skip the replication test cases. skip-im Don't start IM, and skip the IM test cases big-test Set the environment variable BIG_TEST, which can be diff --git a/mysql-test/suite/ndb/r/ndb_auto_increment.result b/mysql-test/suite/ndb/r/ndb_auto_increment.result new file mode 100644 index 00000000000..5740ed38242 --- /dev/null +++ b/mysql-test/suite/ndb/r/ndb_auto_increment.result @@ -0,0 +1,445 @@ +DROP TABLE IF EXISTS t1,t2; +DROP TABLE IF EXISTS t1; +set @old_auto_increment_offset = @@session.auto_increment_offset; +set @old_auto_increment_increment = @@session.auto_increment_increment; +set @old_ndb_autoincrement_prefetch_sz = @@session.ndb_autoincrement_prefetch_sz; +flush status; +create table t1 (a int not null auto_increment primary key) engine ndb; +insert into t1 values (NULL); +select * from t1 order by a; +a +1 +update t1 set a = 5 where a = 1; +insert into t1 values (NULL); +select * from t1 order by a; +a +5 +6 +insert into t1 values (7); +insert into t1 values (NULL); +select * from t1 order by a; +a +5 +6 +7 +8 +insert into t1 values (2); +insert into t1 values (NULL); +select * from t1 order by a; +a +2 +5 +6 +7 +8 +9 +update t1 set a = 4 where a = 2; +insert into t1 values (NULL); +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +10 +delete from t1 where a = 10; +insert into t1 values (NULL); +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +replace t1 values (NULL); +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +12 +replace t1 values (15); +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +12 +15 +replace into t1 values (NULL); +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +12 +15 +16 +replace t1 values (15); +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +12 +15 +16 +insert ignore into t1 values (NULL); +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +12 +15 +16 +17 +insert ignore into t1 values (15), (NULL); +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +12 +15 +16 +17 +18 +insert into t1 values (15) +on duplicate key update a = 20; +insert into t1 values (NULL); +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +12 +16 +17 +18 +20 +21 +insert into t1 values (NULL) on duplicate key update a = 30; +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +12 +16 +17 +18 +20 +21 +22 +insert into t1 values (30) on duplicate key update a = 40; +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +12 +16 +17 +18 +20 +21 +22 +30 +insert ignore into t1 values(600),(NULL),(NULL),(610),(NULL); +select * from t1 order by a; +a +4 +5 +6 +7 +8 +9 +11 +12 +16 +17 +18 +20 +21 +22 +30 +600 +601 +602 +610 +611 +drop table t1; +create table t1 (a int not null primary key, +b int not null unique auto_increment) engine ndb; +insert into t1 values (1, NULL); +insert into t1 values (3, NULL); +update t1 set b = 3 where a = 3; +insert into t1 values (4, NULL); +select * from t1 order by a; +a b +1 1 +3 3 +4 4 +drop table t1; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +1 1 0 +11 2 1 +21 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +TRUNCATE t1; +TRUNCATE t2; +SET @@session.auto_increment_offset=5; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t1 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); +SELECT * FROM t1 ORDER BY pk; +pk b c +5 1 0 +15 2 1 +25 3 2 +27 4 3 +35 5 4 +99 6 5 +105 7 6 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +7 +TRUNCATE t1; +TRUNCATE t2; +SET @@session.auto_increment_increment=2; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +1 1 0 +3 2 1 +5 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 7; +SET @@session.auto_increment_offset=1; +SET @@session.auto_increment_increment=1; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +7 1 0 +8 2 1 +9 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 3; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 3; +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +5 1 0 +15 2 1 +25 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 7; +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +15 1 0 +25 2 1 +35 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 5; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 5; +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +5 1 0 +15 2 1 +25 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 100; +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 100; +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +pk b c +105 1 0 +115 2 1 +125 3 2 +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +COUNT(t1.pk) +3 +DROP TABLE t1, t2; +SET @@session.auto_increment_offset=1; +SET @@session.auto_increment_increment=1; +set ndb_autoincrement_prefetch_sz = 32; +drop table if exists t1; +SET @@session.auto_increment_offset=1; +SET @@session.auto_increment_increment=1; +set ndb_autoincrement_prefetch_sz = 32; +create table t1 (a int not null auto_increment primary key) engine ndb; +insert into t1 values (NULL); +insert into t1 values (NULL); +select * from t1 order by a; +a +1 +33 +insert into t1 values (20); +insert into t1 values (NULL); +select * from t1 order by a; +a +1 +20 +33 +34 +insert into t1 values (35); +insert into t1 values (NULL); +insert into t1 values (NULL); +ERROR 23000: Duplicate entry '35' for key 'PRIMARY' +select * from t1 order by a; +a +1 +20 +21 +33 +34 +35 +insert into t1 values (100); +insert into t1 values (NULL); +insert into t1 values (NULL); +select * from t1 order by a; +a +1 +20 +21 +22 +33 +34 +35 +100 +101 +set auto_increment_offset = @old_auto_increment_offset; +set auto_increment_increment = @old_auto_increment_increment; +set ndb_autoincrement_prefetch_sz = @old_ndb_autoincrement_prefetch_sz; +drop table t1; diff --git a/mysql-test/suite/ndb/r/ndb_basic.result b/mysql-test/suite/ndb/r/ndb_basic.result index 4eddaeb1227..9f4f8c0755c 100644 --- a/mysql-test/suite/ndb/r/ndb_basic.result +++ b/mysql-test/suite/ndb/r/ndb_basic.result @@ -869,6 +869,30 @@ a b 3 30 4 1 drop table t1,t2; +create table t1 (a varchar(100) primary key, b varchar(100)) engine = NDB; +insert into t1 values +('a', 'a'),('b','b'),('c', 'c'),('aa', 'aa'),('bb', 'bb'),('cc', 'cc'); +replace into t1 values ('a', '-a'); +replace into t1 values ('b', '-b'); +replace into t1 values ('c', '-c'); +replace into t1 values ('aa', '-aa'); +replace into t1 values ('bb', '-bb'); +replace into t1 values ('cc', '-cc'); +replace into t1 values ('aaa', '-aaa'); +replace into t1 values ('bbb', '-bbb'); +replace into t1 values ('ccc', '-ccc'); +select * from t1 order by 1,2; +a b +a -a +aa -aa +aaa -aaa +b -b +bb -bb +bbb -bbb +c -c +cc -cc +ccc -ccc +drop table t1; End of 5.0 tests CREATE TABLE t1 (a VARCHAR(255) NOT NULL, CONSTRAINT pk_a PRIMARY KEY (a))engine=ndb; diff --git a/mysql-test/suite/ndb/r/ndb_blob.result b/mysql-test/suite/ndb/r/ndb_blob.result index 34f2c5fdd66..31ce36864af 100644 --- a/mysql-test/suite/ndb/r/ndb_blob.result +++ b/mysql-test/suite/ndb/r/ndb_blob.result @@ -568,3 +568,24 @@ select count(*) from t1; count(*) 0 drop table t1; +create table t1( +a int, +blob_nn blob not null, +text_nn text not null, +blob_nl blob, +text_nl text, +primary key(a) +) engine=ndb; +insert into t1(a) values (1); +Warnings: +Warning 1364 Field 'blob_nn' doesn't have a default value +Warning 1364 Field 'text_nn' doesn't have a default value +insert into t1(a, text_nl) values (2, 'MySQL Cluster NDB'); +Warnings: +Warning 1364 Field 'blob_nn' doesn't have a default value +Warning 1364 Field 'text_nn' doesn't have a default value +select a, length(blob_nn), length(text_nn), blob_nl, text_nl from t1 order by a; +a length(blob_nn) length(text_nn) blob_nl text_nl +1 0 0 NULL NULL +2 0 0 NULL MySQL Cluster NDB +drop table t1; diff --git a/mysql-test/suite/ndb/r/ndb_charset.result b/mysql-test/suite/ndb/r/ndb_charset.result index 1c65a380039..e84c906dd7e 100644 --- a/mysql-test/suite/ndb/r/ndb_charset.result +++ b/mysql-test/suite/ndb/r/ndb_charset.result @@ -112,9 +112,9 @@ unique key(a) ) engine=ndb; insert into t1 values(1, 'aAa'); insert into t1 values(2, 'aaa'); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry 'aaa' for key 'a' insert into t1 values(3, 'AAA'); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry 'AAA' for key 'a' select * from t1 order by p; p a 1 aAa @@ -138,9 +138,9 @@ unique key(a) ) engine=ndb; insert into t1 values (1,'A'),(2,'b '),(3,'C '),(4,'d '),(5,'E'),(6,'f'); insert into t1 values(99,'b'); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry 'b' for key 'a' insert into t1 values(99,'a '); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry 'a ' for key 'a' select a,length(a) from t1 order by a; a length(a) A 1 diff --git a/mysql-test/suite/ndb/r/ndb_index_unique.result b/mysql-test/suite/ndb/r/ndb_index_unique.result index cc63ce69760..bfc0c5a2e56 100644 --- a/mysql-test/suite/ndb/r/ndb_index_unique.result +++ b/mysql-test/suite/ndb/r/ndb_index_unique.result @@ -22,7 +22,7 @@ select * from t1 where b = 4 order by a; a b c 3 4 6 insert into t1 values(8, 2, 3); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '2' for key 'ib' select * from t1 order by a; a b c 1 2 3 @@ -93,7 +93,7 @@ a b c 1 1 1 4 4 NULL insert into t1 values(5,1,1); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '1-1' for key 'bc' drop table t1; CREATE TABLE t2 ( a int unsigned NOT NULL PRIMARY KEY, @@ -116,7 +116,7 @@ select * from t2 where b = 4 order by a; a b c 3 4 6 insert into t2 values(8, 2, 3); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '2-3' for key 'b' select * from t2 order by a; a b c 1 2 3 @@ -139,7 +139,7 @@ a b c 8 2 3 create unique index bi using hash on t2(b); insert into t2 values(9, 3, 1); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '3' for key 'bi' alter table t2 drop index bi; insert into t2 values(9, 3, 1); select * from t2 order by a; @@ -229,7 +229,7 @@ pk a 3 NULL 4 4 insert into t1 values (5,0); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '0' for key 'a' select * from t1 order by pk; pk a -1 NULL @@ -262,7 +262,7 @@ pk a b c 0 NULL 18 NULL 1 3 19 abc insert into t2 values(2,3,19,'abc'); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '3-abc' for key 'si' select * from t2 order by pk; pk a b c -1 1 17 NULL @@ -682,7 +682,7 @@ create table t1 (a int primary key, b varchar(1000) not null, unique key (b)) engine=ndb charset=utf8; insert into t1 values (1, repeat(_utf8 0xe288ab6474, 200)); insert into t1 values (2, repeat(_utf8 0xe288ab6474, 200)); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫d' for key 'b' select a, sha1(b) from t1; a sha1(b) 1 08f5d02c8b8bc244f275bdfc22c42c5cab0d9d7d diff --git a/mysql-test/suite/ndb/r/ndb_insert.result b/mysql-test/suite/ndb/r/ndb_insert.result index 51b346bbf7b..7551dc71823 100644 --- a/mysql-test/suite/ndb/r/ndb_insert.result +++ b/mysql-test/suite/ndb/r/ndb_insert.result @@ -657,172 +657,3 @@ a b 2 NULL 3 NULL drop table t1; -CREATE TABLE t1 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER; -CREATE TABLE t2 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=MYISAM; -SET @@session.auto_increment_increment=10; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -pk b c -1 1 0 -11 2 1 -21 3 2 -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -COUNT(t1.pk) -3 -TRUNCATE t1; -TRUNCATE t2; -SET @@session.auto_increment_offset=5; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t1 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); -SELECT * FROM t1 ORDER BY pk; -pk b c -5 1 0 -15 2 1 -25 3 2 -27 4 3 -35 5 4 -99 6 5 -105 7 6 -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -COUNT(t1.pk) -7 -TRUNCATE t1; -TRUNCATE t2; -SET @@session.auto_increment_increment=2; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -pk b c -1 1 0 -3 2 1 -5 3 2 -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -COUNT(t1.pk) -3 -DROP TABLE t1, t2; -CREATE TABLE t1 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; -CREATE TABLE t2 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=MYISAM AUTO_INCREMENT = 7; -SET @@session.auto_increment_offset=1; -SET @@session.auto_increment_increment=1; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -pk b c -7 1 0 -8 2 1 -9 3 2 -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -COUNT(t1.pk) -3 -DROP TABLE t1, t2; -CREATE TABLE t1 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER AUTO_INCREMENT = 3; -CREATE TABLE t2 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=MYISAM AUTO_INCREMENT = 3; -SET @@session.auto_increment_offset=5; -SET @@session.auto_increment_increment=10; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -pk b c -5 1 0 -15 2 1 -25 3 2 -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -COUNT(t1.pk) -3 -DROP TABLE t1, t2; -CREATE TABLE t1 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; -CREATE TABLE t2 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=MYISAM AUTO_INCREMENT = 7; -SET @@session.auto_increment_offset=5; -SET @@session.auto_increment_increment=10; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -pk b c -15 1 0 -25 2 1 -35 3 2 -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -COUNT(t1.pk) -3 -DROP TABLE t1, t2; -CREATE TABLE t1 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER AUTO_INCREMENT = 5; -CREATE TABLE t2 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=MYISAM AUTO_INCREMENT = 5; -SET @@session.auto_increment_offset=5; -SET @@session.auto_increment_increment=10; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -pk b c -5 1 0 -15 2 1 -25 3 2 -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -COUNT(t1.pk) -3 -DROP TABLE t1, t2; -CREATE TABLE t1 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER AUTO_INCREMENT = 100; -CREATE TABLE t2 ( -pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, -b INT NOT NULL, -c INT NOT NULL UNIQUE -) ENGINE=MYISAM AUTO_INCREMENT = 100; -SET @@session.auto_increment_offset=5; -SET @@session.auto_increment_increment=10; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -pk b c -105 1 0 -115 2 1 -125 3 2 -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -COUNT(t1.pk) -3 -DROP TABLE t1, t2; diff --git a/mysql-test/suite/ndb/r/ndb_multi.result b/mysql-test/suite/ndb/r/ndb_multi.result index 17380b10fd7..40483887919 100644 --- a/mysql-test/suite/ndb/r/ndb_multi.result +++ b/mysql-test/suite/ndb/r/ndb_multi.result @@ -1,4 +1,5 @@ drop table if exists t1, t2, t3, t4; +flush status; drop table if exists t1, t2, t3, t4; flush status; create table t1 (a int) engine=ndbcluster; diff --git a/mysql-test/suite/ndb/r/ndb_multi_row.result b/mysql-test/suite/ndb/r/ndb_multi_row.result index cf5a76d6f01..3d34b16a1a8 100644 --- a/mysql-test/suite/ndb/r/ndb_multi_row.result +++ b/mysql-test/suite/ndb/r/ndb_multi_row.result @@ -1,4 +1,5 @@ drop table if exists t1, t2, t3, t4; +flush status; drop table if exists t1, t2, t3, t4; flush status; create table t1 (a int) engine=ndbcluster; diff --git a/mysql-test/suite/ndb/r/ndb_update.result b/mysql-test/suite/ndb/r/ndb_update.result index ed51daee5cb..fa083587956 100644 --- a/mysql-test/suite/ndb/r/ndb_update.result +++ b/mysql-test/suite/ndb/r/ndb_update.result @@ -28,7 +28,7 @@ pk1 b c 2 2 2 4 1 1 UPDATE t1 set pk1 = 1, c = 2 where pk1 = 4; -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '2' for key 'c' UPDATE IGNORE t1 set pk1 = 1, c = 2 where pk1 = 4; select * from t1 order by pk1; pk1 b c @@ -62,9 +62,9 @@ INSERT INTO t3 VALUES (2, 2); UPDATE t1 SET a = 1; UPDATE t1 SET a = 1 ORDER BY a; UPDATE t2 SET a = 1; -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '1-2' for key 'a' UPDATE t2 SET a = 1 ORDER BY a; -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '1-2' for key 'a' UPDATE t3 SET a = 1; ERROR 23000: Duplicate entry '1-2' for key 'PRIMARY' UPDATE t3 SET a = 1 ORDER BY a; diff --git a/mysql-test/suite/ndb/t/disabled.def b/mysql-test/suite/ndb/t/disabled.def index 1752314ea47..f876039a042 100644 --- a/mysql-test/suite/ndb/t/disabled.def +++ b/mysql-test/suite/ndb/t/disabled.def @@ -12,10 +12,7 @@ partition_03ndb : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table ndb_partition_error2 : HF is not sure if the test can work as internded on all the platforms -ndb_binlog_basic : Bug #32759 2007-11-27 mats ndb_binlog_basic assert failure 'thd->transaction.stmt.modified_non_trans_table' # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open #ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events #ndb_binlog_discover : bug#21806 2006-08-24 -ndb_backup_print : Bug#32357: ndb_backup_print test fails sometimes in pushbuild -ndb_dd_backuprestore : Bug#32659 ndb_dd_backuprestore.test fails randomly diff --git a/mysql-test/suite/ndb/t/ndb_auto_increment.test b/mysql-test/suite/ndb/t/ndb_auto_increment.test new file mode 100644 index 00000000000..14e7ae7ca7b --- /dev/null +++ b/mysql-test/suite/ndb/t/ndb_auto_increment.test @@ -0,0 +1,293 @@ +-- source include/have_multi_ndb.inc +-- source include/not_embedded.inc + +--disable_warnings +connection server1; +DROP TABLE IF EXISTS t1,t2; +connection server2; +DROP TABLE IF EXISTS t1; +connection server1; +--enable_warnings + +set @old_auto_increment_offset = @@session.auto_increment_offset; +set @old_auto_increment_increment = @@session.auto_increment_increment; +set @old_ndb_autoincrement_prefetch_sz = @@session.ndb_autoincrement_prefetch_sz; + +flush status; + +create table t1 (a int not null auto_increment primary key) engine ndb; + +# Step 1: Verify simple insert +insert into t1 values (NULL); +select * from t1 order by a; + +# Step 2: Verify simple update with higher than highest value causes +# next insert to use updated_value + 1 +update t1 set a = 5 where a = 1; +insert into t1 values (NULL); +select * from t1 order by a; + +# Step 3: Verify insert that inserts higher than highest value causes +# next insert to use inserted_value + 1 +insert into t1 values (7); +insert into t1 values (NULL); +select * from t1 order by a; + +# Step 4: Verify that insert into hole, lower than highest value doesn't +# affect next insert +insert into t1 values (2); +insert into t1 values (NULL); +select * from t1 order by a; + +# Step 5: Verify that update into hole, lower than highest value doesn't +# affect next insert +update t1 set a = 4 where a = 2; +insert into t1 values (NULL); +select * from t1 order by a; + +# Step 6: Verify that delete of highest value doesn't cause the next +# insert to reuse this value +delete from t1 where a = 10; +insert into t1 values (NULL); +select * from t1 order by a; + +# Step 7: Verify that REPLACE has the same effect as INSERT +replace t1 values (NULL); +select * from t1 order by a; +replace t1 values (15); +select * from t1 order by a; +replace into t1 values (NULL); +select * from t1 order by a; + +# Step 8: Verify that REPLACE has the same effect as UPDATE +replace t1 values (15); +select * from t1 order by a; + +# Step 9: Verify that IGNORE doesn't affect auto_increment +insert ignore into t1 values (NULL); +select * from t1 order by a; +insert ignore into t1 values (15), (NULL); +select * from t1 order by a; + +# Step 10: Verify that on duplicate key as UPDATE behaves as an +# UPDATE +insert into t1 values (15) +on duplicate key update a = 20; +insert into t1 values (NULL); +select * from t1 order by a; + +# Step 11: Verify that on duplicate key as INSERT behaves as INSERT +insert into t1 values (NULL) on duplicate key update a = 30; +select * from t1 order by a; +insert into t1 values (30) on duplicate key update a = 40; +select * from t1 order by a; + +#Step 12: Vefify INSERT IGNORE (bug#32055) +insert ignore into t1 values(600),(NULL),(NULL),(610),(NULL); +select * from t1 order by a; +drop table t1; + +#Step 13: Verify auto_increment of unique key +create table t1 (a int not null primary key, + b int not null unique auto_increment) engine ndb; +insert into t1 values (1, NULL); +insert into t1 values (3, NULL); +update t1 set b = 3 where a = 3; +insert into t1 values (4, NULL); +select * from t1 order by a; +drop table t1; + +#Step 14: Verify that auto_increment_increment and auto_increment_offset +# work as expected + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM; + +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +TRUNCATE t1; +TRUNCATE t2; +SET @@session.auto_increment_offset=5; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t1 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +TRUNCATE t1; +TRUNCATE t2; +SET @@session.auto_increment_increment=2; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 7; + +SET @@session.auto_increment_offset=1; +SET @@session.auto_increment_increment=1; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 3; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 3; + +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 7; + +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 5; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 5; + +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=NDBCLUSTER AUTO_INCREMENT = 100; + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL UNIQUE +) ENGINE=MYISAM AUTO_INCREMENT = 100; + +SET @@session.auto_increment_offset=5; +SET @@session.auto_increment_increment=10; +INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); +INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); +SELECT * FROM t1 ORDER BY pk; +SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; +DROP TABLE t1, t2; + +#Step 15: Now verify that behaviour on multiple MySQL Servers behave +# properly. Start by dropping table and recreating it to start +# counters and id caches from zero again. +--disable_warnings +connection server2; +SET @@session.auto_increment_offset=1; +SET @@session.auto_increment_increment=1; +set ndb_autoincrement_prefetch_sz = 32; +drop table if exists t1; +connection server1; +SET @@session.auto_increment_offset=1; +SET @@session.auto_increment_increment=1; +set ndb_autoincrement_prefetch_sz = 32; +--enable_warnings + + +create table t1 (a int not null auto_increment primary key) engine ndb; +# Basic test, ensure that the second server gets a new range. +#Generate record with key = 1 +insert into t1 values (NULL); +connection server2; +#Generate record with key = 33 +insert into t1 values (NULL); +connection server1; +select * from t1 order by a; + +#This insert should not affect the range of the second server +insert into t1 values (20); +connection server2; +insert into t1 values (NULL); +select * from t1 order by a; + +connection server1; +#This insert should remove cached values but also skip values already +#taken by server2, given that there is no method of communicating with +#the other server it should also cause a conflict +connection server1; + +insert into t1 values (35); +insert into t1 values (NULL); +connection server2; +--error ER_DUP_ENTRY +insert into t1 values (NULL); +select * from t1 order by a; + +insert into t1 values (100); +insert into t1 values (NULL); +connection server1; +insert into t1 values (NULL); +select * from t1 order by a; + +set auto_increment_offset = @old_auto_increment_offset; +set auto_increment_increment = @old_auto_increment_increment; +set ndb_autoincrement_prefetch_sz = @old_ndb_autoincrement_prefetch_sz; + +drop table t1; diff --git a/mysql-test/suite/ndb/t/ndb_basic.test b/mysql-test/suite/ndb/t/ndb_basic.test index b9ccdf9fd0d..2fc140288ca 100644 --- a/mysql-test/suite/ndb/t/ndb_basic.test +++ b/mysql-test/suite/ndb/t/ndb_basic.test @@ -800,9 +800,27 @@ update ignore t1,t2 set a = 1, c = 1 where a = 3 and c = 3; select * from t1 order by a; drop table t1,t2; -# End of 5.0 tests ---echo End of 5.0 tests +# +# Bug#31635 +# +create table t1 (a varchar(100) primary key, b varchar(100)) engine = NDB; +insert into t1 values + ('a', 'a'),('b','b'),('c', 'c'),('aa', 'aa'),('bb', 'bb'),('cc', 'cc'); +replace into t1 values ('a', '-a'); +replace into t1 values ('b', '-b'); +replace into t1 values ('c', '-c'); +replace into t1 values ('aa', '-aa'); +replace into t1 values ('bb', '-bb'); +replace into t1 values ('cc', '-cc'); + +replace into t1 values ('aaa', '-aaa'); +replace into t1 values ('bbb', '-bbb'); +replace into t1 values ('ccc', '-ccc'); +select * from t1 order by 1,2; +drop table t1; + +--echo End of 5.0 tests # # Bug #18483 Cannot create table with FK constraint diff --git a/mysql-test/suite/ndb/t/ndb_blob.test b/mysql-test/suite/ndb/t/ndb_blob.test index b9a8c7e20ee..0388913df8b 100644 --- a/mysql-test/suite/ndb/t/ndb_blob.test +++ b/mysql-test/suite/ndb/t/ndb_blob.test @@ -497,3 +497,23 @@ select count(*) from t1; drop table t1; # End of 4.1 tests + + +# bug # 30674 : +# NOT NULL Blobs should default to zero-length. Not NULL TEXT +# should default to zero-chars +create table t1( + a int, + blob_nn blob not null, + text_nn text not null, + blob_nl blob, + text_nl text, + primary key(a) +) engine=ndb; + +insert into t1(a) values (1); +insert into t1(a, text_nl) values (2, 'MySQL Cluster NDB'); + +select a, length(blob_nn), length(text_nn), blob_nl, text_nl from t1 order by a; + +drop table t1; diff --git a/mysql-test/suite/ndb/t/ndb_insert.test b/mysql-test/suite/ndb/t/ndb_insert.test index 5b74cc9202c..d659f8357f2 100644 --- a/mysql-test/suite/ndb/t/ndb_insert.test +++ b/mysql-test/suite/ndb/t/ndb_insert.test @@ -638,142 +638,4 @@ create table t1(a int primary key, b int, unique key(b)) engine=ndb; insert ignore into t1 values (1,0), (2,0), (2,null), (3,null); select * from t1 order by a; drop table t1; - -# Bug#26342 auto_increment_increment AND auto_increment_offset REALLY REALLY anger NDB cluster - -CREATE TABLE t1 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER; - -CREATE TABLE t2 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=MYISAM; - -SET @@session.auto_increment_increment=10; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -TRUNCATE t1; -TRUNCATE t2; -SET @@session.auto_increment_offset=5; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t1 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6); -SELECT * FROM t1 ORDER BY pk; -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -TRUNCATE t1; -TRUNCATE t2; -SET @@session.auto_increment_increment=2; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -DROP TABLE t1, t2; - -CREATE TABLE t1 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; - -CREATE TABLE t2 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=MYISAM AUTO_INCREMENT = 7; - -SET @@session.auto_increment_offset=1; -SET @@session.auto_increment_increment=1; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -DROP TABLE t1, t2; - -CREATE TABLE t1 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER AUTO_INCREMENT = 3; - -CREATE TABLE t2 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=MYISAM AUTO_INCREMENT = 3; - -SET @@session.auto_increment_offset=5; -SET @@session.auto_increment_increment=10; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -DROP TABLE t1, t2; - -CREATE TABLE t1 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7; - -CREATE TABLE t2 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=MYISAM AUTO_INCREMENT = 7; - -SET @@session.auto_increment_offset=5; -SET @@session.auto_increment_increment=10; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -DROP TABLE t1, t2; - -CREATE TABLE t1 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER AUTO_INCREMENT = 5; - -CREATE TABLE t2 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=MYISAM AUTO_INCREMENT = 5; - -SET @@session.auto_increment_offset=5; -SET @@session.auto_increment_increment=10; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -DROP TABLE t1, t2; - -CREATE TABLE t1 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=NDBCLUSTER AUTO_INCREMENT = 100; - -CREATE TABLE t2 ( - pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT, - b INT NOT NULL, - c INT NOT NULL UNIQUE -) ENGINE=MYISAM AUTO_INCREMENT = 100; - -SET @@session.auto_increment_offset=5; -SET @@session.auto_increment_increment=10; -INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2); -INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2); -SELECT * FROM t1 ORDER BY pk; -SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c; -DROP TABLE t1, t2; - # End of 4.1 tests diff --git a/mysql-test/suite/ndb/t/ndb_multi.test b/mysql-test/suite/ndb/t/ndb_multi.test index c2217b51d08..e033ad1e479 100644 --- a/mysql-test/suite/ndb/t/ndb_multi.test +++ b/mysql-test/suite/ndb/t/ndb_multi.test @@ -4,11 +4,11 @@ --disable_warnings connection server2; drop table if exists t1, t2, t3, t4; +flush status; connection server1; drop table if exists t1, t2, t3, t4; ---enable_warnings - flush status; +--enable_warnings # Create test tables on server1 create table t1 (a int) engine=ndbcluster; diff --git a/mysql-test/suite/ndb/t/ndb_multi_row.test b/mysql-test/suite/ndb/t/ndb_multi_row.test index c82307839f4..26953093ed0 100644 --- a/mysql-test/suite/ndb/t/ndb_multi_row.test +++ b/mysql-test/suite/ndb/t/ndb_multi_row.test @@ -6,11 +6,12 @@ --disable_warnings connection server2; drop table if exists t1, t2, t3, t4; +flush status; connection server1; drop table if exists t1, t2, t3, t4; +flush status; --enable_warnings -flush status; # Create test tables on server1 create table t1 (a int) engine=ndbcluster; diff --git a/mysql-test/suite/ndb/r/ndb_backup_print.result b/mysql-test/suite/ndb_team/r/ndb_backup_print.result similarity index 100% rename from mysql-test/suite/ndb/r/ndb_backup_print.result rename to mysql-test/suite/ndb_team/r/ndb_backup_print.result diff --git a/mysql-test/suite/ndb/r/ndb_dd_backuprestore.result b/mysql-test/suite/ndb_team/r/ndb_dd_backuprestore.result similarity index 100% rename from mysql-test/suite/ndb/r/ndb_dd_backuprestore.result rename to mysql-test/suite/ndb_team/r/ndb_dd_backuprestore.result diff --git a/mysql-test/suite/ndb/t/ndb_backup_print.test b/mysql-test/suite/ndb_team/t/ndb_backup_print.test similarity index 100% rename from mysql-test/suite/ndb/t/ndb_backup_print.test rename to mysql-test/suite/ndb_team/t/ndb_backup_print.test diff --git a/mysql-test/suite/ndb/t/ndb_dd_backuprestore.test b/mysql-test/suite/ndb_team/t/ndb_dd_backuprestore.test similarity index 100% rename from mysql-test/suite/ndb/t/ndb_dd_backuprestore.test rename to mysql-test/suite/ndb_team/t/ndb_dd_backuprestore.test diff --git a/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result b/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result index af460ded1e7..ad67f96db71 100644 --- a/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result @@ -1089,18 +1089,19 @@ c1 hex(c4) c5 3 62316231623162316231623162316231 QA ** update from master ** +UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; c1 hex(c4) c5 c6 c7 1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP +3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP ** Check slave ** SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; c1 hex(c4) c5 1 62316231623162316231623162316231 Kyle 2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA +3 62316231623162316231623162316231 TEST DROP TABLE t18; @@ -2229,18 +2230,19 @@ c1 hex(c4) c5 3 62316231623162316231623162316231 QA ** update from master ** +UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; c1 hex(c4) c5 c6 c7 1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP +3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP ** Check slave ** SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; c1 hex(c4) c5 1 62316231623162316231623162316231 Kyle 2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA +3 62316231623162316231623162316231 TEST DROP TABLE t18; @@ -3369,18 +3371,19 @@ c1 hex(c4) c5 3 62316231623162316231623162316231 QA ** update from master ** +UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; c1 hex(c4) c5 c6 c7 1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP +3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP ** Check slave ** SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; c1 hex(c4) c5 1 62316231623162316231623162316231 Kyle 2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA +3 62316231623162316231623162316231 TEST DROP TABLE t18; diff --git a/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result b/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result index f0613c16825..8859a8e24e3 100644 --- a/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result +++ b/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result @@ -1089,18 +1089,19 @@ c1 hex(c4) c5 3 62316231623162316231623162316231 QA ** update from master ** +UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; c1 hex(c4) c5 c6 c7 1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP +3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP ** Check slave ** SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; c1 hex(c4) c5 1 62316231623162316231623162316231 Kyle 2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA +3 62316231623162316231623162316231 TEST DROP TABLE t18; @@ -2229,18 +2230,19 @@ c1 hex(c4) c5 3 62316231623162316231623162316231 QA ** update from master ** +UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; c1 hex(c4) c5 c6 c7 1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP +3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP ** Check slave ** SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; c1 hex(c4) c5 1 62316231623162316231623162316231 Kyle 2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA +3 62316231623162316231623162316231 TEST DROP TABLE t18; @@ -3369,18 +3371,19 @@ c1 hex(c4) c5 3 62316231623162316231623162316231 QA ** update from master ** +UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; c1 hex(c4) c5 c6 c7 1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP +3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP ** Check slave ** SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; c1 hex(c4) c5 1 62316231623162316231623162316231 Kyle 2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA +3 62316231623162316231623162316231 TEST DROP TABLE t18; diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_ddl.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_ddl.result index aeaca1e7de0..e668b57293e 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_ddl.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_ddl.result @@ -1086,6 +1086,9 @@ Modified # Created # Security_type DEFINER Comment +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci -------- switch to slave -------- SHOW PROCEDURE STATUS LIKE 'p1'; @@ -1097,6 +1100,9 @@ Modified # Created # Security_type DEFINER Comment +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci -------- switch to master ------- @@ -1149,6 +1155,9 @@ Modified # Created # Security_type DEFINER Comment I have been altered +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci -------- switch to slave -------- SHOW PROCEDURE STATUS LIKE 'p1'; @@ -1160,6 +1169,9 @@ Modified # Created # Security_type DEFINER Comment I have been altered +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci -------- switch to master ------- @@ -1251,13 +1263,13 @@ TEST-INFO: SLAVE: The INSERT is committed (Succeeded) -------- switch to master ------- SHOW CREATE VIEW v1; -View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci -------- switch to slave -------- SHOW CREATE VIEW v1; -View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci -------- switch to master ------- @@ -1302,13 +1314,13 @@ TEST-INFO: SLAVE: The INSERT is committed (Succeeded) -------- switch to master ------- SHOW CREATE VIEW v1; -View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci -------- switch to slave -------- SHOW CREATE VIEW v1; -View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci -------- switch to master ------- @@ -1402,13 +1414,13 @@ TEST-INFO: SLAVE: The INSERT is committed (Succeeded) -------- switch to master ------- SHOW TRIGGERS; -Trigger Event Table Statement Timing Created sql_mode Definer -trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -------- switch to slave -------- SHOW TRIGGERS; -Trigger Event Table Statement Timing Created sql_mode Definer -trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -------- switch to master ------- @@ -1453,11 +1465,11 @@ TEST-INFO: SLAVE: The INSERT is committed (Succeeded) -------- switch to master ------- SHOW TRIGGERS; -Trigger Event Table Statement Timing Created sql_mode Definer +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -------- switch to slave -------- SHOW TRIGGERS; -Trigger Event Table Statement Timing Created sql_mode Definer +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -------- switch to master ------- diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraColMaster.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraColMaster.result index d5d4658c01f..194e6a375f3 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraColMaster.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraColMaster.result @@ -1089,18 +1089,19 @@ c1 hex(c4) c5 3 62316231623162316231623162316231 QA ** update from master ** +UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; c1 hex(c4) c5 c6 c7 1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP +3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP ** Check slave ** SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; c1 hex(c4) c5 1 62316231623162316231623162316231 Kyle 2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA +3 62316231623162316231623162316231 TEST DROP TABLE t18; @@ -2229,18 +2230,19 @@ c1 hex(c4) c5 3 62316231623162316231623162316231 QA ** update from master ** +UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3; SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1; c1 hex(c4) c5 c6 c7 1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP 2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP -3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP +3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP ** Check slave ** SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1; c1 hex(c4) c5 1 62316231623162316231623162316231 Kyle 2 62316231623162316231623162316231 JOE -3 62316231623162316231623162316231 QA +3 62316231623162316231623162316231 TEST DROP TABLE t18; diff --git a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result index abd5bad8e49..f176d4eb52a 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result @@ -389,9 +389,9 @@ INSERT INTO t8 VALUES (99,99,99); INSERT INTO t8 VALUES (99,22,33); ERROR 23000: Duplicate entry '99' for key 'PRIMARY' INSERT INTO t8 VALUES (11,99,33); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '99' for key 'b' INSERT INTO t8 VALUES (11,22,99); -ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +ERROR 23000: Duplicate entry '99' for key 'c' SELECT * FROM t8 ORDER BY a; a b c 99 99 99 diff --git a/mysql-test/suite/rpl_ndb/t/disabled.def b/mysql-test/suite/rpl_ndb/t/disabled.def index 60bfa559953..bb701b9dc3e 100644 --- a/mysql-test/suite/rpl_ndb/t/disabled.def +++ b/mysql-test/suite/rpl_ndb/t/disabled.def @@ -14,7 +14,6 @@ rpl_ndb_2innodb : Bug #32648 Test failure between NDB Cluster and other engines rpl_ndb_2myisam : Bug #32648 Test failure between NDB Cluster and other engines rpl_ndb_2other : Bug #32648 Test failure between NDB Cluster and other engines -rpl_ndb_ddl : BUG#28798 2007-05-31 lars Valgrind failure in NDB rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset rpl_ndb_extraColMaster : BUG#30854 : Tables name show as binary in slave err msg on vm-win2003-64-b and Solaris rpl_ndb_mix_innodb : Bug #32720 Test rpl_ndb_mix_innodb fails on SPARC and PowerPC diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index bf2b19bfc9c..b9d7e846d84 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -588,6 +588,24 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans) err.code, res)); if (res == HA_ERR_FOUND_DUPP_KEY) { + char *error_data= err.details; + uint dupkey= MAX_KEY; + + for (uint i= 0; i < MAX_KEY; i++) + { + if (m_index[i].type == UNIQUE_INDEX || + m_index[i].type == UNIQUE_ORDERED_INDEX) + { + const NDBINDEX *unique_index= + (const NDBINDEX *) m_index[i].unique_index; + if (unique_index && + (char *) unique_index->getObjectId() == error_data) + { + dupkey= i; + break; + } + } + } if (m_rows_to_insert == 1) { /* @@ -595,7 +613,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans) violations here, so we need to return MAX_KEY for non-primary to signal that key is unknown */ - m_dupkey= err.code == 630 ? table_share->primary_key : MAX_KEY; + m_dupkey= err.code == 630 ? table_share->primary_key : dupkey; } else { @@ -618,7 +636,7 @@ bool ha_ndbcluster::get_error_message(int error, DBUG_ENTER("ha_ndbcluster::get_error_message"); DBUG_PRINT("enter", ("error: %d", error)); - Ndb *ndb= get_ndb(); + Ndb *ndb= check_ndb_in_thd(current_thd); if (!ndb) DBUG_RETURN(FALSE); @@ -2704,6 +2722,29 @@ int ha_ndbcluster::full_table_scan(uchar *buf) DBUG_RETURN(next_result(buf)); } +int +ha_ndbcluster::set_auto_inc(Field *field) +{ + DBUG_ENTER("ha_ndbcluster::set_auto_inc"); + Ndb *ndb= get_ndb(); + bool read_bit= bitmap_is_set(table->read_set, field->field_index); + bitmap_set_bit(table->read_set, field->field_index); + Uint64 next_val= (Uint64) field->val_int() + 1; + if (!read_bit) + bitmap_clear_bit(table->read_set, field->field_index); +#ifndef DBUG_OFF + char buff[22]; + DBUG_PRINT("info", + ("Trying to set next auto increment value to %s", + llstr(next_val, buff))); +#endif + Ndb_tuple_id_range_guard g(m_share); + if (ndb->setAutoIncrementValue(m_table, g.range, next_val, TRUE) + == -1) + ERR_RETURN(ndb->getNdbError()); + DBUG_RETURN(0); +} + /* Insert one record into NDB */ @@ -2910,18 +2951,11 @@ int ha_ndbcluster::write_row(uchar *record) } if ((has_auto_increment) && (m_skip_auto_increment)) { - Ndb *ndb= get_ndb(); - Uint64 next_val= (Uint64) table->next_number_field->val_int() + 1; -#ifndef DBUG_OFF - char buff[22]; - DBUG_PRINT("info", - ("Trying to set next auto increment value to %s", - llstr(next_val, buff))); -#endif - Ndb_tuple_id_range_guard g(m_share); - if (ndb->setAutoIncrementValue(m_table, g.range, next_val, TRUE) - == -1) - ERR_RETURN(ndb->getNdbError()); + int ret_val; + if ((ret_val= set_auto_inc(table->next_number_field))) + { + DBUG_RETURN(ret_val); + } } m_skip_auto_increment= TRUE; @@ -3046,6 +3080,17 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data) // Insert new row DBUG_PRINT("info", ("delete succeded")); m_primary_key_update= TRUE; + /* + If we are updating a primary key with auto_increment + then we need to update the auto_increment counter + */ + if (table->found_next_number_field && + bitmap_is_set(table->write_set, + table->found_next_number_field->field_index) && + (error= set_auto_inc(table->found_next_number_field))) + { + DBUG_RETURN(error); + } insert_res= write_row(new_data); m_primary_key_update= FALSE; if (insert_res) @@ -3068,7 +3113,17 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data) DBUG_PRINT("info", ("delete+insert succeeded")); DBUG_RETURN(0); } - + /* + If we are updating a unique key with auto_increment + then we need to update the auto_increment counter + */ + if (table->found_next_number_field && + bitmap_is_set(table->write_set, + table->found_next_number_field->field_index) && + (error= set_auto_inc(table->found_next_number_field))) + { + DBUG_RETURN(error); + } if (cursor) { /* @@ -4478,9 +4533,11 @@ int ha_ndbcluster::init_handler_for_statement(THD *thd, Thd_ndb *thd_ndb) // store thread specific data first to set the right context m_force_send= thd->variables.ndb_force_send; m_ha_not_exact_count= !thd->variables.ndb_use_exact_count; - m_autoincrement_prefetch= - (ha_rows) thd->variables.ndb_autoincrement_prefetch_sz; - + m_autoincrement_prefetch= + (thd->variables.ndb_autoincrement_prefetch_sz > + NDB_DEFAULT_AUTO_PREFETCH) ? + (ha_rows) thd->variables.ndb_autoincrement_prefetch_sz + : (ha_rows) NDB_DEFAULT_AUTO_PREFETCH; m_active_trans= thd_ndb->trans; DBUG_ASSERT(m_active_trans); // Start of transaction @@ -6163,8 +6220,9 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment, ulonglong *first_value, ulonglong *nb_reserved_values) { - int cache_size; + uint cache_size; Uint64 auto_value; + THD *thd= current_thd; DBUG_ENTER("get_auto_increment"); DBUG_PRINT("enter", ("m_tabname: %s", m_tabname)); Ndb *ndb= get_ndb(); @@ -6174,11 +6232,14 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment, /* We guessed too low */ m_rows_to_insert+= m_autoincrement_prefetch; } - cache_size= - (int) ((m_rows_to_insert - m_rows_inserted < m_autoincrement_prefetch) ? - m_rows_to_insert - m_rows_inserted : - ((m_rows_to_insert > m_autoincrement_prefetch) ? - m_rows_to_insert : m_autoincrement_prefetch)); + uint remaining= m_rows_to_insert - m_rows_inserted; + uint min_prefetch= + (remaining < thd->variables.ndb_autoincrement_prefetch_sz) ? + thd->variables.ndb_autoincrement_prefetch_sz + : remaining; + cache_size= ((remaining < m_autoincrement_prefetch) ? + min_prefetch + : remaining); uint retries= NDB_AUTO_INCREMENT_RETRIES; int retry_sleep= 30; /* 30 milliseconds, transaction */ for (;;) @@ -6265,7 +6326,7 @@ ha_ndbcluster::ha_ndbcluster(handlerton *hton, TABLE_SHARE *table_arg): m_dupkey((uint) -1), m_ha_not_exact_count(FALSE), m_force_send(TRUE), - m_autoincrement_prefetch((ha_rows) 32), + m_autoincrement_prefetch((ha_rows) NDB_DEFAULT_AUTO_PREFETCH), m_transaction_on(TRUE), m_cond(NULL), m_multi_cursor(NULL) diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index fd337303853..cc79402fe92 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -31,6 +31,8 @@ #include #define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8 +#define NDB_DEFAULT_AUTO_PREFETCH 32 + class Ndb; // Forward declaration class NdbOperation; // Forward declaration @@ -446,6 +448,7 @@ private: uint errcode); int peek_indexed_rows(const uchar *record, NDB_WRITE_OP write_op); int fetch_next(NdbScanOperation* op); + int set_auto_inc(Field *field); int next_result(uchar *buf); int define_read_attrs(uchar* buf, NdbOperation* op); int filtered_scan(const uchar *key, uint key_len, diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index be75eff2575..d015750ee44 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -241,18 +241,22 @@ static void dbug_print_table(const char *info, TABLE *table) static void run_query(THD *thd, char *buf, char *end, const int *no_print_error, my_bool disable_binlog) { - ulong save_query_length= thd->query_length; - char *save_query= thd->query; + ulong save_thd_query_length= thd->query_length; + char *save_thd_query= thd->query; ulong save_thread_id= thd->variables.pseudo_thread_id; + struct system_status_var save_thd_status_var= thd->status_var; + THD_TRANS save_thd_transaction_all= thd->transaction.all; + THD_TRANS save_thd_transaction_stmt= thd->transaction.stmt; ulonglong save_thd_options= thd->options; DBUG_ASSERT(sizeof(save_thd_options) == sizeof(thd->options)); - NET save_net= thd->net; + NET save_thd_net= thd->net; const char* found_semicolon= NULL; bzero((char*) &thd->net, sizeof(NET)); thd->query_length= end - buf; thd->query= buf; thd->variables.pseudo_thread_id= thread_id; + thd->transaction.stmt.modified_non_trans_table= FALSE; if (disable_binlog) thd->options&= ~OPTION_BIN_LOG; @@ -275,10 +279,13 @@ static void run_query(THD *thd, char *buf, char *end, } thd->options= save_thd_options; - thd->query_length= save_query_length; - thd->query= save_query; + thd->query_length= save_thd_query_length; + thd->query= save_thd_query; thd->variables.pseudo_thread_id= save_thread_id; - thd->net= save_net; + thd->status_var= save_thd_status_var; + thd->transaction.all= save_thd_transaction_all; + thd->transaction.stmt= save_thd_transaction_stmt; + thd->net= save_thd_net; if (thd == injector_thd) { @@ -777,8 +784,9 @@ static int ndbcluster_create_ndb_apply_status_table(THD *thd) " end_pos BIGINT UNSIGNED NOT NULL, " " PRIMARY KEY USING HASH (server_id) ) ENGINE=NDB"); - const int no_print_error[4]= {ER_TABLE_EXISTS_ERROR, + const int no_print_error[5]= {ER_TABLE_EXISTS_ERROR, 701, + 702, 4009, 0}; // do not print error 701 etc run_query(thd, buf, end, no_print_error, TRUE); @@ -837,8 +845,9 @@ static int ndbcluster_create_schema_table(THD *thd) " type INT UNSIGNED NOT NULL," " PRIMARY KEY USING HASH (db,name) ) ENGINE=NDB"); - const int no_print_error[4]= {ER_TABLE_EXISTS_ERROR, + const int no_print_error[5]= {ER_TABLE_EXISTS_ERROR, 701, + 702, 4009, 0}; // do not print error 701 etc run_query(thd, buf, end, no_print_error, TRUE); @@ -3587,6 +3596,7 @@ pthread_handler_t ndb_binlog_thread_func(void *arg) Thd_ndb *thd_ndb=0; int ndb_update_ndb_binlog_index= 1; injector *inj= injector::instance(); + uint incident_id= 0; #ifdef RUN_NDB_BINLOG_TIMER Timer main_timer; @@ -3693,18 +3703,64 @@ pthread_handler_t ndb_binlog_thread_func(void *arg) pthread_mutex_unlock(&injector_mutex); pthread_cond_signal(&injector_cond); + /* + wait for mysql server to start (so that the binlog is started + and thus can receive the first GAP event) + */ + pthread_mutex_lock(&LOCK_server_started); + while (!mysqld_server_started) + { + struct timespec abstime; + set_timespec(abstime, 1); + pthread_cond_timedwait(&COND_server_started, &LOCK_server_started, + &abstime); + if (ndbcluster_terminating) + { + pthread_mutex_unlock(&LOCK_server_started); + pthread_mutex_lock(&LOCK_ndb_util_thread); + goto err; + } + } + pthread_mutex_unlock(&LOCK_server_started); restart: /* Main NDB Injector loop */ + while (ndb_binlog_running) { /* - Always insert a GAP event as we cannot know what has happened in the cluster - while not being connected. + check if it is the first log, if so we do not insert a GAP event + as there is really no log to have a GAP in */ - LEX_STRING const msg= { C_STRING_WITH_LEN("Cluster connect") }; - inj->record_incident(thd, INCIDENT_LOST_EVENTS, msg); + if (incident_id == 0) + { + LOG_INFO log_info; + mysql_bin_log.get_current_log(&log_info); + int len= strlen(log_info.log_file_name); + uint no= 0; + if ((sscanf(log_info.log_file_name + len - 6, "%u", &no) == 1) && + no == 1) + { + /* this is the fist log, so skip GAP event */ + break; + } + } + + /* + Always insert a GAP event as we cannot know what has happened + in the cluster while not being connected. + */ + LEX_STRING const msg[2]= + { + { C_STRING_WITH_LEN("mysqld startup") }, + { C_STRING_WITH_LEN("cluster disconnect")} + }; + IF_DBUG(int error=) + inj->record_incident(thd, INCIDENT_LOST_EVENTS, msg[incident_id]); + DBUG_ASSERT(!error); + break; } + incident_id= 1; { thd->proc_info= "Waiting for ndbcluster to start"; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fad2e5dcd22..7fd625e496b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5534,13 +5534,8 @@ master-ssl", {"ndb-autoincrement-prefetch-sz", OPT_NDB_AUTOINCREMENT_PREFETCH_SZ, "Specify number of autoincrement values that are prefetched.", (uchar**) &global_system_variables.ndb_autoincrement_prefetch_sz, - (uchar**) &global_system_variables.ndb_autoincrement_prefetch_sz, - 0, GET_ULONG, REQUIRED_ARG, 32, 1, 256, 0, 0, 0}, - {"ndb-distribution", OPT_NDB_DISTRIBUTION, - "Default distribution for new tables in ndb", - (uchar**) &opt_ndb_distribution, - (uchar**) &opt_ndb_distribution, - 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + (uchar**) &max_system_variables.ndb_autoincrement_prefetch_sz, + 0, GET_ULONG, REQUIRED_ARG, 1, 1, 256, 0, 0, 0}, {"ndb-force-send", OPT_NDB_FORCE_SEND, "Force send of buffers to ndb immediately without waiting for " "other threads.", diff --git a/storage/ndb/include/kernel/signaldata/TcKeyRef.hpp b/storage/ndb/include/kernel/signaldata/TcKeyRef.hpp index 2846ce3854f..56f6cdae29d 100644 --- a/storage/ndb/include/kernel/signaldata/TcKeyRef.hpp +++ b/storage/ndb/include/kernel/signaldata/TcKeyRef.hpp @@ -40,12 +40,13 @@ class TcKeyRef { friend bool printTCKEYREF(FILE *, const Uint32 *, Uint32, Uint16); public: - STATIC_CONST( SignalLength = 4 ); + STATIC_CONST( SignalLength = 5 ); private: Uint32 connectPtr; Uint32 transId[2]; Uint32 errorCode; + Uint32 errorData; }; #endif diff --git a/storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp b/storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp index 3b5e2f3d3cb..609756605d5 100644 --- a/storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp +++ b/storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp @@ -38,12 +38,13 @@ class TcRollbackRep { friend bool printTCROLBACKREP(FILE *, const Uint32 *, Uint32, Uint16); public: - STATIC_CONST( SignalLength = 4 ); + STATIC_CONST( SignalLength = 5 ); private: Uint32 connectPtr; Uint32 transId[2]; Uint32 returnCode; + Uint32 errorData; }; #endif diff --git a/storage/ndb/include/ndbapi/NdbDictionary.hpp b/storage/ndb/include/ndbapi/NdbDictionary.hpp index 58882e139fd..0e782ba9214 100644 --- a/storage/ndb/include/ndbapi/NdbDictionary.hpp +++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp @@ -1020,7 +1020,7 @@ public: * Get the name of the table being indexed */ const char * getTable() const; - + /** * Get the number of columns in the index */ diff --git a/storage/ndb/src/common/transporter/Transporter.cpp b/storage/ndb/src/common/transporter/Transporter.cpp index cec018575e0..269a5fba4e9 100644 --- a/storage/ndb/src/common/transporter/Transporter.cpp +++ b/storage/ndb/src/common/transporter/Transporter.cpp @@ -70,7 +70,7 @@ Transporter::Transporter(TransporterRegistry &t_reg, signalIdUsed = _signalId; m_connected = false; - m_timeOutMillis = 1000; + m_timeOutMillis = 30000; m_connect_address.s_addr= 0; if(s_port<0) @@ -101,7 +101,7 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) { if(m_connected) { - DBUG_RETURN(true); // TODO assert(0); + DBUG_RETURN(false); // TODO assert(0); } { diff --git a/storage/ndb/src/common/transporter/TransporterRegistry.cpp b/storage/ndb/src/common/transporter/TransporterRegistry.cpp index 5f5f3c17b2d..848738b2983 100644 --- a/storage/ndb/src/common/transporter/TransporterRegistry.cpp +++ b/storage/ndb/src/common/transporter/TransporterRegistry.cpp @@ -758,7 +758,8 @@ TransporterRegistry::poll_TCP(Uint32 timeOutMillis) TCP_Transporter * t = theTCPTransporters[i]; // If the transporter is connected - if (t->isConnected()) { + NodeId nodeId = t->getRemoteNodeId(); + if (is_connected(nodeId) && t->isConnected()) { const NDB_SOCKET_TYPE socket = t->getSocket(); // Find the highest socket value. It will be used by select diff --git a/storage/ndb/src/kernel/blocks/ERROR_codes.txt b/storage/ndb/src/kernel/blocks/ERROR_codes.txt index 4d4d4fcafc4..72791cb0ebc 100644 --- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt @@ -5,7 +5,7 @@ Next DBACC 3002 Next DBTUP 4029 Next DBLQH 5047 Next DBDICT 6008 -Next DBDIH 7193 +Next DBDIH 7195 Next DBTC 8054 Next CMVMI 9000 Next BACKUP 10038 @@ -81,6 +81,11 @@ Delay GCP_SAVEREQ by 10 secs 7185: Dont reply to COPY_GCI_REQ where reason == GCP +7193: Dont send LCP_FRAG_ORD to self, and crash when sending first + LCP_FRAG_ORD(last) + +7194: Force removeNodeFromStored to complete in the middle of MASTER_LCPCONF + ERROR CODES FOR TESTING NODE FAILURE, LOCAL CHECKPOINT HANDLING: ----------------------------------------------------------------- diff --git a/storage/ndb/src/kernel/blocks/backup/Backup.cpp b/storage/ndb/src/kernel/blocks/backup/Backup.cpp index 64e2c41aa69..45501bf50d5 100644 --- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp @@ -1026,8 +1026,9 @@ Backup::execINCL_NODEREQ(Signal* signal) break; }//if }//for - signal->theData[0] = reference(); - sendSignal(senderRef, GSN_INCL_NODECONF, signal, 1, JBB); + signal->theData[0] = inclNode; + signal->theData[1] = reference(); + sendSignal(senderRef, GSN_INCL_NODECONF, signal, 2, JBB); } /***************************************************************************** diff --git a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index 3406176d7a8..6c869435bfa 100644 --- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -421,9 +421,10 @@ void Cmvmi::execCLOSE_COMREQ(Signal* signal) // Uint32 noOfNodes = closeCom->noOfNodes; jamEntry(); - for (unsigned i = 0; i < MAX_NODES; i++){ - if(NodeBitmask::get(closeCom->theNodes, i)){ - + for (unsigned i = 0; i < MAX_NODES; i++) + { + if(NodeBitmask::get(closeCom->theNodes, i)) + { jam(); //----------------------------------------------------- @@ -437,7 +438,9 @@ void Cmvmi::execCLOSE_COMREQ(Signal* signal) globalTransporterRegistry.do_disconnect(i); } } - if (failNo != 0) { + + if (failNo != 0) + { jam(); signal->theData[0] = userRef; signal->theData[1] = failNo; @@ -456,13 +459,21 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal) jamEntry(); const Uint32 len = signal->getLength(); - if(len == 2){ - + if(len == 2) + { #ifdef ERROR_INSERT if (! ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002)) && c_error_9000_nodes_mask.get(tStartingNode))) #endif { + if (globalData.theStartLevel != NodeState::SL_STARTED && + (getNodeInfo(tStartingNode).m_type != NodeInfo::DB && + getNodeInfo(tStartingNode).m_type != NodeInfo::MGM)) + { + jam(); + goto done; + } + globalTransporterRegistry.do_connect(tStartingNode); globalTransporterRegistry.setIOState(tStartingNode, HaltIO); @@ -475,9 +486,11 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal) //----------------------------------------------------- } } else { - for(unsigned int i = 1; i < MAX_NODES; i++ ) { + for(unsigned int i = 1; i < MAX_NODES; i++ ) + { jam(); - if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2){ + if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2) + { jam(); #ifdef ERROR_INSERT @@ -496,6 +509,7 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal) } } +done: if (userRef != 0) { jam(); signal->theData[0] = tStartingNode; @@ -536,24 +550,10 @@ void Cmvmi::execDISCONNECT_REP(Signal *signal) setNodeInfo(hostId).m_connectCount++; const NodeInfo::NodeType type = getNodeInfo(hostId).getType(); ndbrequire(type != NodeInfo::INVALID); - - if(type == NodeInfo::DB || globalData.theStartLevel == NodeState::SL_STARTED){ - jam(); - DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0]; - rep->nodeId = hostId; - rep->err = errNo; - sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal, - DisconnectRep::SignalLength, JBA); - } else if((globalData.theStartLevel == NodeState::SL_CMVMI || - globalData.theStartLevel == NodeState::SL_STARTING) - && type == NodeInfo::MGM) { - /** - * Someone disconnected during cmvmi period - */ - jam(); - globalTransporterRegistry.do_connect(hostId); - } + sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal, + DisconnectRep::SignalLength, JBA); + cancelSubscription(hostId); signal->theData[0] = NDB_LE_Disconnected; @@ -587,6 +587,8 @@ void Cmvmi::execCONNECT_REP(Signal *signal){ */ if(type == NodeInfo::MGM){ jam(); + signal->theData[0] = hostId; + sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA); } else { /** * Dont allow api nodes to connect @@ -802,6 +804,8 @@ Cmvmi::execSTART_ORD(Signal* signal) { } } } + + EXECUTE_DIRECT(QMGR, GSN_START_ORD, signal, 1); return ; } @@ -829,9 +833,6 @@ Cmvmi::execSTART_ORD(Signal* signal) { * * Do Restart */ - - globalScheduler.clear(); - globalTimeQueue.clear(); // Disconnect all nodes as part of the system restart. // We need to ensure that we are starting up diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 569958a6aa9..7ced078144a 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -3825,8 +3825,9 @@ void Dbdict::execINCL_NODEREQ(Signal* signal) c_nodes.getPtr(nodePtr); ndbrequire(nodePtr.p->nodeState == NodeRecord::NDB_NODE_DEAD); nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE; - signal->theData[0] = reference(); - sendSignal(retRef, GSN_INCL_NODECONF, signal, 1, JBB); + signal->theData[0] = nodePtr.i; + signal->theData[1] = reference(); + sendSignal(retRef, GSN_INCL_NODECONF, signal, 2, JBB); c_aliveNodes.set(nodePtr.i); }//execINCL_NODEREQ() diff --git a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp index 21826df28f9..b0bbdefff55 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp +++ b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp @@ -1310,7 +1310,17 @@ private: LcpStatus lcpStatus; Uint32 lcpStatusUpdatedPlace; + struct Save { + LcpStatus m_status; + Uint32 m_place; + } m_saveState[10]; + void setLcpStatus(LcpStatus status, Uint32 line){ + for (Uint32 i = 9; i > 0; i--) + m_saveState[i] = m_saveState[i-1]; + m_saveState[0].m_status = lcpStatus; + m_saveState[0].m_place = lcpStatusUpdatedPlace; + lcpStatus = status; lcpStatusUpdatedPlace = line; } diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index 5403ac5cc38..bbacb300089 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -2135,12 +2135,9 @@ void Dbdih::gcpBlockedLab(Signal* signal) /*---------------------------------------------------------------------------*/ void Dbdih::execINCL_NODECONF(Signal* signal) { - Uint32 TsendNodeId; - Uint32 TstartNode_or_blockref; - jamEntry(); - TstartNode_or_blockref = signal->theData[0]; - TsendNodeId = signal->theData[1]; + Uint32 TstartNode = signal->theData[0]; + Uint32 TsendNodeId_or_blockref = signal->theData[1]; Uint32 blocklist[6]; blocklist[0] = clocallqhblockref; @@ -2152,9 +2149,21 @@ void Dbdih::execINCL_NODECONF(Signal* signal) for (Uint32 i = 0; blocklist[i] != 0; i++) { - if (TstartNode_or_blockref == blocklist[i]) + if (TsendNodeId_or_blockref == blocklist[i]) { jam(); + + if (TstartNode != c_nodeStartSlave.nodeId) + { + jam(); + warningEvent("Recevied INCL_NODECONF for %u from %s" + " while %u is starting", + TstartNode, + getBlockName(refToBlock(TsendNodeId_or_blockref)), + c_nodeStartSlave.nodeId); + return; + } + if (getNodeStatus(c_nodeStartSlave.nodeId) == NodeRecord::ALIVE && blocklist[i+1] != 0) { @@ -2182,10 +2191,21 @@ void Dbdih::execINCL_NODECONF(Signal* signal) } } } + + if (c_nodeStartMaster.startNode != TstartNode) + { + jam(); + warningEvent("Recevied INCL_NODECONF for %u from %u" + " while %u is starting", + TstartNode, + TsendNodeId_or_blockref, + c_nodeStartMaster.startNode); + return; + } ndbrequire(cmasterdihref = reference()); - receiveLoopMacro(INCL_NODEREQ, TsendNodeId); - + receiveLoopMacro(INCL_NODEREQ, TsendNodeId_or_blockref); + CRASH_INSERTION(7128); /*-------------------------------------------------------------------------*/ // Now that we have included the starting node in the node lists in the @@ -5181,11 +5201,19 @@ void Dbdih::startRemoveFailedNode(Signal* signal, NodeRecordPtr failedNodePtr) } jam(); - signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE; - signal->theData[1] = failedNodePtr.i; - signal->theData[2] = 0; // Tab id - sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB); - + + if (!ERROR_INSERTED(7194)) + { + signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE; + signal->theData[1] = failedNodePtr.i; + signal->theData[2] = 0; // Tab id + sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB); + } + else + { + ndbout_c("7194 Not starting ZREMOVE_NODE_FROM_TABLE"); + } + setLocalNodefailHandling(signal, failedNodePtr.i, NF_REMOVE_NODE_FROM_TABLE); }//Dbdih::startRemoveFailedNode() @@ -6114,12 +6142,22 @@ Dbdih::checkEmptyLcpComplete(Signal *signal){ signal->theData[0] = 7012; execDUMP_STATE_ORD(signal); + + if (ERROR_INSERTED(7194)) + { + ndbout_c("7194 starting ZREMOVE_NODE_FROM_TABLE"); + signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE; + signal->theData[1] = c_lcpMasterTakeOverState.failedNodeId; + signal->theData[2] = 0; // Tab id + sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB); + } c_lcpMasterTakeOverState.set(LMTOS_INITIAL, __LINE__); MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0]; req->masterRef = reference(); req->failedNodeId = c_lcpMasterTakeOverState.failedNodeId; sendLoopMacro(MASTER_LCPREQ, sendMASTER_LCPREQ); + } else { sendMASTER_LCPCONF(signal); } @@ -6141,7 +6179,7 @@ void Dbdih::execMASTER_LCPREQ(Signal* signal) jam(); ndbout_c("resending GSN_MASTER_LCPREQ"); sendSignalWithDelay(reference(), GSN_MASTER_LCPREQ, signal, - signal->getLength(), 50); + 50, signal->getLength()); return; } Uint32 failedNodeId = req->failedNodeId; @@ -6432,6 +6470,15 @@ void Dbdih::execMASTER_LCPCONF(Signal* signal) { const MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0]; jamEntry(); + + if (ERROR_INSERTED(7194)) + { + ndbout_c("delaying MASTER_LCPCONF due to error 7194"); + sendSignalWithDelay(reference(), GSN_MASTER_LCPCONF, signal, + 300, signal->getLength()); + return; + } + Uint32 senderNodeId = conf->senderNodeId; MasterLCPConf::State lcpState = (MasterLCPConf::State)conf->lcpState; const Uint32 failedNodeId = conf->failedNodeId; @@ -6566,7 +6613,6 @@ void Dbdih::MASTER_LCPhandling(Signal* signal, Uint32 failedNodeId) #endif c_lcpState.keepGci = SYSFILE->keepGCI; - c_lcpState.setLcpStatus(LCP_START_LCP_ROUND, __LINE__); startLcpRoundLoopLab(signal, 0, 0); break; } @@ -10538,6 +10584,8 @@ void Dbdih::sendLastLCP_FRAG_ORD(Signal* signal) if(ERROR_INSERTED(7075)){ continue; } + + CRASH_INSERTION(7193); BlockReference ref = calcLqhBlockRef(nodePtr.i); sendSignal(ref, GSN_LCP_FRAG_ORD, signal,LcpFragOrd::SignalLength, JBB); } @@ -10650,6 +10698,12 @@ void Dbdih::execLCP_FRAG_REP(Signal* signal) Uint32 started = lcpReport->maxGciStarted; Uint32 completed = lcpReport->maxGciCompleted; + if (started > c_lcpState.lcpStopGcp) + { + jam(); + c_lcpState.lcpStopGcp = started; + } + if(tableDone){ jam(); @@ -10765,6 +10819,13 @@ Dbdih::checkLcpAllTablesDoneInLqh(){ CRASH_INSERTION2(7017, !isMaster()); c_lcpState.setLcpStatus(LCP_TAB_COMPLETED, __LINE__); + + if (ERROR_INSERTED(7194)) + { + ndbout_c("CLEARING 7194"); + CLEAR_ERROR_INSERT_VALUE; + } + return true; } @@ -10954,6 +11015,11 @@ Dbdih::sendLCP_FRAG_ORD(Signal* signal, BlockReference ref = calcLqhBlockRef(replicaPtr.p->procNode); + if (ERROR_INSERTED(7193) && replicaPtr.p->procNode == getOwnNodeId()) + { + return; + } + LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0]; lcpFragOrd->tableId = info.tableId; lcpFragOrd->fragmentId = info.fragId; @@ -11178,7 +11244,12 @@ void Dbdih::allNodesLcpCompletedLab(Signal* signal) signal->theData[0] = NDB_LE_LocalCheckpointCompleted; //Event type signal->theData[1] = SYSFILE->latestLCP_ID; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); - c_lcpState.lcpStopGcp = c_newest_restorable_gci; + + if (c_newest_restorable_gci > c_lcpState.lcpStopGcp) + { + jam(); + c_lcpState.lcpStopGcp = c_newest_restorable_gci; + } /** * Start checking for next LCP @@ -12048,13 +12119,12 @@ void Dbdih::findMinGci(ReplicaRecordPtr fmgReplicaPtr, lcpNo = fmgReplicaPtr.p->nextLcp; do { ndbrequire(lcpNo < MAX_LCP_STORED); - if (fmgReplicaPtr.p->lcpStatus[lcpNo] == ZVALID && - fmgReplicaPtr.p->maxGciStarted[lcpNo] < c_newest_restorable_gci) + if (fmgReplicaPtr.p->lcpStatus[lcpNo] == ZVALID) { jam(); keepGci = fmgReplicaPtr.p->maxGciCompleted[lcpNo]; oldestRestorableGci = fmgReplicaPtr.p->maxGciStarted[lcpNo]; - ndbrequire(((int)oldestRestorableGci) >= 0); + ndbassert(fmgReplicaPtr.p->maxGciStarted[lcpNo] c_lcp_waiting_fragments; // StartFragReq'ed DLFifoList c_lcp_restoring_fragments; // Restoring as we speek DLFifoList c_lcp_complete_fragments; // Restored - DLFifoList c_redo_complete_fragments; // Redo'ed /* ------------------------------------------------------------------------- */ /*USED DURING SYSTEM RESTART, INDICATES THE OLDEST GCI THAT CAN BE RESTARTED */ diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp index db6d201575f..b3a3d512da7 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp @@ -168,7 +168,6 @@ Dblqh::Dblqh(Block_context& ctx): c_lcp_waiting_fragments(c_fragment_pool), c_lcp_restoring_fragments(c_fragment_pool), c_lcp_complete_fragments(c_fragment_pool), - c_redo_complete_fragments(c_fragment_pool), m_commitAckMarkerHash(m_commitAckMarkerPool), c_scanTakeOverHash(c_scanRecordPool) { @@ -295,9 +294,6 @@ Dblqh::Dblqh(Block_context& ctx): addRecSignal(GSN_READ_PSEUDO_REQ, &Dblqh::execREAD_PSEUDO_REQ); - addRecSignal(GSN_BUILDINDXREF, &Dblqh::execBUILDINDXREF); - addRecSignal(GSN_BUILDINDXCONF, &Dblqh::execBUILDINDXCONF); - addRecSignal(GSN_DEFINE_BACKUP_REF, &Dblqh::execDEFINE_BACKUP_REF); addRecSignal(GSN_DEFINE_BACKUP_CONF, &Dblqh::execDEFINE_BACKUP_CONF); diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index e0449e08ddd..83d38595c1f 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -356,7 +356,6 @@ void Dblqh::execCONTINUEB(Signal* signal) break; case ZSR_PHASE3_START: jam(); - signal->theData[0] = data0; srPhase3Start(signal); return; break; @@ -428,25 +427,25 @@ void Dblqh::execCONTINUEB(Signal* signal) if (fragptr.i != RNIL) { jam(); - c_redo_complete_fragments.getPtr(fragptr); + c_lcp_complete_fragments.getPtr(fragptr); signal->theData[0] = fragptr.p->tabRef; signal->theData[1] = fragptr.p->fragId; sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB); Ptr save = fragptr; - c_redo_complete_fragments.next(fragptr); + c_lcp_complete_fragments.next(fragptr); signal->theData[0] = ZENABLE_EXPAND_CHECK; signal->theData[1] = fragptr.i; sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 2, JBB); - c_redo_complete_fragments.remove(save); + c_lcp_complete_fragments.remove(save); return; } else { jam(); cstartRecReq = 2; - ndbrequire(c_redo_complete_fragments.isEmpty()); + ndbrequire(c_lcp_complete_fragments.isEmpty()); StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend(); conf->startingNodeId = getOwnNodeId(); sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal, @@ -495,8 +494,9 @@ void Dblqh::execINCL_NODEREQ(Signal* signal) cnodeStatus[i] = ZNODE_UP; }//if }//for - signal->theData[0] = cownref; - sendSignal(retRef, GSN_INCL_NODECONF, signal, 1, JBB); + signal->theData[0] = nodeId; + signal->theData[1] = cownref; + sendSignal(retRef, GSN_INCL_NODECONF, signal, 2, JBB); return; }//Dblqh::execINCL_NODEREQ() @@ -1121,7 +1121,6 @@ void Dblqh::execLQHFRAGREQ(Signal* signal) Uint32 minRowsHigh = req->minRowsHigh; Uint32 tschemaVersion = req->schemaVersion; Uint32 ttupKeyLength = req->keyLength; - Uint32 nextLcp = req->nextLCP; Uint32 noOfKeyAttr = req->noOfKeyAttr; Uint32 noOfCharsets = req->noOfCharsets; Uint32 checksumIndicator = req->checksumIndicator; @@ -1214,7 +1213,6 @@ void Dblqh::execLQHFRAGREQ(Signal* signal) fragptr.p->lcpFlag = Fragrecord::LCP_STATE_FALSE; }//if - fragptr.p->nextLcp = nextLcp; //---------------------------------------------- // For node restarts it is not necessarily zero //---------------------------------------------- @@ -8939,6 +8937,9 @@ void Dblqh::storedProcConfScanLab(Signal* signal) case Fragrecord::REMOVING: jam(); default: + jamLine(fragptr.p->fragStatus); + ndbout_c("fragptr.p->fragStatus: %u", + fragptr.p->fragStatus); ndbrequire(false); break; }//switch @@ -14141,15 +14142,12 @@ void Dblqh::execSTART_FRAGREQ(Signal* signal) if (lcpNo == (MAX_LCP_STORED - 1)) { jam(); fragptr.p->lcpId[lcpNo] = lcpId; - fragptr.p->nextLcp = 0; } else if (lcpNo < (MAX_LCP_STORED - 1)) { jam(); fragptr.p->lcpId[lcpNo] = lcpId; - fragptr.p->nextLcp = lcpNo + 1; } else { ndbrequire(lcpNo == ZNIL); jam(); - fragptr.p->nextLcp = 0; }//if fragptr.p->srNoLognodes = noOfLogNodes; fragptr.p->logFlag = Fragrecord::STATE_FALSE; @@ -14181,19 +14179,9 @@ void Dblqh::execSTART_FRAGREQ(Signal* signal) */ c_lcp_complete_fragments.add(fragptr); - if(lcpNo == ZNIL) - { - signal->theData[0] = tabptr.i; - signal->theData[1] = fragId; - sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB); - } - - if (getNodeState().getNodeRestartInProgress()) - { - jam(); - fragptr.p->fragStatus = Fragrecord::ACTIVE_CREATION; - } - + signal->theData[0] = tabptr.i; + signal->theData[1] = fragId; + sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB); c_tup->disk_restart_lcp_id(tabptr.i, fragId, RNIL); jamEntry(); return; @@ -14395,65 +14383,9 @@ void Dblqh::execSTART_RECCONF(Signal* signal) return; } - c_lcp_complete_fragments.first(fragptr); - build_acc(signal, fragptr.i); - return; -}//Dblqh::execSTART_RECCONF() - -void -Dblqh::build_acc(Signal* signal, Uint32 fragPtrI) -{ - fragptr.i = fragPtrI; - while(fragptr.i != RNIL) - { - c_lcp_complete_fragments.getPtr(fragptr); - tabptr.i = fragptr.p->tabRef; - ptrCheckGuard(tabptr, ctabrecFileSize, tablerec); - - if(true || fragptr.i != tabptr.p->fragrec[0]) - { - // Only need to send 1 build per table, TUP will rebuild all - fragptr.i = fragptr.p->nextList; - continue; - } - - BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend(); - req->setUserRef(reference()); - req->setConnectionPtr(fragptr.i); - req->setRequestType(BuildIndxReq::RT_SYSTEMRESTART); - req->setBuildId(0); // not used - req->setBuildKey(0); // not used - req->setIndexType(RNIL); - req->setIndexId(RNIL); - req->setTableId(tabptr.i); - req->setParallelism(0); - - sendSignal(DBTUP_REF, GSN_BUILDINDXREQ, signal, - BuildIndxReq::SignalLength, JBB); - return; - } - startExecSr(signal); } -void -Dblqh::execBUILDINDXREF(Signal* signal) -{ - ndbrequire(false); -} - -void -Dblqh::execBUILDINDXCONF(Signal* signal) -{ - BuildIndxConf* conf = (BuildIndxConf*)signal->getDataPtrSend(); - Uint32 fragPtrI = conf->getConnectionPtr(); - - fragptr.i = fragPtrI; - c_fragment_pool.getPtr(fragptr); - infoEvent("LQH: primary key index %u rebuild done", fragptr.p->tabRef); - build_acc(signal, fragptr.p->nextList); -} - /* ***************> */ /* START_RECREF > */ /* ***************> */ @@ -14472,9 +14404,9 @@ void Dblqh::execSTART_EXEC_SR(Signal* signal) fragptr.i = signal->theData[0]; Uint32 next = RNIL; - if (fragptr.i == RNIL) { + if (fragptr.i == RNIL) + { jam(); - ndbrequire(cnoOfNodes < MAX_NDB_NODES); /* ---------------------------------------------------------------------- * NO MORE FRAGMENTS TO START EXECUTING THE LOG ON. * SEND EXEC_SRREQ TO ALL LQH TO INDICATE THAT THIS NODE WILL @@ -14490,10 +14422,15 @@ void Dblqh::execSTART_EXEC_SR(Signal* signal) } else { jam(); c_lcp_complete_fragments.getPtr(fragptr); - if (fragptr.p->srNoLognodes > csrPhasesCompleted) { + next = fragptr.p->nextList; + + if (fragptr.p->srNoLognodes > csrPhasesCompleted) + { jam(); + cnoOutstandingExecFragReq++; + Uint32 index = csrPhasesCompleted; - arrGuard(index, 4); + arrGuard(index, MAX_LOG_EXEC); BlockReference ref = calcLqhBlockRef(fragptr.p->srLqhLognode[index]); fragptr.p->srStatus = Fragrecord::SS_STARTED; @@ -14512,34 +14449,7 @@ void Dblqh::execSTART_EXEC_SR(Signal* signal) sendSignal(ref, GSN_EXEC_FRAGREQ, signal, ExecFragReq::SignalLength, JBB); - next = fragptr.p->nextList; - } else { - jam(); - /* -------------------------------------------------------------------- - * THIS FRAGMENT IS NOW FINISHED WITH THE SYSTEM RESTART. IT DOES - * NOT NEED TO PARTICIPATE IN ANY MORE PHASES. REMOVE IT FROM THE - * LIST OF COMPLETED FRAGMENTS TO EXECUTE THE LOG ON. - * ALSO SEND START_FRAGCONF TO DIH AND SET THE STATE TO ACTIVE ON THE - * FRAGMENT. - * ------------------------------------------------------------------- */ - next = fragptr.p->nextList; - c_lcp_complete_fragments.remove(fragptr); - c_redo_complete_fragments.add(fragptr); - - if (!getNodeState().getNodeRestartInProgress()) - { - fragptr.p->logFlag = Fragrecord::STATE_TRUE; - fragptr.p->fragStatus = Fragrecord::FSACTIVE; - } - else - { - fragptr.p->fragStatus = Fragrecord::ACTIVE_CREATION; - } - signal->theData[0] = fragptr.p->srUserptr; - signal->theData[1] = cownNodeid; - sendSignal(fragptr.p->srBlockref, GSN_START_FRAGCONF, signal, 2, JBB); - - } //if + } signal->theData[0] = next; sendSignal(cownref, GSN_START_EXEC_SR, signal, 1, JBB); }//if @@ -14560,24 +14470,8 @@ void Dblqh::execEXEC_FRAGREQ(Signal* signal) tabptr.i = execFragReq->tableId; Uint32 fragId = execFragReq->fragId; ptrCheckGuard(tabptr, ctabrecFileSize, tablerec); - if (!getFragmentrec(signal, fragId)) { - jam(); - if (!insertFragrec(signal, fragId)) { - jam(); - sendExecFragRefLab(signal); - return; - }//if - initFragrec(signal, tabptr.i, fragId, ZLOG_NODE); - fragptr.p->execSrStatus = Fragrecord::ACTIVE_REMOVE_AFTER; - } else { - jam(); - if (fragptr.p->execSrStatus == Fragrecord::ACTIVE_REMOVE_AFTER) { - jam(); - fragptr.p->execSrStatus = Fragrecord::ACTIVE_REMOVE_AFTER; - } else { - jam(); - }//if - }//if + ndbrequire(getFragmentrec(signal, fragId)); + ndbrequire(fragptr.p->execSrNoReplicas < 4); fragptr.p->execSrBlockref[fragptr.p->execSrNoReplicas] = execFragReq->userRef; fragptr.p->execSrUserptr[fragptr.p->execSrNoReplicas] = execFragReq->userPtr; @@ -14610,6 +14504,21 @@ void Dblqh::execEXEC_FRAGCONF(Signal* signal) fragptr.i = signal->theData[0]; c_fragment_pool.getPtr(fragptr); fragptr.p->srStatus = Fragrecord::SS_COMPLETED; + + ndbrequire(cnoOutstandingExecFragReq); + cnoOutstandingExecFragReq--; + if (fragptr.p->srNoLognodes == csrPhasesCompleted + 1) + { + jam(); + + fragptr.p->logFlag = Fragrecord::STATE_TRUE; + fragptr.p->fragStatus = Fragrecord::FSACTIVE; + + signal->theData[0] = fragptr.p->srUserptr; + signal->theData[1] = cownNodeid; + sendSignal(fragptr.p->srBlockref, GSN_START_FRAGCONF, signal, 2, JBB); + } + return; }//Dblqh::execEXEC_FRAGCONF() @@ -14633,6 +14542,7 @@ void Dblqh::execEXEC_SRCONF(Signal* signal) Uint32 nodeId = signal->theData[0]; arrGuard(nodeId, MAX_NDB_NODES); m_sr_exec_sr_conf.set(nodeId); + if (!m_sr_nodes.equal(m_sr_exec_sr_conf)) { jam(); @@ -14653,16 +14563,8 @@ void Dblqh::execEXEC_SRCONF(Signal* signal) * NOW CHECK IF ALL FRAGMENTS IN THIS PHASE HAVE COMPLETED. IF SO START THE * NEXT PHASE. * ----------------------------------------------------------------------- */ - c_lcp_complete_fragments.first(fragptr); - while (fragptr.i != RNIL) - { - jam(); - if(fragptr.p->srStatus != Fragrecord::SS_COMPLETED) - { - return; - } - c_lcp_complete_fragments.next(fragptr); - } + ndbrequire(cnoOutstandingExecFragReq == 0); + execSrCompletedLab(signal); return; }//Dblqh::execEXEC_SRCONF() @@ -14718,6 +14620,7 @@ void Dblqh::execSrCompletedLab(Signal* signal) * THERE ARE YET MORE PHASES TO RESTART. * WE MUST INITIALISE DATA FOR NEXT PHASE AND SEND START SIGNAL. * --------------------------------------------------------------------- */ + csrPhaseStarted = ZSR_PHASE1_COMPLETED; // Set correct state first... startExecSr(signal); }//if return; @@ -14791,7 +14694,8 @@ void Dblqh::srPhase3Start(Signal* signal) UintR tsrPhaseStarted; jamEntry(); - tsrPhaseStarted = signal->theData[0]; + + tsrPhaseStarted = signal->theData[1]; if (csrPhaseStarted == ZSR_NO_PHASE_STARTED) { jam(); csrPhaseStarted = tsrPhaseStarted; @@ -15968,18 +15872,6 @@ void Dblqh::sendExecConf(Signal* signal) sendSignal(fragptr.p->execSrBlockref[i], GSN_EXEC_FRAGCONF, signal, 1, JBB); }//for - if (fragptr.p->execSrStatus == Fragrecord::ACTIVE) { - jam(); - fragptr.p->execSrStatus = Fragrecord::IDLE; - } else { - ndbrequire(fragptr.p->execSrStatus == Fragrecord::ACTIVE_REMOVE_AFTER); - jam(); - Uint32 fragId = fragptr.p->fragId; - tabptr.i = fragptr.p->tabRef; - ptrCheckGuard(tabptr, ctabrecFileSize, tablerec); - c_lcp_complete_fragments.remove(fragptr); - deleteFragrec(fragId); - }//if fragptr.p->execSrNoReplicas = 0; }//if loopCount++; @@ -16007,17 +15899,10 @@ void Dblqh::sendExecConf(Signal* signal) void Dblqh::srPhase3Comp(Signal* signal) { jamEntry(); - ndbrequire(cnoOfNodes < MAX_NDB_NODES); - for (Uint32 i = 0; i < cnoOfNodes; i++) { - jam(); - if (cnodeStatus[i] == ZNODE_UP) { - jam(); - ndbrequire(cnodeData[i] < MAX_NDB_NODES); - BlockReference ref = calcLqhBlockRef(cnodeData[i]); - signal->theData[0] = cownNodeid; - sendSignal(ref, GSN_EXEC_SRCONF, signal, 1, JBB); - }//if - }//for + + signal->theData[0] = cownNodeid; + NodeReceiverGroup rg(DBLQH, m_sr_nodes); + sendSignal(rg, GSN_EXEC_SRCONF, signal, 1, JBB); return; }//Dblqh::srPhase3Comp() @@ -16259,7 +16144,7 @@ void Dblqh::srFourthComp(Signal* signal) if(cstartType == NodeState::ST_SYSTEM_RESTART) { jam(); - if (c_redo_complete_fragments.first(fragptr)) + if (c_lcp_complete_fragments.first(fragptr)) { jam(); signal->theData[0] = ZENABLE_EXPAND_CHECK; @@ -17367,7 +17252,6 @@ void Dblqh::initFragrec(Signal* signal, fragptr.p->maxGciInLcp = 0; fragptr.p->copyFragState = ZIDLE; fragptr.p->newestGci = cnewestGci; - fragptr.p->nextLcp = 0; fragptr.p->tabRef = tableId; fragptr.p->fragId = fragId; fragptr.p->srStatus = Fragrecord::SS_IDLE; @@ -18456,6 +18340,7 @@ void Dblqh::sendLqhTransconf(Signal* signal, LqhTransConf::OperationStatus stat) void Dblqh::startExecSr(Signal* signal) { cnoFragmentsExecSr = 0; + cnoOutstandingExecFragReq = 0; c_lcp_complete_fragments.first(fragptr); signal->theData[0] = fragptr.i; sendSignal(cownref, GSN_START_EXEC_SR, signal, 1, JBB); diff --git a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index 3d5e52a525d..4c5c6420d56 100644 --- a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -734,6 +734,7 @@ public: // Index op return context UintR indexOp; UintR clientData; + Uint32 errorData; UintR attrInfoLen; UintR accumulatingIndexOp; diff --git a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index ce20059e663..e54f163b2e4 100644 --- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -310,9 +310,11 @@ void Dbtc::execINCL_NODEREQ(Signal* signal) hostptr.i = signal->theData[1]; ptrCheckGuard(hostptr, chostFilesize, hostRecord); hostptr.p->hostStatus = HS_ALIVE; - signal->theData[0] = cownref; c_alive_nodes.set(hostptr.i); + signal->theData[0] = hostptr.i; + signal->theData[1] = cownref; + if (ERROR_INSERTED(8039)) { CLEAR_ERROR_INSERT_VALUE; @@ -321,11 +323,11 @@ void Dbtc::execINCL_NODEREQ(Signal* signal) sendSignal(numberToRef(CMVMI, hostptr.i), GSN_NDB_TAMPER, signal, 1, JBB); signal->theData[0] = save; - sendSignalWithDelay(tblockref, GSN_INCL_NODECONF, signal, 5000, 1); + sendSignalWithDelay(tblockref, GSN_INCL_NODECONF, signal, 5000, 2); return; } - sendSignal(tblockref, GSN_INCL_NODECONF, signal, 1, JBB); + sendSignal(tblockref, GSN_INCL_NODECONF, signal, 2, JBB); } void Dbtc::execREAD_NODESREF(Signal* signal) @@ -5117,6 +5119,7 @@ void Dbtc::releaseDirtyWrite(Signal* signal) void Dbtc::execLQHKEYREF(Signal* signal) { const LqhKeyRef * const lqhKeyRef = (LqhKeyRef *)signal->getDataPtr(); + Uint32 indexId = 0; jamEntry(); UintR compare_transid1, compare_transid2; @@ -5168,6 +5171,9 @@ void Dbtc::execLQHKEYREF(Signal* signal) ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord); // The operation executed an index trigger + TcIndexData* indexData = c_theIndexes.getPtr(currentIndexId); + indexId = indexData->indexId; + regApiPtr->errorData = indexId; const Uint32 opType = regTcPtr->operation; if (errCode == ZALREADYEXIST) errCode = terrorCode = ZNOTUNIQUE; @@ -5180,7 +5186,6 @@ void Dbtc::execLQHKEYREF(Signal* signal) } else { jam(); /** ZDELETE && NOT_FOUND */ - TcIndexData* indexData = c_theIndexes.getPtr(currentIndexId); if(indexData->indexState == IS_BUILDING && state != CS_ABORTING){ jam(); /** @@ -5265,12 +5270,14 @@ void Dbtc::execLQHKEYREF(Signal* signal) jam(); regApiPtr->lqhkeyreqrec--; // Compensate for extra during read tcKeyRef->connectPtr = indexOp; + tcKeyRef->errorData = indexId; EXECUTE_DIRECT(DBTC, GSN_TCKEYREF, signal, TcKeyRef::SignalLength); apiConnectptr.i = save; apiConnectptr.p = regApiPtr; } else { jam(); tcKeyRef->connectPtr = clientData; + tcKeyRef->errorData = indexId; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCKEYREF, signal, TcKeyRef::SignalLength, JBB); }//if @@ -10571,6 +10578,7 @@ void Dbtc::releaseAbortResources(Signal* signal) tcRollbackRep->transId[0] = apiConnectptr.p->transid[0]; tcRollbackRep->transId[1] = apiConnectptr.p->transid[1]; tcRollbackRep->returnCode = apiConnectptr.p->returncode; + tcRollbackRep->errorData = apiConnectptr.p->errorData; sendSignal(blockRef, GSN_TCROLLBACKREP, signal, TcRollbackRep::SignalLength, JBB); } @@ -11995,6 +12003,7 @@ void Dbtc::execTCKEYCONF(Signal* signal) tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; + tcIndxRef->errorData = 0; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB); return; @@ -12014,6 +12023,7 @@ void Dbtc::execTCKEYCONF(Signal* signal) tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; + tcIndxRef->errorData = 0; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB); return; @@ -12097,6 +12107,7 @@ void Dbtc::execTCKEYREF(Signal* signal) tcIndxRef->transId[0] = tcKeyRef->transId[0]; tcIndxRef->transId[1] = tcKeyRef->transId[1]; tcIndxRef->errorCode = tcKeyRef->errorCode; + tcIndxRef->errorData = 0; releaseIndexOperation(regApiPtr, indexOp); @@ -12174,6 +12185,7 @@ void Dbtc::execTRANSID_AI(Signal* signal) tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4000; + tcIndxRef->errorData = 0; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB); return; @@ -12189,6 +12201,7 @@ void Dbtc::execTRANSID_AI(Signal* signal) tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; + tcIndxRef->errorData = 0; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB); return; @@ -12217,6 +12230,7 @@ void Dbtc::execTRANSID_AI(Signal* signal) tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; + tcIndxRef->errorData = 0; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB); */ @@ -12242,6 +12256,7 @@ void Dbtc::execTRANSID_AI(Signal* signal) tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; + tcIndxRef->errorData = regApiPtr->errorData; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB); return; @@ -12295,6 +12310,7 @@ void Dbtc::readIndexTable(Signal* signal, tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4000; + // tcIndxRef->errorData = ??; Where to find indexId sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB); return; @@ -12441,6 +12457,7 @@ void Dbtc::executeIndexOperation(Signal* signal, tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; + tcIndxRef->errorData = 0; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB); return; diff --git a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp index 8d51b24ec6a..6a76ce5217a 100644 --- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp +++ b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp @@ -265,6 +265,8 @@ private: void execALLOC_NODEID_CONF(Signal *); void execALLOC_NODEID_REF(Signal *); void completeAllocNodeIdReq(Signal *); + + void execSTART_ORD(Signal*); // Arbitration signals void execARBIT_CFG(Signal* signal); @@ -281,6 +283,7 @@ private: void check_readnodes_reply(Signal* signal, Uint32 nodeId, Uint32 gsn); Uint32 check_startup(Signal* signal); + void api_failed(Signal* signal, Uint32 aFailedNode); void node_failed(Signal* signal, Uint16 aFailedNode); void checkStartInterface(Signal* signal); void failReport(Signal* signal, diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp index f9950072ab4..2f03bd56694 100644 --- a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp +++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp @@ -31,10 +31,6 @@ void Qmgr::initData() cnoCommitFailedNodes = 0; c_maxDynamicId = 0; c_clusterNodes.clear(); - - Uint32 hbDBAPI = 500; - setHbApiDelay(hbDBAPI); - c_connectedNodes.set(getOwnNodeId()); c_stopReq.senderRef = 0; /** @@ -43,6 +39,27 @@ void Qmgr::initData() ndbrequire((Uint32)NodeInfo::DB == 0); ndbrequire((Uint32)NodeInfo::API == 1); ndbrequire((Uint32)NodeInfo::MGM == 2); + + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrAss(nodePtr, nodeRec); + nodePtr.p->blockRef = reference(); + + c_connectedNodes.set(getOwnNodeId()); + setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION; + + + /** + * Timeouts + */ + const ndb_mgm_configuration_iterator * p = + m_ctx.m_config.getOwnConfigIterator(); + ndbrequire(p != 0); + + Uint32 hbDBAPI = 1500; + ndb_mgm_get_int_parameter(p, CFG_DB_API_HEARTBEAT_INTERVAL, &hbDBAPI); + + setHbApiDelay(hbDBAPI); }//Qmgr::initData() void Qmgr::initRecords() @@ -113,6 +130,7 @@ Qmgr::Qmgr(Block_context& ctx) addRecSignal(GSN_DIH_RESTARTREF, &Qmgr::execDIH_RESTARTREF); addRecSignal(GSN_DIH_RESTARTCONF, &Qmgr::execDIH_RESTARTCONF); addRecSignal(GSN_NODE_VERSION_REP, &Qmgr::execNODE_VERSION_REP); + addRecSignal(GSN_START_ORD, &Qmgr::execSTART_ORD); initData(); }//Qmgr::Qmgr() diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp index 1fba4d62e17..23e7829481e 100644 --- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp +++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp @@ -238,6 +238,38 @@ Qmgr::execREAD_CONFIG_REQ(Signal* signal) ReadConfigConf::SignalLength, JBB); } +void +Qmgr::execSTART_ORD(Signal* signal) +{ + /** + * Start timer handling + */ + signal->theData[0] = ZTIMER_HANDLING; + sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 1, JBB); + + NodeRecPtr nodePtr; + for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) + { + ptrAss(nodePtr, nodeRec); + nodePtr.p->ndynamicId = 0; + if(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB) + { + nodePtr.p->phase = ZINIT; + c_definedNodes.set(nodePtr.i); + } else { + nodePtr.p->phase = ZAPI_INACTIVE; + } + + setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0; + nodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE; + nodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE; + nodePtr.p->sendPresToStatus = Q_NOT_ACTIVE; + nodePtr.p->failState = NORMAL; + nodePtr.p->rcv[0] = 0; + nodePtr.p->rcv[1] = 0; + }//for +} + /* 4.2 ADD NODE MODULE*/ /*##########################################################################*/ @@ -298,8 +330,6 @@ void Qmgr::startphase1(Signal* signal) nodePtr.i = getOwnNodeId(); ptrAss(nodePtr, nodeRec); nodePtr.p->phase = ZSTARTING; - nodePtr.p->blockRef = reference(); - c_connectedNodes.set(nodePtr.i); signal->theData[0] = reference(); sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal, 1, JBB); @@ -371,11 +401,14 @@ void Qmgr::execCONNECT_REP(Signal* signal) case ZFAIL_CLOSING: jam(); return; - case ZINIT: - ndbrequire(false); case ZAPI_ACTIVE: case ZAPI_INACTIVE: return; + case ZINIT: + ndbrequire(getNodeInfo(nodeId).m_type == NodeInfo::MGM); + break; + default: + ndbrequire(false); } if (getNodeInfo(nodeId).getType() != NodeInfo::DB) @@ -1212,12 +1245,6 @@ void Qmgr::execCM_REGREF(Signal* signal) { jam(); electionWon(signal); - - /** - * Start timer handling - */ - signal->theData[0] = ZTIMER_HANDLING; - sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 10, JBB); } return; @@ -1855,12 +1882,6 @@ Qmgr::joinedCluster(Signal* signal, NodeRecPtr nodePtr){ sendSttorryLab(signal); - /** - * Start timer handling - */ - signal->theData[0] = ZTIMER_HANDLING; - sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 10, JBB); - sendCmAckAdd(signal, getOwnNodeId(), CmAdd::CommitNew); } @@ -2094,25 +2115,6 @@ void Qmgr::findNeighbours(Signal* signal) /*---------------------------------------------------------------------------*/ void Qmgr::initData(Signal* signal) { - NodeRecPtr nodePtr; - for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) { - ptrAss(nodePtr, nodeRec); - nodePtr.p->ndynamicId = 0; - if(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB){ - nodePtr.p->phase = ZINIT; - c_definedNodes.set(nodePtr.i); - } else { - nodePtr.p->phase = ZAPI_INACTIVE; - } - - setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0; - nodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE; - nodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE; - nodePtr.p->sendPresToStatus = Q_NOT_ACTIVE; - nodePtr.p->failState = NORMAL; - nodePtr.p->rcv[0] = 0; - nodePtr.p->rcv[1] = 0; - }//for cfailureNr = 1; ccommitFailureNr = 1; cprepareFailureNr = 1; @@ -2146,13 +2148,11 @@ void Qmgr::initData(Signal* signal) ndbrequire(p != 0); Uint32 hbDBDB = 1500; - Uint32 hbDBAPI = 1500; Uint32 arbitTimeout = 1000; c_restartPartialTimeout = 30000; c_restartPartionedTimeout = 60000; c_restartFailureTimeout = ~0; ndb_mgm_get_int_parameter(p, CFG_DB_HEARTBEAT_INTERVAL, &hbDBDB); - ndb_mgm_get_int_parameter(p, CFG_DB_API_HEARTBEAT_INTERVAL, &hbDBAPI); ndb_mgm_get_int_parameter(p, CFG_DB_ARBIT_TIMEOUT, &arbitTimeout); ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTIAL_TIMEOUT, &c_restartPartialTimeout); @@ -2177,7 +2177,6 @@ void Qmgr::initData(Signal* signal) } setHbDelay(hbDBDB); - setHbApiDelay(hbDBAPI); setArbitTimeout(arbitTimeout); arbitRec.state = ARBIT_NULL; // start state for all nodes @@ -2204,7 +2203,6 @@ void Qmgr::initData(Signal* signal) execARBIT_CFG(signal); } - setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION; }//Qmgr::initData() @@ -2237,20 +2235,22 @@ void Qmgr::timerHandlingLab(Signal* signal) hb_check_timer.reset(); } } - + if (interface_check_timer.check(TcurrentTime)) { jam(); interface_check_timer.reset(); checkStartInterface(signal); } + if (hb_api_timer.check(TcurrentTime)) + { + jam(); + hb_api_timer.reset(); + apiHbHandlingLab(signal); + } + if (cactivateApiCheck != 0) { jam(); - if (hb_api_timer.check(TcurrentTime)) { - jam(); - hb_api_timer.reset(); - apiHbHandlingLab(signal); - }//if if (clatestTransactionCheck == 0) { //------------------------------------------------------------- // Initialise the Transaction check timer. @@ -2367,18 +2367,21 @@ void Qmgr::apiHbHandlingLab(Signal* signal) if(type == NodeInfo::INVALID) continue; - if (TnodePtr.p->phase == ZAPI_ACTIVE){ + if (c_connectedNodes.get(nodeId)) + { jam(); setNodeInfo(TnodePtr.i).m_heartbeat_cnt++; - if(getNodeInfo(TnodePtr.i).m_heartbeat_cnt > 2){ + if(getNodeInfo(TnodePtr.i).m_heartbeat_cnt > 2) + { signal->theData[0] = NDB_LE_MissedHeartbeat; signal->theData[1] = nodeId; signal->theData[2] = getNodeInfo(TnodePtr.i).m_heartbeat_cnt - 1; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB); } - if (getNodeInfo(TnodePtr.i).m_heartbeat_cnt > 4) { + if (getNodeInfo(TnodePtr.i).m_heartbeat_cnt > 4) + { jam(); /*------------------------------------------------------------------*/ /* THE API NODE HAS NOT SENT ANY HEARTBEAT FOR THREE SECONDS. @@ -2390,8 +2393,8 @@ void Qmgr::apiHbHandlingLab(Signal* signal) signal->theData[0] = NDB_LE_DeadDueToHeartbeat; signal->theData[1] = nodeId; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); - - node_failed(signal, nodeId); + + api_failed(signal, nodeId); }//if }//if }//for @@ -2480,26 +2483,6 @@ void Qmgr::sendApiFailReq(Signal* signal, Uint16 failedNodeNo) sendSignal(DBTC_REF, GSN_API_FAILREQ, signal, 2, JBA); sendSignal(DBDICT_REF, GSN_API_FAILREQ, signal, 2, JBA); sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA); - - /**------------------------------------------------------------------------- - * THE OTHER NODE WAS AN API NODE. THE COMMUNICATION LINK IS ALREADY - * BROKEN AND THUS NO ACTION IS NEEDED TO BREAK THE CONNECTION. - * WE ONLY NEED TO SET PARAMETERS TO ENABLE A NEW CONNECTION IN A FEW - * SECONDS. - *-------------------------------------------------------------------------*/ - setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0; - setNodeInfo(failedNodePtr.i).m_version = 0; - recompute_version_info(getNodeInfo(failedNodePtr.i).m_type); - - CloseComReqConf * const closeCom = (CloseComReqConf *)&signal->theData[0]; - - closeCom->xxxBlockRef = reference(); - closeCom->failNo = 0; - closeCom->noOfNodes = 1; - NodeBitmask::clear(closeCom->theNodes); - NodeBitmask::set(closeCom->theNodes, failedNodePtr.i); - sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal, - CloseComReqConf::SignalLength, JBA); }//Qmgr::sendApiFailReq() void Qmgr::execAPI_FAILREQ(Signal* signal) @@ -2512,20 +2495,7 @@ void Qmgr::execAPI_FAILREQ(Signal* signal) ndbrequire(getNodeInfo(failedNodePtr.i).getType() != NodeInfo::DB); - // ignore if api not active - if (failedNodePtr.p->phase != ZAPI_ACTIVE) - { - jam(); - // But send to SUMA anyway... - sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA); - return; - } - - signal->theData[0] = NDB_LE_Disconnected; - signal->theData[1] = failedNodePtr.i; - sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); - - node_failed(signal, failedNodePtr.i); + api_failed(signal, signal->theData[0]); } void Qmgr::execAPI_FAILCONF(Signal* signal) @@ -2649,6 +2619,13 @@ void Qmgr::execDISCONNECT_REP(Signal* signal) ndbrequire(false); } + if (getNodeInfo(nodeId).getType() != NodeInfo::DB) + { + jam(); + api_failed(signal, nodeId); + return; + } + switch(nodePtr.p->phase){ case ZRUNNING: jam(); @@ -2685,66 +2662,109 @@ void Qmgr::node_failed(Signal* signal, Uint16 aFailedNode) failedNodePtr.i = aFailedNode; ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec); - if (getNodeInfo(failedNodePtr.i).getType() == NodeInfo::DB){ + ndbrequire(getNodeInfo(failedNodePtr.i).getType() == NodeInfo::DB); + + /**--------------------------------------------------------------------- + * THE OTHER NODE IS AN NDB NODE, WE HANDLE IT AS IF A HEARTBEAT + * FAILURE WAS DISCOVERED. + *---------------------------------------------------------------------*/ + switch(failedNodePtr.p->phase){ + case ZRUNNING: jam(); - /**--------------------------------------------------------------------- - * THE OTHER NODE IS AN NDB NODE, WE HANDLE IT AS IF A HEARTBEAT - * FAILURE WAS DISCOVERED. - *---------------------------------------------------------------------*/ - switch(failedNodePtr.p->phase){ - case ZRUNNING: - jam(); - failReportLab(signal, aFailedNode, FailRep::ZLINK_FAILURE); - return; - case ZFAIL_CLOSING: - jam(); - return; - case ZSTARTING: - c_start.reset(); - // Fall-through - default: - jam(); - /*---------------------------------------------------------------------*/ - // The other node is still not in the cluster but disconnected. - // We must restart communication in three seconds. - /*---------------------------------------------------------------------*/ - failedNodePtr.p->failState = NORMAL; - failedNodePtr.p->phase = ZFAIL_CLOSING; - setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0; + failReportLab(signal, aFailedNode, FailRep::ZLINK_FAILURE); + return; + case ZFAIL_CLOSING: + jam(); + return; + case ZSTARTING: + c_start.reset(); + // Fall-through + default: + jam(); + /*---------------------------------------------------------------------*/ + // The other node is still not in the cluster but disconnected. + // We must restart communication in three seconds. + /*---------------------------------------------------------------------*/ + failedNodePtr.p->failState = NORMAL; + failedNodePtr.p->phase = ZFAIL_CLOSING; + setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0; - CloseComReqConf * const closeCom = - (CloseComReqConf *)&signal->theData[0]; + CloseComReqConf * const closeCom = + (CloseComReqConf *)&signal->theData[0]; - closeCom->xxxBlockRef = reference(); - closeCom->failNo = 0; - closeCom->noOfNodes = 1; - NodeBitmask::clear(closeCom->theNodes); - NodeBitmask::set(closeCom->theNodes, failedNodePtr.i); - sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal, - CloseComReqConf::SignalLength, JBA); - }//if + closeCom->xxxBlockRef = reference(); + closeCom->failNo = 0; + closeCom->noOfNodes = 1; + NodeBitmask::clear(closeCom->theNodes); + NodeBitmask::set(closeCom->theNodes, failedNodePtr.i); + sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal, + CloseComReqConf::SignalLength, JBA); + }//if + return; +} + +void +Qmgr::api_failed(Signal* signal, Uint32 nodeId) +{ + NodeRecPtr failedNodePtr; + /**------------------------------------------------------------------------ + * A COMMUNICATION LINK HAS BEEN DISCONNECTED. WE MUST TAKE SOME ACTION + * DUE TO THIS. + *-----------------------------------------------------------------------*/ + failedNodePtr.i = nodeId; + ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec); + + if (failedNodePtr.p->phase == ZFAIL_CLOSING) + { + /** + * Failure handling already in progress + */ + jam(); return; } - /** - * API code - */ - jam(); - if (failedNodePtr.p->phase != ZFAIL_CLOSING){ + if (failedNodePtr.p->phase == ZAPI_ACTIVE) + { jam(); - //------------------------------------------------------------------------- - // The API was active and has now failed. We need to initiate API failure - // handling. If the API had already failed then we can ignore this - // discovery. - //------------------------------------------------------------------------- - failedNodePtr.p->phase = ZFAIL_CLOSING; - - sendApiFailReq(signal, aFailedNode); + sendApiFailReq(signal, nodeId); arbitRec.code = ArbitCode::ApiFail; - handleArbitApiFail(signal, aFailedNode); - }//if - return; -}//Qmgr::node_failed() + handleArbitApiFail(signal, nodeId); + } + else + { + /** + * Always inform SUMA + */ + jam(); + signal->theData[0] = nodeId; + signal->theData[1] = QMGR_REF; + sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA); + failedNodePtr.p->failState = NORMAL; + } + + failedNodePtr.p->phase = ZFAIL_CLOSING; + setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0; + setNodeInfo(failedNodePtr.i).m_version = 0; + recompute_version_info(getNodeInfo(failedNodePtr.i).m_type); + + CloseComReqConf * const closeCom = (CloseComReqConf *)&signal->theData[0]; + closeCom->xxxBlockRef = reference(); + closeCom->failNo = 0; + closeCom->noOfNodes = 1; + NodeBitmask::clear(closeCom->theNodes); + NodeBitmask::set(closeCom->theNodes, failedNodePtr.i); + sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal, + CloseComReqConf::SignalLength, JBA); + + if (getNodeInfo(failedNodePtr.i).getType() == NodeInfo::MGM) + { + /** + * Allow MGM do reconnect "directly" + */ + jam(); + setNodeInfo(failedNodePtr.i).m_heartbeat_cnt = 3; + } +} /**-------------------------------------------------------------------------- * AN API NODE IS REGISTERING. IF FOR THE FIRST TIME WE WILL ENABLE @@ -4963,43 +4983,39 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal) c_start.m_president_candidate_gci); infoEvent("ctoStatus = %d\n", ctoStatus); for(Uint32 i = 1; iphase){ - case ZINIT: - sprintf(buf, "Node %d: ZINIT(%d)", i, nodePtr.p->phase); - break; - case ZSTARTING: - sprintf(buf, "Node %d: ZSTARTING(%d)", i, nodePtr.p->phase); - break; - case ZRUNNING: - sprintf(buf, "Node %d: ZRUNNING(%d)", i, nodePtr.p->phase); - break; - case ZPREPARE_FAIL: - sprintf(buf, "Node %d: ZPREPARE_FAIL(%d)", i, nodePtr.p->phase); - break; - case ZFAIL_CLOSING: - sprintf(buf, "Node %d: ZFAIL_CLOSING(%d)", i, nodePtr.p->phase); - break; - case ZAPI_INACTIVE: - sprintf(buf, "Node %d: ZAPI_INACTIVE(%d)", i, nodePtr.p->phase); - break; - case ZAPI_ACTIVE: - sprintf(buf, "Node %d: ZAPI_ACTIVE(%d)", i, nodePtr.p->phase); - break; - default: - sprintf(buf, "Node %d: (%d)", i, nodePtr.p->phase); - break; - } - infoEvent(buf); + NodeRecPtr nodePtr; + nodePtr.i = i; + ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); + char buf[100]; + switch(nodePtr.p->phase){ + case ZINIT: + sprintf(buf, "Node %d: ZINIT(%d)", i, nodePtr.p->phase); + break; + case ZSTARTING: + sprintf(buf, "Node %d: ZSTARTING(%d)", i, nodePtr.p->phase); + break; + case ZRUNNING: + sprintf(buf, "Node %d: ZRUNNING(%d)", i, nodePtr.p->phase); + break; + case ZPREPARE_FAIL: + sprintf(buf, "Node %d: ZPREPARE_FAIL(%d)", i, nodePtr.p->phase); + break; + case ZFAIL_CLOSING: + sprintf(buf, "Node %d: ZFAIL_CLOSING(%d)", i, nodePtr.p->phase); + break; + case ZAPI_INACTIVE: + sprintf(buf, "Node %d: ZAPI_INACTIVE(%d)", i, nodePtr.p->phase); + break; + case ZAPI_ACTIVE: + sprintf(buf, "Node %d: ZAPI_ACTIVE(%d)", i, nodePtr.p->phase); + break; + default: + sprintf(buf, "Node %d: (%d)", i, nodePtr.p->phase); + break; } + infoEvent(buf); } - default: - ; - }//switch + } #ifdef ERROR_INSERT if (signal->theData[0] == 935 && signal->getLength() == 2) diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp index 7845b83693c..113b63a19d3 100644 --- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp +++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp @@ -821,8 +821,9 @@ Suma::execINCL_NODEREQ(Signal* signal){ ndbrequire(!c_alive_nodes.get(nodeId)); c_alive_nodes.set(nodeId); - signal->theData[0] = reference(); - sendSignal(senderRef, GSN_INCL_NODECONF, signal, 1, JBB); + signal->theData[0] = nodeId; + signal->theData[1] = reference(); + sendSignal(senderRef, GSN_INCL_NODECONF, signal, 2, JBB); } void @@ -974,6 +975,54 @@ Suma::execDUMP_STATE_ORD(Signal* signal){ } return; } + + if (tCase == 8011) + { + jam(); + Uint32 bucket = signal->theData[1]; + KeyTable::Iterator it; + if (signal->getLength() == 1) + { + jam(); + bucket = 0; + infoEvent("-- Starting dump of subscribers --"); + } + + c_tables.next(bucket, it); + const Uint32 RT_BREAK = 16; + for(Uint32 i = 0; im_tableId, + it.curr.p->m_schemaVersion, + it.curr.p->n_subscribers); + + Ptr ptr; + LocalDLList list(c_subscriberPool, it.curr.p->c_subscribers); + for (list.first(ptr); !ptr.isNull(); list.next(ptr), i++) + { + jam(); + infoEvent(" [ %x %u %u ]", + ptr.p->m_senderRef, + ptr.p->m_senderData, + ptr.p->m_subPtrI); + } + c_tables.next(it); + } + + signal->theData[0] = tCase; + signal->theData[1] = it.bucket; + sendSignalWithDelay(reference(), GSN_DUMP_STATE_ORD, signal, 100, 2); + return; + } } /************************************************************* @@ -2402,6 +2451,7 @@ Suma::execSUB_START_REQ(Signal* signal){ { jam(); + c_subscriberPool.release(subbPtr); sendSubStartRef(signal, SubStartRef::PartiallyConnected); return; } diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp index ee5bb5103d8..184d51bad78 100644 --- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -119,7 +119,11 @@ operator<<(NdbOut& out, const LogLevel & ll) void MgmtSrvr::logLevelThreadRun() { - while (!_isStopThread) { + while (!_isStopThread) + { + Vector failed_started_nodes; + Vector failed_log_level_requests; + /** * Handle started nodes */ @@ -144,14 +148,15 @@ MgmtSrvr::logLevelThreadRun() m_started_nodes.unlock(); if (setEventReportingLevelImpl(node, req)) - { - ndbout_c("setEventReportingLevelImpl(%d): failed", node); - } - - SetLogLevelOrd ord; - ord = m_nodeLogLevel[node]; - setNodeLogLevelImpl(node, ord); - + { + failed_started_nodes.push_back(node); + } + else + { + SetLogLevelOrd ord; + ord = m_nodeLogLevel[node]; + setNodeLogLevelImpl(node, ord); + } m_started_nodes.lock(); } } @@ -166,17 +171,20 @@ MgmtSrvr::logLevelThreadRun() if(req.blockRef == 0) { - req.blockRef = _ownReference; - if (setEventReportingLevelImpl(0, req)) - { - ndbout_c("setEventReportingLevelImpl: failed 2!"); - } + req.blockRef = _ownReference; + if (setEventReportingLevelImpl(0, req)) + { + failed_log_level_requests.push_back(req); + } } else { SetLogLevelOrd ord; ord = req; - setNodeLogLevelImpl(req.blockRef, ord); + if (setNodeLogLevelImpl(req.blockRef, ord)) + { + failed_log_level_requests.push_back(req); + } } m_log_level_requests.lock(); } @@ -185,7 +193,28 @@ MgmtSrvr::logLevelThreadRun() if(!ERROR_INSERTED(10000)) m_event_listner.check_listeners(); - NdbSleep_MilliSleep(_logLevelThreadSleep); + Uint32 sleeptime = _logLevelThreadSleep; + if (failed_started_nodes.size()) + { + m_started_nodes.lock(); + for (Uint32 i = 0; i; template class MutexVector; +template class Vector; template class MutexVector; diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp index a82983fca8c..dff953923fe 100644 --- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp @@ -792,6 +792,18 @@ NdbEventOperationImpl::receive_event() p = p->next(); } } + // change the blobHandle's to refer to the new table object. + NdbBlob *p = theBlobList; + while (p) + { + int no = p->getColumn()->getColumnNo(); + NdbColumnImpl *tAttrInfo = at->getColumn(no); + DBUG_PRINT("info", ("blob_handle: 0x%lx " + "switching column impl 0x%lx -> 0x%lx", + (long) p, (long) p->theColumn, (long) tAttrInfo)); + p->theColumn = tAttrInfo; + p = p->next(); + } if (tmp_table_impl) delete tmp_table_impl; } diff --git a/storage/ndb/src/ndbapi/NdbOperationExec.cpp b/storage/ndb/src/ndbapi/NdbOperationExec.cpp index 27672e0458c..cd1ac44d82c 100644 --- a/storage/ndb/src/ndbapi/NdbOperationExec.cpp +++ b/storage/ndb/src/ndbapi/NdbOperationExec.cpp @@ -24,6 +24,7 @@ #include "Interpreter.hpp" #include #include +#include #include #include #include @@ -545,6 +546,12 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal) }//if setErrorCode(aSignal->readData(4)); + if (aSignal->getLength() == TcKeyRef::SignalLength) + { + // Signal may contain additional error data + theError.details = (char *) aSignal->readData(5); + } + theStatus = Finished; theReceiver.m_received_result_length = ~0; diff --git a/storage/ndb/src/ndbapi/NdbTransaction.cpp b/storage/ndb/src/ndbapi/NdbTransaction.cpp index bc59df722aa..17c7188bff2 100644 --- a/storage/ndb/src/ndbapi/NdbTransaction.cpp +++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp @@ -30,6 +30,7 @@ #include #include #include +#include /***************************************************************************** NdbTransaction( Ndb* aNdb ); @@ -1729,6 +1730,8 @@ Remark: Handles the reception of the ROLLBACKREP signal. int NdbTransaction::receiveTCROLLBACKREP( NdbApiSignal* aSignal) { + DBUG_ENTER("NdbTransaction::receiveTCROLLBACKREP"); + /**************************************************************************** Check that we are expecting signals from this transaction and that it doesn't belong to a transaction already completed. Simply ignore messages from other @@ -1736,6 +1739,11 @@ transactions. ****************************************************************************/ if(checkState_TransId(aSignal->getDataPtr() + 1)){ theError.code = aSignal->readData(4);// Override any previous errors + if (aSignal->getLength() == TcRollbackRep::SignalLength) + { + // Signal may contain additional error data + theError.details = (char *) aSignal->readData(5); + } /**********************************************************************/ /* A serious error has occured. This could be due to deadlock or */ @@ -1747,14 +1755,14 @@ transactions. theCompletionStatus = CompletedFailure; theCommitStatus = Aborted; theReturnStatus = ReturnFailure; - return 0; + DBUG_RETURN(0); } else { #ifdef NDB_NO_DROPPED_SIGNAL abort(); #endif } - return -1; + DBUG_RETURN(-1); }//NdbTransaction::receiveTCROLLBACKREP() /******************************************************************************* diff --git a/storage/ndb/src/ndbapi/TransporterFacade.cpp b/storage/ndb/src/ndbapi/TransporterFacade.cpp index eabfc6bc371..22eee859ef3 100644 --- a/storage/ndb/src/ndbapi/TransporterFacade.cpp +++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp @@ -1501,9 +1501,9 @@ void PollGuard::unlock_and_signal() if (t_signal_cond_waiter) t_signal_cond_waiter->set_poll_owner(true); } - m_tp->unlock_mutex(); if (t_signal_cond_waiter) t_signal_cond_waiter->cond_signal(); + m_tp->unlock_mutex(); m_locked=false; } diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c index 0ad2faff76a..e7f946118f2 100644 --- a/storage/ndb/src/ndbapi/ndberror.c +++ b/storage/ndb/src/ndbapi/ndberror.c @@ -169,7 +169,7 @@ ErrorBundle ErrorCodes[] = { { 219, DMEC, TR, "219" }, { 233, DMEC, TR, "Out of operation records in transaction coordinator (increase MaxNoOfConcurrentOperations)" }, - { 275, DMEC, TR, "275" }, + { 275, DMEC, TR, "Out of transaction records for complete phase (increase MaxNoOfConcurrentTransactions)" }, { 279, DMEC, TR, "Out of transaction markers in transaction coordinator" }, { 414, DMEC, TR, "414" }, { 418, DMEC, TR, "Out of transaction buffers in LQH" }, @@ -766,8 +766,6 @@ ndberror_update(ndberror_struct * error){ if(!found){ error->status = ST_U; } - - error->details = 0; } #if CHECK_ERRORCODES diff --git a/storage/ndb/test/ndbapi/testDict.cpp b/storage/ndb/test/ndbapi/testDict.cpp index 16b6e129605..e1b8f2b3c7f 100644 --- a/storage/ndb/test/ndbapi/testDict.cpp +++ b/storage/ndb/test/ndbapi/testDict.cpp @@ -2776,9 +2776,13 @@ runDropDDObjects(NDBT_Context* ctx, NDBT_Step* step){ case NdbDictionary::Object::UserTable: tableFound = list.elements[i].name; if(tableFound != 0){ - if(pDict->dropTable(tableFound) != 0){ - g_err << "Failed to drop table: " << pDict->getNdbError() << endl; - return NDBT_FAILED; + if(strcmp(tableFound, "ndb_apply_status") != 0 && + strcmp(tableFound, "NDB$BLOB_2_3") != 0 && + strcmp(tableFound, "ndb_schema") != 0){ + if(pDict->dropTable(tableFound) != 0){ + g_err << "Failed to drop table: " << tableFound << pDict->getNdbError() << endl; + return NDBT_FAILED; + } } } tableFound = 0; diff --git a/storage/ndb/test/ndbapi/testNodeRestart.cpp b/storage/ndb/test/ndbapi/testNodeRestart.cpp index 419196e00eb..751134c43c5 100644 --- a/storage/ndb/test/ndbapi/testNodeRestart.cpp +++ b/storage/ndb/test/ndbapi/testNodeRestart.cpp @@ -1590,6 +1590,8 @@ runBug27466(NDBT_Context* ctx, NDBT_Step* step) node2 = res.getDbNodeId(rand() % res.getNumDbNodes()); } + ndbout_c("nodes %u %u", node1, node2); + if (res.restartOneDbNode(node1, false, true, true)) return NDBT_FAILED; @@ -1830,6 +1832,51 @@ runBug31525(NDBT_Context* ctx, NDBT_Step* step) if (res.restartOneDbNode(nodes[1], false, false, true)) return NDBT_FAILED; + if (res.waitClusterStarted()) + return NDBT_FAILED; + + return NDBT_OK; +} + +int +runBug32160(NDBT_Context* ctx, NDBT_Step* step) +{ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + Ndb* pNdb = GETNDB(step); + NdbRestarter res; + + if (res.getNumDbNodes() < 2) + { + return NDBT_OK; + } + + int master = res.getMasterNodeId(); + int next = res.getNextMasterNodeId(master); + + if (res.insertErrorInNode(next, 7194)) + { + return NDBT_FAILED; + } + + int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 }; + if (res.dumpStateOneNode(master, val2, 2)) + return NDBT_FAILED; + + if (res.insertErrorInNode(master, 7193)) + return NDBT_FAILED; + + int val3[] = { 7099 }; + if (res.dumpStateOneNode(master, val3, 1)) + return NDBT_FAILED; + + if (res.waitNodesNoStart(&master, 1)) + return NDBT_FAILED; + + if (res.startNodes(&master, 1)) + return NDBT_FAILED; + if (res.waitClusterStarted()) return NDBT_FAILED; @@ -2205,6 +2252,9 @@ TESTCASE("Bug28717", ""){ TESTCASE("Bug29364", ""){ INITIALIZER(runBug29364); } +TESTCASE("Bug32160", ""){ + INITIALIZER(runBug32160); +} NDBT_TESTSUITE_END(testNodeRestart); int main(int argc, const char** argv){ diff --git a/storage/ndb/test/ndbapi/testSystemRestart.cpp b/storage/ndb/test/ndbapi/testSystemRestart.cpp index 89580c0cef8..0f9100f67fa 100644 --- a/storage/ndb/test/ndbapi/testSystemRestart.cpp +++ b/storage/ndb/test/ndbapi/testSystemRestart.cpp @@ -1501,6 +1501,38 @@ int runSR_DD_2(NDBT_Context* ctx, NDBT_Step* step) return result; } +int runBug22696(NDBT_Context* ctx, NDBT_Step* step) +{ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + Uint32 loops = ctx->getNumLoops(); + Uint32 rows = ctx->getNumRecords(); + NdbRestarter restarter; + HugoTransactions hugoTrans(*ctx->getTab()); + + Uint32 i = 0; + while(i<=loops && result != NDBT_FAILED) + { + for (Uint32 j = 0; j<10 && result != NDBT_FAILED; j++) + CHECK(hugoTrans.scanUpdateRecords(pNdb, rows) == 0); + + CHECK(restarter.restartAll(false, true, i > 0 ? true : false) == 0); + CHECK(restarter.waitClusterNoStart() == 0); + CHECK(restarter.insertErrorInAllNodes(7072) == 0); + CHECK(restarter.startAll() == 0); + CHECK(restarter.waitClusterStarted() == 0); + + i++; + if (i < loops) + { + NdbSleep_SecSleep(5); // Wait for a few gcp + } + } + + ctx->stopTest(); + return result; +} + int runBug27434(NDBT_Context* ctx, NDBT_Step* step) { @@ -1813,8 +1845,13 @@ TESTCASE("Bug28770", STEP(runBug28770); FINALIZER(runClearTable); } - - +TESTCASE("Bug22696", "") +{ + INITIALIZER(runWaitStarted); + INITIALIZER(runLoadTable); + INITIALIZER(runBug22696); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testSystemRestart); int main(int argc, const char** argv){ diff --git a/storage/ndb/test/run-test/daily-basic-tests.txt b/storage/ndb/test/run-test/daily-basic-tests.txt index 103675d8e35..37db5e01dd6 100644 --- a/storage/ndb/test/run-test/daily-basic-tests.txt +++ b/storage/ndb/test/run-test/daily-basic-tests.txt @@ -581,6 +581,10 @@ max-time: 1000 cmd: testNodeRestart args: -n Bug29364 T1 +max-time: 300 +cmd: testNodeRestart +args: -n Bug32160 T1 + # # DICT TESTS max-time: 500 @@ -1038,4 +1042,7 @@ max-time: 300 cmd: test_event args: -n Bug31701 T1 +max-time: 300 +cmd: testSystemRestart +args: -n Bug22696 T1 diff --git a/storage/ndb/test/tools/Makefile.am b/storage/ndb/test/tools/Makefile.am index 1683d4d84ae..da715caa1cb 100644 --- a/storage/ndb/test/tools/Makefile.am +++ b/storage/ndb/test/tools/Makefile.am @@ -13,7 +13,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -ndbtest_PROGRAMS = hugoLoad hugoFill hugoLockRecords hugoPkDelete hugoPkRead hugoPkReadRecord hugoPkUpdate hugoScanRead hugoScanUpdate restart verify_index copy_tab create_index ndb_cpcc listen_event eventlog rep_latency +ndbtest_PROGRAMS = hugoLoad hugoFill hugoLockRecords hugoPkDelete hugoPkRead hugoPkReadRecord hugoPkUpdate hugoScanRead hugoScanUpdate restart verify_index copy_tab create_index ndb_cpcc listen_event eventlog rep_latency ndb_connect # transproxy @@ -35,6 +35,7 @@ ndb_cpcc_SOURCES = cpcc.cpp listen_event_SOURCES = listen.cpp eventlog_SOURCES = log_listner.cpp rep_latency_SOURCES = rep_latency.cpp +ndb_connect_SOURCES = connect.cpp include $(top_srcdir)/storage/ndb/config/common.mk.am include $(top_srcdir)/storage/ndb/config/type_ndbapitest.mk.am diff --git a/storage/ndb/test/tools/connect.cpp b/storage/ndb/test/tools/connect.cpp new file mode 100644 index 00000000000..2d3ac34d3e8 --- /dev/null +++ b/storage/ndb/test/tools/connect.cpp @@ -0,0 +1,152 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include +#include +#include +#include + +NDB_STD_OPTS_VARS; + +static int _loop = 25; +static int _sleep = 25; +static int _drop = 1; + +typedef uchar* gptr; + +static struct my_option my_long_options[] = +{ + NDB_STD_OPTS("ndb_desc"), + { "loop", 'l', "loops", + (gptr*) &_loop, (gptr*) &_loop, 0, + GET_INT, REQUIRED_ARG, _loop, 0, 0, 0, 0, 0 }, + { "sleep", 's', "Sleep (ms) between connection attempt", + (gptr*) &_sleep, (gptr*) &_sleep, 0, + GET_INT, REQUIRED_ARG, _sleep, 0, 0, 0, 0, 0 }, + { "drop", 'd', + "Drop event operations before disconnect (0 = no, 1 = yes, else rand", + (gptr*) &_drop, (gptr*) &_drop, 0, + GET_INT, REQUIRED_ARG, _drop, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + +static void usage() +{ + char desc[] = "This program connects to ndbd, and then disconnects\n"; + ndb_std_print_version(); + my_print_help(my_long_options); + my_print_variables(my_long_options); +} + +int main(int argc, char** argv){ + NDB_INIT(argv[0]); + + const char *load_default_groups[]= { "mysql_cluster",0 }; + load_defaults("my",load_default_groups,&argc,&argv); + int ho_error; +#ifndef DBUG_OFF + opt_debug= "d:t:O,/tmp/ndb_desc.trace"; +#endif + if ((ho_error=handle_options(&argc, &argv, my_long_options, + ndb_std_get_one_option))) + return NDBT_ProgramExit(NDBT_WRONGARGS); + + for (int i = 0; i<_loop; i++) + { + Ndb_cluster_connection con(opt_connect_str); + if(con.connect(12, 5, 1) != 0) + { + ndbout << "Unable to connect to management server." << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + if (con.wait_until_ready(30,30) != 0) + { + ndbout << "Cluster nodes not ready in 30 seconds." << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + + Ndb MyNdb(&con, "TEST_DB"); + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + Vector ops; + const NdbDictionary::Dictionary * dict= MyNdb.getDictionary(); + for (int j = 0; j < argc; j++) + { + const NdbDictionary::Table * pTab = dict->getTable(argv[j]); + if (pTab == 0) + { + ndbout_c("Failed to retreive table: \"%s\"", argv[j]); + } + + BaseString tmp; + tmp.appfmt("EV-%s", argv[j]); + NdbEventOperation* pOp = MyNdb.createEventOperation(tmp.c_str()); + if ( pOp == NULL ) + { + ndbout << "Event operation creation failed: " << + MyNdb.getNdbError() << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + + for (int a = 0; a < pTab->getNoOfColumns(); a++) + { + pOp->getValue(pTab->getColumn(a)->getName()); + pOp->getPreValue(pTab->getColumn(a)->getName()); + } + + if (pOp->execute()) + { + ndbout << "operation execution failed: " << pOp->getNdbError() + << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + ops.push_back(pOp); + } + + if (_sleep) + { + NdbSleep_MilliSleep(10 + rand() % _sleep); + } + + for (Uint32 i = 0; i 50) + goto do_drop; + } + } + } + + return NDBT_ProgramExit(NDBT_OK); +} + +template class Vector; diff --git a/storage/ndb/tools/restore/Restore.cpp b/storage/ndb/tools/restore/Restore.cpp index a7d8a9d10d9..f599bb21978 100644 --- a/storage/ndb/tools/restore/Restore.cpp +++ b/storage/ndb/tools/restore/Restore.cpp @@ -534,6 +534,88 @@ TupleS::prepareRecord(TableS & tab){ return true; } +int +RestoreDataIterator::readTupleData(Uint32 *buf_ptr, Uint32 *ptr, + Uint32 dataLength) +{ + while (ptr + 2 < buf_ptr + dataLength) + { + typedef BackupFormat::DataFile::VariableData VarData; + VarData * data = (VarData *)ptr; + Uint32 sz = ntohl(data->Sz); + Uint32 attrId = ntohl(data->Id); // column_no + + AttributeData * attr_data = m_tuple.getData(attrId); + const AttributeDesc * attr_desc = m_tuple.getDesc(attrId); + + // just a reminder - remove when backwards compat implemented + if (m_currentTable->backupVersion < MAKE_VERSION(5,1,3) && + attr_desc->m_column->getNullable()) + { + const Uint32 ind = attr_desc->m_nullBitIndex; + if(BitmaskImpl::get(m_currentTable->m_nullBitmaskSize, + buf_ptr,ind)) + { + attr_data->null = true; + attr_data->void_value = NULL; + continue; + } + } + + if (m_currentTable->backupVersion < MAKE_VERSION(5,1,3)) + { + sz *= 4; + } + + attr_data->null = false; + attr_data->void_value = &data->Data[0]; + attr_data->size = sz; + + //if (m_currentTable->getTableId() >= 2) { ndbout << "var off=" << ptr-buf_ptr << " attrId=" << attrId << endl; } + + /** + * Compute array size + */ + const Uint32 arraySize = sz / (attr_desc->size / 8); + assert(arraySize <= attr_desc->arraySize); + + //convert the length of blob(v1) and text(v1) + if(!m_hostByteOrder + && (attr_desc->m_column->getType() == NdbDictionary::Column::Blob + || attr_desc->m_column->getType() == NdbDictionary::Column::Text) + && attr_desc->m_column->getArrayType() == NdbDictionary::Column::ArrayTypeFixed) + { + char* p = (char*)&attr_data->u_int64_value[0]; + Uint64 x; + memcpy(&x, p, sizeof(Uint64)); + x = Twiddle64(x); + memcpy(p, &x, sizeof(Uint64)); + } + + //convert datetime type + if(!m_hostByteOrder + && attr_desc->m_column->getType() == NdbDictionary::Column::Datetime) + { + char* p = (char*)&attr_data->u_int64_value[0]; + Uint64 x; + memcpy(&x, p, sizeof(Uint64)); + x = Twiddle64(x); + memcpy(p, &x, sizeof(Uint64)); + } + + if(!Twiddle(attr_desc, attr_data, attr_desc->arraySize)) + { + return -1; + } + + ptr += ((sz + 3) >> 2) + 2; + } + + assert(ptr == buf_ptr + dataLength); + + return 0; +} + const TupleS * RestoreDataIterator::getNextTuple(int & res) { @@ -630,78 +712,8 @@ RestoreDataIterator::getNextTuple(int & res) attr_data->void_value = NULL; } - while (ptr + 2 < buf_ptr + dataLength) { - typedef BackupFormat::DataFile::VariableData VarData; - VarData * data = (VarData *)ptr; - Uint32 sz = ntohl(data->Sz); - Uint32 attrId = ntohl(data->Id); // column_no - - AttributeData * attr_data = m_tuple.getData(attrId); - const AttributeDesc * attr_desc = m_tuple.getDesc(attrId); - - // just a reminder - remove when backwards compat implemented - if(m_currentTable->backupVersion < MAKE_VERSION(5,1,3) && - attr_desc->m_column->getNullable()){ - const Uint32 ind = attr_desc->m_nullBitIndex; - if(BitmaskImpl::get(m_currentTable->m_nullBitmaskSize, - buf_ptr,ind)){ - attr_data->null = true; - attr_data->void_value = NULL; - continue; - } - } - - if (m_currentTable->backupVersion < MAKE_VERSION(5,1,3)) - { - sz *= 4; - } - - attr_data->null = false; - attr_data->void_value = &data->Data[0]; - attr_data->size = sz; - - //if (m_currentTable->getTableId() >= 2) { ndbout << "var off=" << ptr-buf_ptr << " attrId=" << attrId << endl; } - - /** - * Compute array size - */ - const Uint32 arraySize = sz / (attr_desc->size / 8); - assert(arraySize <= attr_desc->arraySize); - - //convert the length of blob(v1) and text(v1) - if(!m_hostByteOrder - && (attr_desc->m_column->getType() == NdbDictionary::Column::Blob - || attr_desc->m_column->getType() == NdbDictionary::Column::Text) - && attr_desc->m_column->getArrayType() == NdbDictionary::Column::ArrayTypeFixed) - { - char* p = (char*)&attr_data->u_int64_value[0]; - Uint64 x; - memcpy(&x, p, sizeof(Uint64)); - x = Twiddle64(x); - memcpy(p, &x, sizeof(Uint64)); - } - - //convert datetime type - if(!m_hostByteOrder - && attr_desc->m_column->getType() == NdbDictionary::Column::Datetime) - { - char* p = (char*)&attr_data->u_int64_value[0]; - Uint64 x; - memcpy(&x, p, sizeof(Uint64)); - x = Twiddle64(x); - memcpy(p, &x, sizeof(Uint64)); - } - - if(!Twiddle(attr_desc, attr_data, attr_desc->arraySize)) - { - res = -1; - return NULL; - } - - ptr += ((sz + 3) >> 2) + 2; - } - - assert(ptr == buf_ptr + dataLength); + if ((res = readTupleData(buf_ptr, ptr, dataLength))) + return NULL; m_count ++; res = 0; diff --git a/storage/ndb/tools/restore/Restore.hpp b/storage/ndb/tools/restore/Restore.hpp index 5455fa17aa0..f6de9245509 100644 --- a/storage/ndb/tools/restore/Restore.hpp +++ b/storage/ndb/tools/restore/Restore.hpp @@ -355,6 +355,10 @@ public: bool validateFragmentFooter(); const TupleS *getNextTuple(int & res); + +private: + + int readTupleData(Uint32 *buf_ptr, Uint32 *ptr, Uint32 dataLength); }; class LogEntry {