From: Ole John Aske Date: January 17 2011 12:08pm Subject: bzr commit into mysql-5.1-telco-7.0-spj-scan-vs-scan branch (ole.john.aske:3407) List-Archive: http://lists.mysql.com/commits/128941 Message-Id: <20110117120859.A4C9C223@fimafeng09.norway.sun.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///net/fimafeng09/export/home/tmp/oleja/mysql/mysql-5.1-telco-7.0-spj-scan-scan/ based on revid:ole.john.aske@stripped 3407 Ole John Aske 2011-01-17 [merge] Merge from telco-7.0 modified: include/my_sys.h include/mysql.h.pp include/mysql_com.h mysql-test/r/join_outer.result mysql-test/suite/ndb/r/ndb_blob_big.result mysql-test/suite/ndb/r/ndb_condition_pushdown.result mysql-test/suite/ndb/t/ndb_blob_big.test mysql-test/suite/ndb/t/ndb_condition_pushdown.test mysql-test/t/join_outer.test mysys/my_lockmem.c sql/ha_ndbcluster.cc sql/ha_ndbcluster.h sql/ha_ndbcluster_binlog.cc sql/ha_ndbcluster_cond.cc sql/ha_ndbcluster_cond.h sql/ha_ndbcluster_glue.h sql/item.h sql/item_cmpfunc.cc sql/item_subselect.cc sql/rpl_utility.cc sql/sql_select.cc sql/sql_select.h storage/ndb/include/kernel/signaldata/NodeFailRep.hpp storage/ndb/include/ndb_config.h.in storage/ndb/include/ndbapi/Ndb.hpp storage/ndb/include/util/Bitmask.hpp storage/ndb/ndb_configure.cmake storage/ndb/ndb_configure.m4 storage/ndb/src/common/portlib/NdbMutex.c storage/ndb/src/kernel/blocks/ERROR_codes.txt storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp storage/ndb/src/kernel/blocks/lgman.cpp storage/ndb/src/kernel/blocks/tsman.cpp storage/ndb/src/kernel/blocks/tsman.hpp storage/ndb/src/kernel/vm/mt.cpp storage/ndb/src/mgmsrv/ConfigManager.cpp storage/ndb/src/mgmsrv/InitConfigFileParser.cpp storage/ndb/src/mgmsrv/MgmtSrvr.cpp storage/ndb/src/ndbapi/ClusterMgr.cpp storage/ndb/src/ndbapi/ClusterMgr.hpp storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp storage/ndb/src/ndbapi/NdbImpl.hpp storage/ndb/src/ndbapi/NdbInfoScanOperation.cpp storage/ndb/src/ndbapi/NdbQueryOperation.cpp storage/ndb/src/ndbapi/Ndbif.cpp storage/ndb/src/ndbapi/SignalSender.cpp storage/ndb/src/ndbapi/SignalSender.hpp storage/ndb/src/ndbapi/TransporterFacade.cpp storage/ndb/src/ndbapi/TransporterFacade.hpp storage/ndb/src/ndbapi/trp_client.cpp storage/ndb/src/ndbapi/trp_client.hpp storage/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp storage/ndb/test/ndbapi/testBasic.cpp storage/ndb/test/run-test/daily-basic-tests.txt === modified file 'include/my_sys.h' --- a/include/my_sys.h 2010-12-17 15:05:09 +0000 +++ b/include/my_sys.h 2011-01-14 15:26:59 +0000 @@ -845,10 +845,13 @@ extern my_bool dynstr_set(DYNAMIC_STRING extern my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size); extern my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n); extern void dynstr_free(DYNAMIC_STRING *str); -#if defined(HAVE_MLOCK) && 0 +#ifdef MCP_BUG54662 +#ifdef HAVE_MLOCK extern void *my_malloc_lock(size_t length,myf flags); extern void my_free_lock(void *ptr,myf flags); #else +#endif +#else #define my_malloc_lock(A,B) my_malloc((A),(B)) #define my_free_lock(A,B) my_free((A),(B)) #endif === modified file 'include/mysql.h.pp' --- a/include/mysql.h.pp 2010-11-09 09:29:29 +0000 +++ b/include/mysql.h.pp 2011-01-14 14:02:55 +0000 @@ -58,8 +58,7 @@ enum enum_field_types { MYSQL_TYPE_DECIM MYSQL_TYPE_BLOB=252, MYSQL_TYPE_VAR_STRING=253, MYSQL_TYPE_STRING=254, - MYSQL_TYPE_GEOMETRY=255, - MYSQL_NUM_FIELD_TYPES + MYSQL_TYPE_GEOMETRY=255 }; enum mysql_enum_shutdown_level { SHUTDOWN_DEFAULT = 0, @@ -103,8 +102,7 @@ struct rand_struct { double max_value_dbl; }; enum Item_result {STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, - DECIMAL_RESULT, - MYSQL_NUM_ITEM_RESULTS }; + DECIMAL_RESULT}; typedef struct st_udf_args { unsigned int arg_count; === modified file 'include/mysql_com.h' --- a/include/mysql_com.h 2010-11-09 09:29:29 +0000 +++ b/include/mysql_com.h 2011-01-14 14:02:55 +0000 @@ -315,12 +315,7 @@ enum enum_field_types { MYSQL_TYPE_DECIM MYSQL_TYPE_BLOB=252, MYSQL_TYPE_VAR_STRING=253, MYSQL_TYPE_STRING=254, -#ifndef MCP_BUG58075 - MYSQL_TYPE_GEOMETRY=255, - MYSQL_NUM_FIELD_TYPES /* Always last */ -#else MYSQL_TYPE_GEOMETRY=255 -#endif }; /* For backward compatibility */ @@ -448,12 +443,7 @@ struct rand_struct { /* The following is for user defined functions */ enum Item_result {STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, -#ifndef MCP_BUG58075 - DECIMAL_RESULT, - MYSQL_NUM_ITEM_RESULTS /* Always last */ }; -#else DECIMAL_RESULT}; -#endif typedef struct st_udf_args { === modified file 'mysql-test/r/join_outer.result' --- a/mysql-test/r/join_outer.result 2010-12-03 16:59:43 +0000 +++ b/mysql-test/r/join_outer.result 2011-01-17 12:08:49 +0000 @@ -1442,6 +1442,76 @@ i i i i 4 4 4 NULL DROP TABLE t1,t2,t3,t4; # +# Bug#57034 incorrect OUTER JOIN result when joined on unique key +# +CREATE TABLE t1 (pk INT PRIMARY KEY, +col_int INT, +col_int_unique INT UNIQUE KEY); +INSERT INTO t1 VALUES (1,NULL,2), (2,0,0); +CREATE TABLE t2 (pk INT PRIMARY KEY, +col_int INT, +col_int_unique INT UNIQUE KEY); +INSERT INTO t2 VALUES (1,0,1), (2,0,2); +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 +ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int +WHERE t1.pk=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 const col_int_unique col_int_unique 5 const 1 +SELECT * FROM t1 LEFT JOIN t2 +ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int +WHERE t1.pk=1; +pk col_int col_int_unique pk col_int col_int_unique +1 NULL 2 NULL NULL NULL +DROP TABLE t1,t2; +# +# Bug#48046 Server incorrectly processing JOINs on NULL values +# +CREATE TABLE `BB` ( +`pk` int(11) NOT NULL AUTO_INCREMENT, +`time_key` time DEFAULT NULL, +`varchar_key` varchar(1) DEFAULT NULL, +`varchar_nokey` varchar(1) DEFAULT NULL, +PRIMARY KEY (`pk`), +KEY `time_key` (`time_key`), +KEY `varchar_key` (`varchar_key`) +) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1; +INSERT INTO `BB` VALUES (10,'18:27:58',NULL,NULL); +SELECT table1.time_key AS field1, table2.pk +FROM BB table1 LEFT JOIN BB table2 +ON table2.varchar_nokey = table1.varchar_key +HAVING field1; +field1 pk +18:27:58 NULL +DROP TABLE BB; +# +# Bug#49600 Server incorrectly processing RIGHT JOIN with +# constant WHERE clause and no index +# +CREATE TABLE `BB` ( +`col_datetime_key` datetime DEFAULT NULL, +`col_varchar_key` varchar(1) DEFAULT NULL, +`col_varchar_nokey` varchar(1) DEFAULT NULL, +KEY `col_datetime_key` (`col_datetime_key`), +KEY `col_varchar_key` (`col_varchar_key`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO `BB` VALUES ('1900-01-01 00:00:00',NULL,NULL); +SELECT table1.col_datetime_key +FROM BB table1 RIGHT JOIN BB table2 +ON table2 .col_varchar_nokey = table1.col_varchar_key +WHERE 7; +col_datetime_key +NULL +ALTER TABLE BB DISABLE KEYS; +SELECT table1.col_datetime_key +FROM BB table1 RIGHT JOIN BB table2 +ON table2 .col_varchar_nokey = table1.col_varchar_key +WHERE 7; +col_datetime_key +NULL +DROP TABLE BB; +# # Bug#58626 Incorrect result for WHERE IN () IS UNKNOWN # CREATE TABLE t1 (I INT NOT NULL); @@ -1481,24 +1551,4 @@ WHERE t3.pk2 = t2.i IS UNKNOWN; I I DROP TABLE t1,t2,t3; -# -# Bug#57034 incorrect OUTER JOIN result when joined on unique key -# -CREATE TABLE t1 (pk INT PRIMARY KEY, col_int INT, col_int_unique INT UNIQUE KEY); -INSERT INTO t1 VALUES (1,NULL,2), (2,0,0); -CREATE TABLE t2 (pk INT PRIMARY KEY, col_int INT, col_int_unique INT UNIQUE KEY); -INSERT INTO t2 VALUES (1,0,1), (2,0,2); -EXPLAIN -SELECT * FROM t1 LEFT JOIN t2 -ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int -WHERE t1.pk=1; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 -1 SIMPLE t2 const col_int_unique col_int_unique 5 const 1 -SELECT * FROM t1 LEFT JOIN t2 -ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int -WHERE t1.pk=1; -pk col_int col_int_unique pk col_int col_int_unique -1 NULL 2 NULL NULL NULL -DROP TABLE t1,t2; End of 5.1 tests === modified file 'mysql-test/suite/ndb/r/ndb_blob_big.result' --- a/mysql-test/suite/ndb/r/ndb_blob_big.result 2010-12-22 16:23:32 +0000 +++ b/mysql-test/suite/ndb/r/ndb_blob_big.result 2011-01-14 11:51:58 +0000 @@ -35,11 +35,6 @@ Now heavy insert should succeed call heavy_insert(10, 9*1024*1024); Now heavy read should fail call heavy_read(100); -show warnings; -Level Code Message -Error 1297 Got temporary error 1218 'Send Buffers overloaded in NDB kernel' from NDB -Error 1297 Got temporary error 1218 'Send Buffers overloaded in NDB kernel' from NDB -Error 1297 Got temporary error 1218 'Send Buffers overloaded in NDB kernel' from NDBCLUSTER set ndb_blob_read_batch_bytes=100 * 1024; Now heavy read should succeed call heavy_read(100); === modified file 'mysql-test/suite/ndb/r/ndb_condition_pushdown.result' --- a/mysql-test/suite/ndb/r/ndb_condition_pushdown.result 2010-12-21 12:37:25 +0000 +++ b/mysql-test/suite/ndb/r/ndb_condition_pushdown.result 2011-01-17 12:08:49 +0000 @@ -2298,5 +2298,37 @@ pk1 pk1 pk2 pk2 3 3 0 0 4 3 0 0 drop table t; +set engine_condition_pushdown = on; +create table t (pk int, i int) engine = ndb; +insert into t values (1,3), (3,6), (6,9), (9,1); +create table subq (pk int, i int) engine = ndb; +insert into subq values (1,3), (3,6), (6,9), (9,1); +explain extended +select * from t where exists +(select * from t as subq where subq.i=3 and t.i=3); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t ALL NULL NULL NULL NULL 4 50.00 Using where +2 DEPENDENT SUBQUERY subq ALL NULL NULL NULL NULL 4 100.00 Using where with pushed condition: (`test`.`subq`.`i` = 3) +Warnings: +Note 1276 Field or reference 'test.t.i' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `test`.`t`.`pk` AS `pk`,`test`.`t`.`i` AS `i` from `test`.`t` where exists(select 1 from `test`.`t` `subq` where ((`test`.`subq`.`i` = 3) and (`test`.`t`.`i` = 3))) +explain extended +select * from t where exists +(select * from subq where subq.i=3 and t.i=3); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY subq ALL NULL NULL NULL NULL 4 50.00 Using where with pushed condition: (`test`.`subq`.`i` = 3) +Warnings: +Note 1276 Field or reference 'test.t.i' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `test`.`t`.`pk` AS `pk`,`test`.`t`.`i` AS `i` from `test`.`t` where exists(select 1 from `test`.`subq` where ((`test`.`subq`.`i` = 3) and (`test`.`t`.`i` = 3))) +select * from t where exists +(select * from t as subq where subq.i=3 and t.i=3); +pk i +1 3 +select * from t where exists +(select * from subq where subq.i=3 and t.i=3); +pk i +1 3 +drop table t,subq; set engine_condition_pushdown = @old_ecpd; DROP TABLE t1,t2,t3,t4,t5; === modified file 'mysql-test/suite/ndb/t/ndb_blob_big.test' --- a/mysql-test/suite/ndb/t/ndb_blob_big.test 2010-12-22 16:23:32 +0000 +++ b/mysql-test/suite/ndb/t/ndb_blob_big.test 2011-01-14 11:51:58 +0000 @@ -44,6 +44,7 @@ set ndb_blob_write_batch_bytes = 0; --error 0,1297,1297 call heavy_insert(20, 5*1024*1024); +# NOTE don't check for warnings...as it doesnt fail consistenly delete from t1; @@ -58,7 +59,7 @@ call heavy_insert(10, 9*1024*1024); --error 0,1297,1297 call heavy_read(100); --enable_result_log -show warnings; +# NOTE don't check for warnings...as it doesnt fail consistenly set ndb_blob_read_batch_bytes=100 * 1024; === modified file 'mysql-test/suite/ndb/t/ndb_condition_pushdown.test' --- a/mysql-test/suite/ndb/t/ndb_condition_pushdown.test 2010-12-08 07:58:31 +0000 +++ b/mysql-test/suite/ndb/t/ndb_condition_pushdown.test 2011-01-17 12:08:49 +0000 @@ -2345,7 +2345,6 @@ group by t2.c; drop table tx; - # Bug#58791 Incorrect result as Cluster may fail to reject an unpushable condition create table t (pk1 int, pk2 int, primary key(pk1,pk2)) engine = ndb; @@ -2367,6 +2366,31 @@ select table1.pk1, table2.pk1, table1.pk drop table t; +# Bug#58134: Incorrectly condition pushdown inside subquery to NDB engine +set engine_condition_pushdown = on; + +create table t (pk int, i int) engine = ndb; +insert into t values (1,3), (3,6), (6,9), (9,1); +create table subq (pk int, i int) engine = ndb; +insert into subq values (1,3), (3,6), (6,9), (9,1); + +# 'Explain extended' to verify that only 'subq.i=3' is pushed +explain extended +select * from t where exists + (select * from t as subq where subq.i=3 and t.i=3); +explain extended + select * from t where exists + (select * from subq where subq.i=3 and t.i=3); + +--sorted_result +select * from t where exists + (select * from t as subq where subq.i=3 and t.i=3); +--sorted_result +select * from t where exists + (select * from subq where subq.i=3 and t.i=3); + +drop table t,subq; + set engine_condition_pushdown = @old_ecpd; DROP TABLE t1,t2,t3,t4,t5; === modified file 'mysql-test/t/join_outer.test' --- a/mysql-test/t/join_outer.test 2010-12-03 16:59:43 +0000 +++ b/mysql-test/t/join_outer.test 2011-01-17 12:08:49 +0000 @@ -981,7 +981,6 @@ EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt DROP TABLE t1; - --echo # --echo # Bug#58490: Incorrect result in multi level OUTER JOIN --echo # in combination with IS NULL @@ -1023,6 +1022,88 @@ SELECT * FROM DROP TABLE t1,t2,t3,t4; --echo # +--echo # Bug#57034 incorrect OUTER JOIN result when joined on unique key +--echo # + +CREATE TABLE t1 (pk INT PRIMARY KEY, + col_int INT, + col_int_unique INT UNIQUE KEY); +INSERT INTO t1 VALUES (1,NULL,2), (2,0,0); + +CREATE TABLE t2 (pk INT PRIMARY KEY, + col_int INT, + col_int_unique INT UNIQUE KEY); +INSERT INTO t2 VALUES (1,0,1), (2,0,2); + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 + ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int + WHERE t1.pk=1; + +SELECT * FROM t1 LEFT JOIN t2 + ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int + WHERE t1.pk=1; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug#48046 Server incorrectly processing JOINs on NULL values +--echo # + +# bug#48046 is a duplicate of bug#57034 + +CREATE TABLE `BB` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `time_key` time DEFAULT NULL, + `varchar_key` varchar(1) DEFAULT NULL, + `varchar_nokey` varchar(1) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `time_key` (`time_key`), + KEY `varchar_key` (`varchar_key`) +) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1; + +INSERT INTO `BB` VALUES (10,'18:27:58',NULL,NULL); + +SELECT table1.time_key AS field1, table2.pk +FROM BB table1 LEFT JOIN BB table2 + ON table2.varchar_nokey = table1.varchar_key + HAVING field1; + +DROP TABLE BB; + +--echo # +--echo # Bug#49600 Server incorrectly processing RIGHT JOIN with +--echo # constant WHERE clause and no index +--echo # + +# bug#49600 is a duplicate of bug#57034 + +CREATE TABLE `BB` ( + `col_datetime_key` datetime DEFAULT NULL, + `col_varchar_key` varchar(1) DEFAULT NULL, + `col_varchar_nokey` varchar(1) DEFAULT NULL, + KEY `col_datetime_key` (`col_datetime_key`), + KEY `col_varchar_key` (`col_varchar_key`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +INSERT INTO `BB` VALUES ('1900-01-01 00:00:00',NULL,NULL); + +SELECT table1.col_datetime_key +FROM BB table1 RIGHT JOIN BB table2 + ON table2 .col_varchar_nokey = table1.col_varchar_key + WHERE 7; + +# Disable keys, and we get incorrect result for the same query +ALTER TABLE BB DISABLE KEYS; + +SELECT table1.col_datetime_key +FROM BB table1 RIGHT JOIN BB table2 + ON table2 .col_varchar_nokey = table1.col_varchar_key + WHERE 7; + +DROP TABLE BB; + +--echo # --echo # Bug#58626 Incorrect result for WHERE IN () IS UNKNOWN --echo # @@ -1066,24 +1147,4 @@ SELECT * FROM DROP TABLE t1,t2,t3; ---echo # ---echo # Bug#57034 incorrect OUTER JOIN result when joined on unique key ---echo # - -CREATE TABLE t1 (pk INT PRIMARY KEY, col_int INT, col_int_unique INT UNIQUE KEY); -INSERT INTO t1 VALUES (1,NULL,2), (2,0,0); -CREATE TABLE t2 (pk INT PRIMARY KEY, col_int INT, col_int_unique INT UNIQUE KEY); -INSERT INTO t2 VALUES (1,0,1), (2,0,2); - -EXPLAIN -SELECT * FROM t1 LEFT JOIN t2 - ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int - WHERE t1.pk=1; - -SELECT * FROM t1 LEFT JOIN t2 - ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int - WHERE t1.pk=1; - -DROP TABLE t1,t2; - --echo End of 5.1 tests === modified file 'mysys/my_lockmem.c' --- a/mysys/my_lockmem.c 2010-12-17 15:05:09 +0000 +++ b/mysys/my_lockmem.c 2011-01-14 15:26:59 +0000 @@ -22,7 +22,8 @@ #include "mysys_err.h" #include -#if defined(HAVE_MLOCK) && 0 +#ifdef MCP_BUG54662 +#ifdef HAVE_MLOCK #include struct st_mem_list @@ -100,3 +101,4 @@ void my_free_lock(uchar *ptr,myf Myflags } #endif /* HAVE_MLOCK */ +#endif === modified file 'sql/ha_ndbcluster.cc' --- a/sql/ha_ndbcluster.cc 2011-01-06 21:25:28 +0000 +++ b/sql/ha_ndbcluster.cc 2011-01-17 12:08:49 +0000 @@ -70,7 +70,6 @@ static ulong opt_ndb_cache_check_time; static uint opt_ndb_cluster_connection_pool; static char* opt_ndb_connectstring; static uint opt_ndb_nodeid; -extern ulong opt_server_id_mask; static MYSQL_THDVAR_UINT( autoincrement_prefetch_sz, /* name */ @@ -278,7 +277,7 @@ static int ndbcluster_alter_tablespace(h static int ndbcluster_fill_files_table(handlerton *hton, THD *thd, TABLE_LIST *tables, - COND *cond); + Item *cond); static int ndbcluster_make_pushed_join(handlerton *hton, THD* thd, AQP::Join_plan* plan); @@ -296,7 +295,7 @@ static int ndbcluster_make_pushed_join(h */ static int ndbcluster_fill_is_table(handlerton *hton, THD *thd, TABLE_LIST *tables, - COND *cond, enum enum_schema_tables schema_table_idx) + Item *cond, enum enum_schema_tables schema_table_idx) { if (schema_table_idx == SCH_FILES) return ndbcluster_fill_files_table(hton, thd, tables, cond); @@ -5990,9 +5989,8 @@ ha_ndbcluster::eventSetAnyValue(THD *thd In future it may be useful to support *not* mapping composite AnyValues to/from Binlogged server-ids */ - assert(thd->server_id == (thd->unmasked_server_id & opt_server_id_mask)); options->optionsPresent |= NdbOperation::OperationOptions::OO_ANYVALUE; - options->anyValue = thd->unmasked_server_id; + options->anyValue = thd_unmasked_server_id(thd); } else if (thd_ndb->trans_options & TNTO_NO_LOGGING) { @@ -8683,20 +8681,42 @@ static int ndbcluster_update_apply_statu r|= op->setValue(1u, (Uint64)0); DBUG_ASSERT(r == 0); } +#if MYSQL_VERSION_ID < 50600 + const char* group_master_log_name = + active_mi->rli.group_master_log_name; + const Uint64 group_master_log_pos = + (Uint64)active_mi->rli.group_master_log_pos; + const Uint64 future_event_relay_log_pos = + (Uint64)active_mi->rli.future_event_relay_log_pos; + const Uint64 group_relay_log_pos = + (Uint64)active_mi->rli.group_relay_log_pos; +#else + /* + - Master_info's rli member returns Relay_log_info* + - Relay_log_info members are protected and must be accessed + using accessor functions + */ + const char* group_master_log_name = + active_mi->rli->get_group_master_log_name(); + const Uint64 group_master_log_pos = + (Uint64)active_mi->rli->get_group_master_log_pos(); + const Uint64 future_event_relay_log_pos = + (Uint64)active_mi->rli->get_future_event_relay_log_pos(); + const Uint64 group_relay_log_pos = + (Uint64)active_mi->rli->get_group_relay_log_pos(); +#endif // log_name char tmp_buf[FN_REFLEN]; ndb_pack_varchar(ndbtab->getColumn(2u), tmp_buf, - active_mi->rli.group_master_log_name, - strlen(active_mi->rli.group_master_log_name)); + group_master_log_name, strlen(group_master_log_name)); r|= op->setValue(2u, tmp_buf); DBUG_ASSERT(r == 0); // start_pos - r|= op->setValue(3u, (Uint64)active_mi->rli.group_master_log_pos); + r|= op->setValue(3u, group_master_log_pos); DBUG_ASSERT(r == 0); // end_pos - r|= op->setValue(4u, (Uint64)active_mi->rli.group_master_log_pos + - ((Uint64)active_mi->rli.future_event_relay_log_pos - - (Uint64)active_mi->rli.group_relay_log_pos)); + r|= op->setValue(4u, group_master_log_pos + + (future_event_relay_log_pos - group_relay_log_pos)); DBUG_ASSERT(r == 0); return 0; } @@ -13046,7 +13066,9 @@ ulonglong ha_ndbcluster::table_flags(voi HA_NULL_IN_KEY | HA_AUTO_PART_KEY | HA_NO_PREFIX_CHAR_KEYS | +#ifndef NDB_WITH_NEW_MRR_INTERFACE HA_NEED_READ_RANGE_BUFFER | +#endif HA_CAN_GEOMETRY | HA_CAN_BIT_FIELD | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | @@ -14128,7 +14150,7 @@ int ha_ndbcluster::write_ndb_file(const DBUG_RETURN(error); } - +#ifndef NDB_WITH_NEW_MRR_INTERFACE bool ha_ndbcluster::null_value_index_search(KEY_MULTI_RANGE *ranges, KEY_MULTI_RANGE *end_range, @@ -14158,6 +14180,7 @@ ha_ndbcluster::null_value_index_search(K } DBUG_RETURN(FALSE); } +#endif void ha_ndbcluster::check_read_before_write_removal() { @@ -14198,7 +14221,7 @@ void ha_ndbcluster::check_read_before_wr DBUG_VOID_RETURN; } - +#ifndef NDB_WITH_NEW_MRR_INTERFACE /* This is used to check if an ordered index scan is needed for a range in a multi range read. @@ -14901,6 +14924,7 @@ ha_ndbcluster::read_multi_range_fetch_ne } DBUG_RETURN(0); } +#endif /** @param[in] comment table comment defined by user @@ -15255,8 +15279,8 @@ ndb_util_thread_fail: the scan for evaluation (and thus not saved on stack) */ const -COND* -ha_ndbcluster::cond_push(const COND *cond) +Item* +ha_ndbcluster::cond_push(const Item *cond) { DBUG_ENTER("cond_push"); @@ -15268,7 +15292,7 @@ ha_ndbcluster::cond_push(const COND *con * (Optimizer need to have a better understanding of what is * pushable by each handler.) */ - DBUG_EXECUTE("where",print_where((COND *)cond, "Rejected cond_push", QT_ORDINARY);); + DBUG_EXECUTE("where",print_where((Item *)cond, "Rejected cond_push", QT_ORDINARY);); DBUG_RETURN(NULL); } if (!m_cond) @@ -15278,7 +15302,7 @@ ha_ndbcluster::cond_push(const COND *con my_errno= HA_ERR_OUT_OF_MEM; DBUG_RETURN(NULL); } - DBUG_EXECUTE("where",print_where((COND *)cond, m_tabname, QT_ORDINARY);); + DBUG_EXECUTE("where",print_where((Item *)cond, m_tabname, QT_ORDINARY);); DBUG_RETURN(m_cond->cond_push(cond, table, (NDBTAB *)m_table)); } @@ -16804,7 +16828,7 @@ bool ha_ndbcluster::get_no_parts(const c static int ndbcluster_fill_files_table(handlerton *hton, THD *thd, TABLE_LIST *tables, - COND *cond) + Item *cond) { TABLE* table= tables->table; Ndb *ndb= check_ndb_in_thd(thd); === modified file 'sql/ha_ndbcluster.h' --- a/sql/ha_ndbcluster.h 2011-01-06 21:19:05 +0000 +++ b/sql/ha_ndbcluster.h 2011-01-17 12:08:49 +0000 @@ -462,6 +462,7 @@ class ha_ndbcluster: public handler int read_range_next(); int alter_tablespace(st_alter_tablespace *info); +#ifndef NDB_WITH_NEW_MRR_INTERFACE /** * Multi range stuff */ @@ -472,6 +473,7 @@ class ha_ndbcluster: public handler bool null_value_index_search(KEY_MULTI_RANGE *ranges, KEY_MULTI_RANGE *end_range, HANDLER_BUFFER *buffer); +#endif bool get_error_message(int error, String *buf); ha_rows records(); @@ -587,7 +589,7 @@ static void set_tabname(const char *path =, !=, >, >=, <, <=, like, "not like", "is null", and "is not null". Negated conditions are supported by NOT which generate NAND/NOR groups. */ - const COND *cond_push(const COND *cond); + const Item *cond_push(const Item *cond); /* Pop the top condition from the condition stack of the handler instance. SYNOPSIS === modified file 'sql/ha_ndbcluster_binlog.cc' --- a/sql/ha_ndbcluster_binlog.cc 2010-11-16 14:05:31 +0000 +++ b/sql/ha_ndbcluster_binlog.cc 2011-01-14 14:37:28 +0000 @@ -24,7 +24,11 @@ #include "rpl_injector.h" #include "rpl_filter.h" +#if MYSQL_VERSION_ID > 50600 +#include "rpl_slave.h" +#else #include "slave.h" +#endif #include "ha_ndbcluster_binlog.h" #include #include @@ -43,7 +47,6 @@ extern my_bool opt_ndb_log_updated_only; extern my_bool opt_ndb_log_binlog_index; extern my_bool opt_ndb_log_apply_status; extern ulong opt_ndb_extra_logging; -extern ulong opt_server_id_mask; bool ndb_log_empty_epochs(void); @@ -636,7 +639,7 @@ setup_thd(char * stackptr) lex_start(thd); thd->init_for_queries(); - thd->command= COM_DAEMON; + thd_set_command(thd, COM_DAEMON); thd->system_thread= SYSTEM_THREAD_NDBCLUSTER_BINLOG; #ifndef NDB_THD_HAS_NO_VERSION thd->version= refresh_version; @@ -2273,8 +2276,7 @@ int ndbcluster_log_schema_op(THD *thd, */ DBUG_PRINT("info", ("Replicated schema event with original server id %d", thd->server_id)); - assert(thd->server_id == (thd->unmasked_server_id & opt_server_id_mask)); - anyValue = thd->unmasked_server_id; + anyValue = thd_unmasked_server_id(thd); } #ifndef DBUG_OFF @@ -5981,7 +5983,7 @@ pthread_handler_t ndb_binlog_thread_func lex_start(thd); thd->init_for_queries(); - thd->command= COM_DAEMON; + thd_set_command(thd, COM_DAEMON); thd->system_thread= SYSTEM_THREAD_NDBCLUSTER_BINLOG; #ifndef NDB_THD_HAS_NO_VERSION thd->version= refresh_version; @@ -7001,4 +7003,11 @@ void ndbcluster_anyvalue_set_serverid(Ui anyValue |= (serverId & opt_server_id_mask); } +#ifdef NDB_WITHOUT_SERVER_ID_BITS + +/* No --server-id-bits= -> implement constant opt_server_id_mask */ +ulong opt_server_id_mask = ~0; + +#endif + #endif === modified file 'sql/ha_ndbcluster_cond.cc' --- a/sql/ha_ndbcluster_cond.cc 2010-11-19 11:25:46 +0000 +++ b/sql/ha_ndbcluster_cond.cc 2011-01-17 12:08:49 +0000 @@ -963,8 +963,8 @@ void ndb_serialize_cond(const Item *item Push a condition */ const -COND* -ha_ndbcluster_cond::cond_push(const COND *cond, +Item* +ha_ndbcluster_cond::cond_push(const Item *cond, TABLE *table, const NDBTAB *ndb_table) { DBUG_ENTER("cond_push"); @@ -1020,7 +1020,7 @@ ha_ndbcluster_cond::cond_clear() } bool -ha_ndbcluster_cond::serialize_cond(const COND *cond, Ndb_cond_stack *ndb_cond, +ha_ndbcluster_cond::serialize_cond(const Item *cond, Ndb_cond_stack *ndb_cond, TABLE *table, const NDBTAB *ndb_table) { DBUG_ENTER("serialize_cond"); === modified file 'sql/ha_ndbcluster_cond.h' --- a/sql/ha_ndbcluster_cond.h 2010-11-15 09:23:10 +0000 +++ b/sql/ha_ndbcluster_cond.h 2011-01-14 14:15:54 +0000 @@ -25,8 +25,6 @@ #pragma interface /* gcc class implementation */ #endif -#define round_up_byte(size) ((size + 7) >> 3) << 3 - typedef enum ndb_item_type { NDB_VALUE = 0, // Qualified more with Item::Type NDB_FIELD = 1, // Qualified from table definition @@ -333,22 +331,23 @@ class Ndb_cond_stack : public Sql_alloc */ class Ndb_expect_stack : public Sql_alloc { + static const uint MAX_EXPECT_ITEMS = Item::VIEW_FIXER_ITEM + 1; + static const uint MAX_EXPECT_FIELD_TYPES = MYSQL_TYPE_GEOMETRY + 1; + static const uint MAX_EXPECT_FIELD_RESULTS = DECIMAL_RESULT + 1; public: Ndb_expect_stack(): collation(NULL), length(0), max_length(0), next(NULL) { - // Allocate type checking bitmaps - bitmap_init(&expect_mask, - 0, round_up_byte(Item::MAX_NUM_ITEMS), FALSE); - bitmap_init(&expect_field_type_mask, - 0, round_up_byte(MYSQL_NUM_FIELD_TYPES), FALSE); - bitmap_init(&expect_field_result_mask, - 0, round_up_byte(MYSQL_NUM_ITEM_RESULTS), FALSE); + // Allocate type checking bitmaps using fixed size buffers + // since max size is known at compile time + bitmap_init(&expect_mask, m_expect_buf, + MAX_EXPECT_ITEMS, FALSE); + bitmap_init(&expect_field_type_mask, m_expect_field_type_buf, + MAX_EXPECT_FIELD_TYPES, FALSE); + bitmap_init(&expect_field_result_mask, m_expect_field_result_buf, + MAX_EXPECT_FIELD_RESULTS, FALSE); }; ~Ndb_expect_stack() { - bitmap_free(&expect_mask); - bitmap_free(&expect_field_type_mask); - bitmap_free(&expect_field_result_mask); if (next) delete next; next= NULL; @@ -385,6 +384,11 @@ Ndb_expect_stack(): collation(NULL), len } bool expecting(Item::Type type) { + if (unlikely((uint)type > MAX_EXPECT_ITEMS)) + { + // Unknown type, can't be expected + return false; + } return bitmap_is_set(&expect_mask, (uint) type); } void expect_nothing() @@ -411,6 +415,11 @@ Ndb_expect_stack(): collation(NULL), len } bool expecting_field_type(enum_field_types type) { + if (unlikely((uint)type > MAX_EXPECT_FIELD_TYPES)) + { + // Unknown type, can't be expected + return false; + } return bitmap_is_set(&expect_field_type_mask, (uint) type); } void expect_no_field_type() @@ -433,6 +442,11 @@ Ndb_expect_stack(): collation(NULL), len } bool expecting_field_result(Item_result result) { + if (unlikely((uint)result > MAX_EXPECT_FIELD_RESULTS)) + { + // Unknown result, can't be expected + return false; + } return bitmap_is_set(&expect_field_result_mask, (uint) result); } @@ -484,6 +498,12 @@ Ndb_expect_stack(): collation(NULL), len } private: + my_bitmap_map + m_expect_buf[bitmap_buffer_size(MAX_EXPECT_ITEMS)]; + my_bitmap_map + m_expect_field_type_buf[bitmap_buffer_size(MAX_EXPECT_FIELD_TYPES)]; + my_bitmap_map + m_expect_field_result_buf[bitmap_buffer_size(MAX_EXPECT_FIELD_RESULTS)]; MY_BITMAP expect_mask; MY_BITMAP expect_field_type_mask; MY_BITMAP expect_field_result_mask; @@ -651,7 +671,7 @@ public: {} ~ha_ndbcluster_cond() { if (m_cond_stack) delete m_cond_stack; } - const COND *cond_push(const COND *cond, + const Item *cond_push(const Item *cond, TABLE *table, const NdbDictionary::Table *ndb_table); void cond_pop(); void cond_clear(); @@ -665,7 +685,7 @@ public: const key_range *end_key, uchar *buf); private: - bool serialize_cond(const COND *cond, Ndb_cond_stack *ndb_cond, + bool serialize_cond(const Item *cond, Ndb_cond_stack *ndb_cond, TABLE *table, const NdbDictionary::Table *ndb_table); int build_scan_filter_predicate(Ndb_cond* &cond, NdbScanFilter* filter, === modified file 'sql/ha_ndbcluster_glue.h' --- a/sql/ha_ndbcluster_glue.h 2010-11-17 08:10:15 +0000 +++ b/sql/ha_ndbcluster_glue.h 2011-01-14 15:12:39 +0000 @@ -115,6 +115,28 @@ enum column_format_type { #endif +#if MYSQL_VERSION_ID >= 50600 + +/* No support for --server-id-bits and thd->unmasked_server_id, yet */ +#define NDB_WITHOUT_SERVER_ID_BITS + +#endif + +extern ulong opt_server_id_mask; + +static inline +uint32 thd_unmasked_server_id(const THD* thd) +{ +#ifndef NDB_WITHOUT_SERVER_ID_BITS + const uint32 unmasked_server_id = thd->unmasked_server_id; + assert(thd->server_id == (thd->unmasked_server_id & opt_server_id_mask)); + return unmasked_server_id; +#else + return thd->server_id; +#endif +} + + /* extract the bitmask of options from THD */ static inline ulonglong thd_options(const THD * thd) @@ -127,6 +149,18 @@ ulonglong thd_options(const THD * thd) #endif } +/* set the "command" member of thd */ +static inline +void thd_set_command(THD* thd, enum enum_server_command command) +{ +#if MYSQL_VERSION_ID < 50600 + thd->command = command; +#else + /* "command" renamed to "m_command", use accessor function */ + thd->set_command(command); +#endif +} + /* get pointer to diagnostic area for statement from THD */ static inline Diagnostics_area* thd_stmt_da(THD* thd) @@ -286,4 +320,11 @@ bool mysql_truncate_table(THD *thd, TABL #endif } +#if MYSQL_VERSION_ID >= 50600 + +/* New multi range read interface replaced original mrr */ +#define NDB_WITH_NEW_MRR_INTERFACE + +#endif + #endif === modified file 'sql/item.h' --- a/sql/item.h 2010-11-09 09:29:29 +0000 +++ b/sql/item.h 2011-01-14 14:02:55 +0000 @@ -490,12 +490,7 @@ public: SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER, PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM, XPATH_NODESET, XPATH_NODESET_CMP, -#ifndef MCP_BUG58075 - VIEW_FIXER_ITEM, - MAX_NUM_ITEMS /* Always last */ -#else VIEW_FIXER_ITEM -#endif }; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; === modified file 'sql/item_cmpfunc.cc' --- a/sql/item_cmpfunc.cc 2010-12-03 16:59:43 +0000 +++ b/sql/item_cmpfunc.cc 2011-01-17 12:08:49 +0000 @@ -5598,15 +5598,25 @@ longlong Item_equal::val_int() return 0; List_iterator_fast it(fields); Item *item= const_item ? const_item : it++; +#ifndef MCP_BUG57034 eval_item->store_value(item); if ((null_value= item->null_value)) return 0; +#else + if ((null_value= item->null_value)) + return 0; + eval_item->store_value(item); +#endif while ((item_field= it++)) { /* Skip fields of non-const tables. They haven't been read yet */ if (item_field->field->table->const_table) { +#ifndef MCP_BUG57034 if (eval_item->cmp(item_field) || (null_value= item_field->null_value)) +#else + if ((null_value= item_field->null_value) || eval_item->cmp(item_field)) +#endif return 0; } } === modified file 'sql/item_subselect.cc' --- a/sql/item_subselect.cc 2011-01-13 12:28:49 +0000 +++ b/sql/item_subselect.cc 2011-01-17 12:08:49 +0000 @@ -1121,7 +1121,9 @@ Item_in_subselect::single_value_transfor select_lex->having= join->having= and_items(join->having, item); if (join->having == item) item->name= (char*)in_having_cond; +#ifndef MCP_BUG58818 select_lex->having->top_level_item(); +#endif select_lex->having_fix_field= 1; /* we do not check join->having->fixed, because Item_and (from and_items) === modified file 'sql/rpl_utility.cc' --- a/sql/rpl_utility.cc 2010-11-23 14:45:43 +0000 +++ b/sql/rpl_utility.cc 2011-01-14 14:02:55 +0000 @@ -736,8 +736,6 @@ can_convert_field_to(Field *field, case MYSQL_TYPE_NULL: case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: - - case MYSQL_NUM_FIELD_TYPES: DBUG_RETURN(false); } DBUG_RETURN(false); // To keep GCC happy === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2011-01-04 14:50:54 +0000 +++ b/sql/sql_select.cc 2011-01-17 12:08:49 +0000 @@ -3411,7 +3411,30 @@ add_key_field(KEY_FIELD **key_fields,uin eq_func is NEVER true when num_values > 1 */ if (!eq_func) +#ifndef MCP_BUG57030 return; +#else + { + /* + Additional optimization: if we're processing + "t.key BETWEEN c1 AND c1" then proceed as if we were processing + "t.key = c1". + TODO: This is a very limited fix. A more generic fix is possible. + There are 2 options: + A) Make equality propagation code be able to handle BETWEEN + (including cases like t1.key BETWEEN t2.key AND t3.key) + B) Make range optimizer to infer additional "t.key = c" equalities + and use them in equality propagation process (see details in + OptimizerKBAndTodo) + */ + if ((cond->functype() != Item_func::BETWEEN) || + ((Item_func_between*) cond)->negated || + !value[0]->eq(value[1], field->binary())) + return; + eq_func= TRUE; + } + +#endif if (field->result_type() == STRING_RESULT) { if ((*value)->result_type() != STRING_RESULT) @@ -3607,6 +3630,7 @@ add_key_fields(JOIN *join, KEY_FIELD **k case Item_func::OPTIMIZE_KEY: { Item **values; +#ifndef MCP_BUG57030 /* Build list of possible keys for 'a BETWEEN low AND high'. It is handled similar to the equivalent condition @@ -3657,7 +3681,7 @@ add_key_fields(JOIN *join, KEY_FIELD **k { field_item= (Item_field *) (values[i]->real_item()); add_key_equal_fields(key_fields, *and_level, cond_func, - field_item, equal_func, &values[0], + field_item, equal_func, values, 1, usable_tables, sargables); } } @@ -3666,6 +3690,11 @@ add_key_fields(JOIN *join, KEY_FIELD **k // IN, NE else if (is_local_field (cond_func->key_item()) && !(cond_func->used_tables() & OUTER_REF_TABLE_BIT)) +#else + // BETWEEN, IN, NE + if (is_local_field (cond_func->key_item()) && + !(cond_func->used_tables() & OUTER_REF_TABLE_BIT)) +#endif /* MCP_BUG57030 */ { values= cond_func->arguments()+1; if (cond_func->functype() == Item_func::NE_FUNC && @@ -3679,6 +3708,23 @@ add_key_fields(JOIN *join, KEY_FIELD **k cond_func->argument_count()-1, usable_tables, sargables); } +#ifdef MCP_BUG57030 + if (cond_func->functype() == Item_func::BETWEEN) + { + values= cond_func->arguments(); + for (uint i= 1 ; i < cond_func->argument_count() ; i++) + { + Item_field *field_item; + if (is_local_field (cond_func->arguments()[i])) + { + field_item= (Item_field *) (cond_func->arguments()[i]->real_item()); + add_key_equal_fields(key_fields, *and_level, cond_func, + field_item, 0, values, 1, usable_tables, + sargables); + } + } + } +#endif break; } case Item_func::OPTIMIZE_OP: @@ -5884,6 +5930,7 @@ static bool create_ref_for_key(JOIN *joi j->ref.null_rejecting |= 1 << i; keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; +#ifndef MCP_BUG58628 store_key* key= get_store_key(thd, keyuse,join->const_table_map, &keyinfo->key_part[i], @@ -5913,6 +5960,25 @@ static bool create_ref_for_key(JOIN *joi *ref_key++= key; // Reevaluate in JOIN::exec() } } +#else + if (!keyuse->used_tables && + !(join->select_options & SELECT_DESCRIBE)) + { // Compare against constant + store_key_item tmp(thd, keyinfo->key_part[i].field, + key_buff + maybe_null, + maybe_null ? key_buff : 0, + keyinfo->key_part[i].length, keyuse->val); + if (thd->is_fatal_error) + DBUG_RETURN(TRUE); + tmp.copy(); + } + else + *ref_key++= get_store_key(thd, + keyuse,join->const_table_map, + &keyinfo->key_part[i], + key_buff, maybe_null); +#endif + /* Remember if we are going to use REF_OR_NULL But only if field _really_ can be null i.e. we force JT_REF @@ -6478,7 +6544,11 @@ make_join_select(JOIN *join,SQL_SELECT * if (thd->variables.engine_condition_pushdown) { COND *push_cond= +#ifndef MCP_BUG58134 make_cond_for_table(tmp, tab->table->map, tab->table->map); +#else + make_cond_for_table(tmp, current_map, current_map); +#endif if (push_cond) { /* Push condition to handler */ @@ -11937,7 +12007,11 @@ join_read_const_table(JOIN_TAB *tab, POS /* Mark for EXPLAIN that the row was not found */ pos->records_read=0.0; pos->ref_depend_map= 0; +#ifndef MCP_BUG58422 if (!table->pos_in_table_list->outer_join || error > 0) +#else + if (!table->maybe_null || error > 0) +#endif DBUG_RETURN(error); } } @@ -11958,7 +12032,11 @@ join_read_const_table(JOIN_TAB *tab, POS /* Mark for EXPLAIN that the row was not found */ pos->records_read=0.0; pos->ref_depend_map= 0; +#ifndef MCP_BUG58422 if (!table->pos_in_table_list->outer_join || error > 0) +#else + if (!table->maybe_null || error > 0) +#endif DBUG_RETURN(error); } } @@ -13160,6 +13238,7 @@ part_of_refkey(TABLE *table,Field *field KEY_PART_INFO *key_part= table->key_info[table->reginfo.join_tab->ref.key].key_part; +#ifndef MCP_BUG58626 uint part; /* If execution plan may use 'Full scan on NULL key', There might @@ -13172,6 +13251,9 @@ part_of_refkey(TABLE *table,Field *field } for (part=0 ; part < ref_parts ; part++,key_part++) +#else + for (uint part=0 ; part < ref_parts ; part++,key_part++) +#endif { if (field->eq(key_part->field) && !(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART))) === modified file 'sql/sql_select.h' --- a/sql/sql_select.h 2010-12-01 12:31:27 +0000 +++ b/sql/sql_select.h 2011-01-17 12:08:49 +0000 @@ -761,8 +761,14 @@ public: store_key_const_item(THD *thd, Field *to_field_arg, uchar *ptr, uchar *null_ptr_arg, uint length, Item *item_arg) +#ifndef MCP_BUG58628 :store_key_item(thd, to_field_arg, ptr, null_ptr_arg, length, item_arg), inited(0) +#else + :store_key_item(thd, to_field_arg,ptr, + null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ? + &err : (uchar*) 0, length, item_arg), inited(0) +#endif { } const char *name() const { return "const"; } @@ -770,6 +776,7 @@ public: protected: enum store_key_result copy_inner() { +#ifndef MCP_BUG58628 if (!inited) { inited=1; @@ -777,6 +784,25 @@ protected: if (res && !err) err= res; } +#else + int res; + if (!inited) + { + inited=1; + if ((res= item->save_in_field(to_field, 1))) + { + if (!err) + err= res < 0 ? 1 : res; /* 1=STORE_KEY_FATAL */ + } + /* + Item::save_in_field() may call Item::val_xxx(). And if this is a subquery + we need to check for errors executing it and react accordingly + */ + if (!err && to_field->table->in_use->is_error()) + err= 1; /* STORE_KEY_FATAL */ + } + null_key= to_field->is_null() || item->null_value; +#endif return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err); } }; === modified file 'storage/ndb/include/kernel/signaldata/NodeFailRep.hpp' --- a/storage/ndb/include/kernel/signaldata/NodeFailRep.hpp 2009-10-08 10:19:19 +0000 +++ b/storage/ndb/include/kernel/signaldata/NodeFailRep.hpp 2011-01-10 11:22:17 +0000 @@ -29,7 +29,7 @@ */ struct NodeFailRep { STATIC_CONST( SignalLength = 3 + NdbNodeBitmask::Size ); - + STATIC_CONST( SignalLengthLong = 3 + NodeBitmask::Size ); Uint32 failNo; /** === modified file 'storage/ndb/include/ndb_config.h.in' --- a/storage/ndb/include/ndb_config.h.in 2010-11-18 09:38:59 +0000 +++ b/storage/ndb/include/ndb_config.h.in 2011-01-11 08:39:44 +0000 @@ -35,3 +35,9 @@ #cmakedefine HAVE_ATOMIC_H 1 #cmakedefine HAVE_SUN_PREFETCH_H 1 #cmakedefine NDB_PORT @NDB_PORT@ +#cmakedefine HAVE_MLOCK 1 +#cmakedefine HAVE_FFS 1 +#cmakedefine HAVE___BUILTIN_FFS 1 +#cmakedefine HAVE__BITSCANFORWARD 1 +#cmakedefine HAVE_PTHREAD_MUTEXATTR_INIT 1 +#cmakedefine HAVE_PTHREAD_MUTEXATTR_SETTYPE 1 === modified file 'storage/ndb/include/ndbapi/Ndb.hpp' --- a/storage/ndb/include/ndbapi/Ndb.hpp 2010-10-15 21:04:14 +0000 +++ b/storage/ndb/include/ndbapi/Ndb.hpp 2011-01-17 12:08:49 +0000 @@ -1773,7 +1773,6 @@ private: const char* aCatalogName, const char* aSchemaName); void connected(Uint32 block_reference); - void report_node_connected(Uint32 nodeId); NdbTransaction* startTransactionLocal(Uint32 aPrio, Uint32 aFragmentId); === modified file 'storage/ndb/include/util/Bitmask.hpp' --- a/storage/ndb/include/util/Bitmask.hpp 2011-01-05 19:52:51 +0000 +++ b/storage/ndb/include/util/Bitmask.hpp 2011-01-09 11:06:50 +0000 @@ -21,6 +21,10 @@ #include +#ifdef HAVE__BITSCANFORWARD +#include +#endif + /** * Bitmask implementation. Size (in 32-bit words) is given explicitly * (as first argument). All methods are static. @@ -362,18 +366,23 @@ inline Uint32 BitmaskImpl::ffs(Uint32 x) { -#if defined(__GNUC__) -#if defined(__x86_64__) || defined (__i386__) +#if defined(__GNUC__) && (defined(__x86_64__) || defined (__i386__)) asm("bsf %1,%0" : "=r" (x) : "rm" (x)); return x; -#elif HAVE___BUILTIN_FFS +#elif defined HAVE___BUILTIN_FFS /** * gcc defined ffs(0) == 0, and returned indexes 1-32 */ return __builtin_ffs(x) - 1; -#endif +#elif defined HAVE__BITSCANFORWARD + unsigned long r; + unsigned char res = _BitScanForward(&r, (unsigned long)x); + assert(res > 0); + return (Uint32)r; +#elif defined HAVE_FFS + return ::ffs(x) - 1; #else int b = 0; if (!(x & 0xffff)) === modified file 'storage/ndb/ndb_configure.cmake' --- a/storage/ndb/ndb_configure.cmake 2010-12-17 15:05:09 +0000 +++ b/storage/ndb/ndb_configure.cmake 2011-01-09 16:31:17 +0000 @@ -21,6 +21,7 @@ INCLUDE(CheckFunctionExists) INCLUDE(CheckIncludeFiles) INCLUDE(CheckCSourceCompiles) +INCLUDE(CheckCXXSourceCompiles) INCLUDE(CheckCXXSourceRuns) INCLUDE(ndb_require_variable) @@ -39,9 +40,32 @@ CHECK_FUNCTION_EXISTS(sysconf HAVE_SYSCO CHECK_FUNCTION_EXISTS(directio HAVE_DIRECTIO) CHECK_FUNCTION_EXISTS(atomic_swap_32 HAVE_ATOMIC_SWAP32) CHECK_FUNCTION_EXISTS(mlock HAVE_MLOCK) +CHECK_FUNCTION_EXISTS(ffs HAVE_FFS) +CHECK_FUNCTION_EXISTS(pthread_mutexattr_init HAVE_PTHREAD_MUTEXATTR_INIT) +CHECK_FUNCTION_EXISTS(pthread_mutexattr_settype HAVE_PTHREAD_MUTEXATTR_SETTYPE) CHECK_INCLUDE_FILES(sun_prefetch.h HAVE_SUN_PREFETCH_H) +CHECK_CXX_SOURCE_COMPILES(" +unsigned A = 7; +int main() +{ + unsigned a = __builtin_ffs(A); + return 0; +}" +HAVE___BUILTIN_FFS) + +CHECK_C_SOURCE_COMPILES(" +#include +unsigned long A = 7; +int main() +{ + unsigned long a; + unsigned char res = _BitScanForward(&a, A); + return (int)a; +}" +HAVE__BITSCANFORWARD) + # Linux scheduling and locking support CHECK_C_SOURCE_COMPILES(" #ifndef _GNU_SOURCE === modified file 'storage/ndb/ndb_configure.m4' --- a/storage/ndb/ndb_configure.m4 2011-01-06 21:19:05 +0000 +++ b/storage/ndb/ndb_configure.m4 2011-01-17 12:08:49 +0000 @@ -172,6 +172,17 @@ AC_DEFUN([NDB_COMPILER_FEATURES], [Compiler supports __has_trivial_constructor(typename)])], AC_MSG_RESULT([no]) ) + + # need c++ here, cause c will accept function wo/ prototype + # which will later lead to link error + AC_MSG_CHECKING([checking __builtin_ffs(unsigned)]) + AC_TRY_COMPILE([unsigned A = 7;],[ unsigned a = __builtin_ffs(A)], + [ AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE___BUILTIN_FFS], [1], + [Compiler supports __builtin_ffs])], + AC_MSG_RESULT([no]) + ) + AC_LANG_POP([C++]) ]) @@ -400,7 +411,8 @@ AC_DEFUN([MYSQL_SETUP_NDBCLUSTER], [ AC_CHECK_FUNCS(pthread_self \ sched_get_priority_min sched_get_priority_max sched_setaffinity \ sched_setscheduler processor_bind epoll_create \ - posix_memalign memalign sysconf directio atomic_swap_32 mlock) + posix_memalign memalign sysconf directio atomic_swap_32 mlock \ + ffs pthread_mutexattr_init pthread_mutexattr_settype) AC_MSG_CHECKING(for Linux scheduling and locking support) AC_TRY_LINK( === modified file 'storage/ndb/src/common/portlib/NdbMutex.c' --- a/storage/ndb/src/common/portlib/NdbMutex.c 2010-10-12 14:53:28 +0000 +++ b/storage/ndb/src/common/portlib/NdbMutex.c 2011-01-09 16:31:17 +0000 @@ -32,10 +32,13 @@ NdbMutex* NdbMutex_Create(void) if (pNdbMutex == NULL) return NULL; - result = pthread_mutex_init(pNdbMutex, NULL); - assert(result == 0); - - return pNdbMutex; + result = NdbMutex_Init(pNdbMutex); + if (result == 0) + { + return pNdbMutex; + } + NdbMem_Free(pNdbMutex); + return 0; } int NdbMutex_Init(NdbMutex* pNdbMutex) @@ -43,9 +46,19 @@ int NdbMutex_Init(NdbMutex* pNdbMutex) int result; DBUG_ENTER("NdbMutex_Init"); - result = pthread_mutex_init(pNdbMutex, NULL); +#if defined(VM_TRACE) && \ + defined(HAVE_PTHREAD_MUTEXATTR_INIT) && \ + defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) + + pthread_mutexattr_t t; + pthread_mutexattr_init(&t); + pthread_mutexattr_settype(&t, PTHREAD_MUTEX_ERRORCHECK); + result = pthread_mutex_init(pNdbMutex, &t); assert(result == 0); - + pthread_mutexattr_destroy(&t); +#else + result = pthread_mutex_init(pNdbMutex, 0); +#endif DBUG_RETURN(result); } @@ -72,7 +85,8 @@ int NdbMutex_Lock(NdbMutex* p_mutex) return -1; result = pthread_mutex_lock(p_mutex); - + assert(result == 0); + return result; } @@ -85,7 +99,8 @@ int NdbMutex_Unlock(NdbMutex* p_mutex) return -1; result = pthread_mutex_unlock(p_mutex); - + assert(result == 0); + return result; } @@ -96,6 +111,7 @@ int NdbMutex_Trylock(NdbMutex* p_mutex) if (p_mutex != NULL) { result = pthread_mutex_trylock(p_mutex); + assert(result == 0 || result == EBUSY); } return result; === modified file 'storage/ndb/src/kernel/blocks/ERROR_codes.txt' --- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt 2011-01-06 21:19:05 +0000 +++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt 2011-01-17 12:08:49 +0000 @@ -6,7 +6,7 @@ Next DBTUP 4035 Next DBLQH 5064 Next DBDICT 6026 Next DBDIH 7229 -Next DBTC 8088 +Next DBTC 8090 Next CMVMI 9000 Next BACKUP 10042 Next DBUTIL 11002 === modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp' --- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2011-01-06 21:19:05 +0000 +++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2011-01-17 12:08:49 +0000 @@ -5078,7 +5078,11 @@ void Dbtc::commit020Lab(Signal* signal) Tcount += sendCommitLqh(signal, localTcConnectptr.p); if (localTcConnectptr.i != RNIL) { - if (Tcount < 16 && !ERROR_INSERTED(8057) && !ERROR_INSERTED(8073)) { + if (Tcount < 16 && + ! (ERROR_INSERTED(8057) || + ERROR_INSERTED(8073) || + ERROR_INSERTED(8089))) + { ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord); jam(); @@ -5100,6 +5104,11 @@ void Dbtc::commit020Lab(Signal* signal) signal->theData[0] = TcContinueB::ZSEND_COMMIT_LOOP; signal->theData[1] = apiConnectptr.i; signal->theData[2] = localTcConnectptr.i; + if (ERROR_INSERTED(8089)) + { + sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 100, 3); + return; + } sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB); return; }//if @@ -5108,6 +5117,9 @@ void Dbtc::commit020Lab(Signal* signal) if (ERROR_INSERTED(8057)) CLEAR_ERROR_INSERT_VALUE; + if (ERROR_INSERTED(8089)) + CLEAR_ERROR_INSERT_VALUE; + regApiPtr->apiConnectstate = CS_COMMIT_SENT; return; }//if @@ -6813,9 +6825,13 @@ ABORT020: if (tcConnectptr.p->nextTcConnect != RNIL) { jam(); tcConnectptr.i = tcConnectptr.p->nextTcConnect; - if (TloopCount < 1024) { + if (TloopCount < 1024 && ! + (ERROR_INSERTED(8089))) + { goto ABORT020; - } else { + } + else + { jam(); /*--------------------------------------------------------------------- * Reset timer to avoid time-out in real-time break. @@ -6827,10 +6843,21 @@ ABORT020: signal->theData[0] = TcContinueB::ZABORT_BREAK; signal->theData[1] = tcConnectptr.i; signal->theData[2] = apiConnectptr.i; + if (ERROR_INSERTED(8089)) + { + sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 100, 3); + return; + } sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB); return; }//if }//if + + if (ERROR_INSERTED(8089)) + { + CLEAR_ERROR_INSERT_VALUE; + } + if (apiConnectptr.p->counter > 0) { jam(); setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__); === modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp' --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2011-01-06 21:19:05 +0000 +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2011-01-17 12:08:49 +0000 @@ -286,8 +286,9 @@ Dbtup::setup_read(KeyReqStruct *req_stru Uint32 currOp= currOpPtr.p->op_struct.op_type; + bool is_insert = (bits & Tuple_header::ALLOC); if((found && currOp == ZDELETE) || - ((dirty || !found) && currOp == ZINSERT)) + ((dirty || !found) && is_insert)) { terrorCode= ZTUPLE_DELETED_ERROR; break; === modified file 'storage/ndb/src/kernel/blocks/lgman.cpp' --- a/storage/ndb/src/kernel/blocks/lgman.cpp 2010-08-17 11:47:55 +0000 +++ b/storage/ndb/src/kernel/blocks/lgman.cpp 2011-01-15 06:29:18 +0000 @@ -312,7 +312,8 @@ Lgman::execCONTINUEB(Signal* signal){ jam(); Ptr ptr; m_logfile_group_pool.getPtr(ptr, ptrI); - if (ptr.p->m_state & Logfile_group::LG_THREAD_MASK) + if ((ptr.p->m_state & Logfile_group::LG_THREAD_MASK) || + ptr.p->m_outstanding_fs > 0) { jam(); sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, === modified file 'storage/ndb/src/kernel/blocks/tsman.cpp' --- a/storage/ndb/src/kernel/blocks/tsman.cpp 2010-02-09 05:24:15 +0000 +++ b/storage/ndb/src/kernel/blocks/tsman.cpp 2011-01-15 06:29:18 +0000 @@ -486,6 +486,13 @@ Tsman::execDROP_FILEGROUP_IMPL_REQ(Signa ptr.p->m_state = Tablespace::TS_DROPPING; break; case DropFilegroupImplReq::Commit: + if (ptr.p->m_ref_count) + { + jam(); + sendSignalWithDelay(reference(), GSN_DROP_FILEGROUP_REQ, signal, + 100, signal->getLength()); + return; + } m_tablespace_list.remove(ptr); m_tablespace_hash.release(ptr); break; @@ -1482,6 +1489,14 @@ Tsman::execDROP_FILE_IMPL_REQ(Signal* si } case DropFileImplReq::Commit: ndbrequire(find_file_by_id(file_ptr, fg_ptr.p->m_meta_files, req.file_id)); + if (file_ptr.p->m_ref_count) + { + jam(); + sendSignalWithDelay(reference(), GSN_DROP_FILE_REQ, signal, + 100, signal->getLength()); + return; + } + file_ptr.p->m_create.m_extent_pages = file_ptr.p->m_online.m_offset_data_pages - 1; file_ptr.p->m_create.m_senderRef = req.senderRef; @@ -1535,6 +1550,7 @@ Tsman::Tablespace::Tablespace(Tsman* ts, m_logfile_group_id = req->tablespace.logfile_group_id; m_tablespace_id = req->filegroup_id; m_version = req->filegroup_version; + m_ref_count = 0; m_extent_size = (Uint32)DIV(req->tablespace.extent_size, File_formats::NDB_PAGE_SIZE); #if defined VM_TRACE || defined ERROR_INSERT @@ -1549,6 +1565,7 @@ Tsman::Datafile::Datafile(const struct C m_file_no = RNIL; m_fd = RNIL; m_online.m_first_free_extent = RNIL; + m_ref_count = 0; m_create.m_senderRef = req->senderRef; // During META m_create.m_senderData = req->senderData; // During META @@ -2127,8 +2144,10 @@ Tsman::execEND_LCP_REQ(Signal* signal) * Move extents from "lcp" free list to real free list */ Ptr ptr; - if(m_tablespace_list.first(ptr)) + if (m_tablespace_list.first(ptr)) { + jam(); + ptr.p->m_ref_count ++; signal->theData[0] = TsmanContinueB::END_LCP; signal->theData[1] = ptr.i; signal->theData[2] = 0; // free @@ -2142,6 +2161,8 @@ Tsman::end_lcp(Signal* signal, Uint32 pt { Ptr ptr; m_tablespace_list.getPtr(ptr, ptrI); + ndbrequire(ptr.p->m_ref_count); + ptr.p->m_ref_count--; Ptr file; file.i = filePtrI; @@ -2162,6 +2183,8 @@ Tsman::end_lcp(Signal* signal, Uint32 pt else { tmp.getPtr(file); + ndbrequire(file.p->m_ref_count); + file.p->m_ref_count--; } break; } @@ -2181,6 +2204,8 @@ Tsman::end_lcp(Signal* signal, Uint32 pt else { tmp.getPtr(file); + ndbrequire(file.p->m_ref_count); + file.p->m_ref_count--; } break; } @@ -2263,10 +2288,19 @@ Tsman::end_lcp(Signal* signal, Uint32 pt m_tablespace_list.next(ptr); } } + else + { + jam(); + ndbrequire(ptr.i != RNIL); + m_file_pool.getPtr(file); + file.p->m_ref_count++; + } next: if(ptr.i != RNIL) { + ptr.p->m_ref_count++; + signal->theData[0] = TsmanContinueB::END_LCP; signal->theData[1] = ptr.i; signal->theData[2] = list; === modified file 'storage/ndb/src/kernel/blocks/tsman.hpp' --- a/storage/ndb/src/kernel/blocks/tsman.hpp 2009-10-08 11:15:24 +0000 +++ b/storage/ndb/src/kernel/blocks/tsman.hpp 2011-01-15 06:29:18 +0000 @@ -96,7 +96,8 @@ public: Uint32 m_tablespace_ptr_i; Uint32 m_extent_size; - Uint32 m_state; + Uint16 m_state; + Uint16 m_ref_count; enum FileState { @@ -160,7 +161,8 @@ public: Uint32 m_tablespace_id; }; Uint32 m_version; - Uint32 m_state; + Uint16 m_state; + Uint16 m_ref_count; // Can't release when m_ref_count > 0 enum TablespaceState { === modified file 'storage/ndb/src/kernel/vm/mt.cpp' --- a/storage/ndb/src/kernel/vm/mt.cpp 2011-01-06 21:19:05 +0000 +++ b/storage/ndb/src/kernel/vm/mt.cpp 2011-01-17 12:08:49 +0000 @@ -370,7 +370,7 @@ inline void lock(struct thr_mutex* sl) { - NdbMutex_Lock(&sl.m_mutex); + NdbMutex_Lock(&sl->m_mutex); } template @@ -379,7 +379,7 @@ inline void unlock(struct thr_mutex* sl) { - NdbMutex_Unlock(&sl.m_mutex); + NdbMutex_Unlock(&sl->m_mutex); } template @@ -388,7 +388,7 @@ inline int trylock(struct thr_mutex * sl) { - return NdbMutex_Trylock(&sl.m_mutex); + return NdbMutex_Trylock(&sl->m_mutex); } /** === modified file 'storage/ndb/src/mgmsrv/ConfigManager.cpp' --- a/storage/ndb/src/mgmsrv/ConfigManager.cpp 2010-09-30 09:32:28 +0000 +++ b/storage/ndb/src/mgmsrv/ConfigManager.cpp 2011-01-11 19:13:37 +0000 @@ -1924,6 +1924,7 @@ ConfigManager::run() break; case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: break; default: @@ -1938,6 +1939,7 @@ ConfigManager::run() } } stop_checkers(); + ss.unlock(); } === modified file 'storage/ndb/src/mgmsrv/InitConfigFileParser.cpp' --- a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp 2010-10-13 09:33:02 +0000 +++ b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp 2011-01-14 16:13:34 +0000 @@ -17,6 +17,7 @@ */ #include +#include #include "InitConfigFileParser.hpp" #include "Config.hpp" @@ -737,6 +738,9 @@ load_defaults(Vector& BaseString group_suffix; const char *save_file = my_defaults_file; +#if MYSQL_VERSION_ID >= 50508 + const +#endif char *save_extra_file = my_defaults_extra_file; const char *save_group_suffix = my_defaults_group_suffix; === modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp' --- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2010-12-15 06:07:35 +0000 +++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2011-01-10 13:30:14 +0000 @@ -409,7 +409,8 @@ MgmtSrvr::start_transporter(const Config Register ourself at TransporterFacade to be able to receive signals and to be notified when a database process has died. */ - if ((_blockNumber= open(theFacade)) == -1) + Uint32 res; + if ((res = open(theFacade)) == 0) { g_eventLogger->error("Failed to open block in TransporterFacade"); theFacade->stop_instance(); @@ -417,6 +418,7 @@ MgmtSrvr::start_transporter(const Config theFacade = 0; DBUG_RETURN(false); } + _blockNumber = refToBlock(res); /** * Need to call ->open() prior to actually starting TF @@ -435,7 +437,7 @@ MgmtSrvr::start_transporter(const Config /** * Wait for loopback interface to be enabled */ - while (!theFacade->isConnected(_ownNodeId)) + while (!theFacade->ext_isConnected(_ownNodeId)) { NdbSleep_MilliSleep(20); } @@ -450,7 +452,7 @@ MgmtSrvr::start_transporter(const Config is not dependent on heartbeat settings in the configuration */ - theFacade->theClusterMgr->set_max_api_reg_req_interval(100); + theFacade->ext_set_max_api_reg_req_interval(100); DBUG_RETURN(true); } @@ -801,10 +803,10 @@ int MgmtSrvr::okToSendTo(NodeId nodeId, return WRONG_PROCESS_TYPE; // Check if we have contact with it if(unCond){ - if(theFacade->theClusterMgr->getNodeInfo(nodeId).is_confirmed()) + if (getNodeInfo(nodeId).is_confirmed()) return 0; } - else if (theFacade->get_node_alive(nodeId) == true) + else if (getNodeInfo(nodeId).m_alive == true) return 0; return NO_CONTACT_WITH_PROCESS; } @@ -880,7 +882,7 @@ MgmtSrvr::versionNode(int nodeId, Uint32 } else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) { - trp_node node = theFacade->theClusterMgr->getNodeInfo(nodeId); + trp_node node = getNodeInfo(nodeId); if(node.is_connected()) { version= node.m_info.m_version; @@ -971,6 +973,7 @@ MgmtSrvr::sendVersionReq(int v_nodeId, } case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: // Ignore continue; default: @@ -1292,6 +1295,7 @@ int MgmtSrvr::sendSTOP_REQ(const Vector< } case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: continue; default: report_unknown_signal(signal); @@ -1421,7 +1425,7 @@ bool MgmtSrvr::is_any_node_stopping() trp_node node; while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { - node = theFacade->theClusterMgr->getNodeInfo(nodeId); + node = getNodeInfo(nodeId); if((node.m_state.startLevel == NodeState::SL_STOPPING_1) || (node.m_state.startLevel == NodeState::SL_STOPPING_2) || (node.m_state.startLevel == NodeState::SL_STOPPING_3) || @@ -1437,7 +1441,7 @@ bool MgmtSrvr::is_any_node_starting() trp_node node; while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { - node = theFacade->theClusterMgr->getNodeInfo(nodeId); + node = getNodeInfo(nodeId); if((node.m_state.startLevel == NodeState::SL_STARTING)) return true; // At least one node was starting } @@ -1450,7 +1454,7 @@ bool MgmtSrvr::is_cluster_single_user() trp_node node; while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { - node = theFacade->theClusterMgr->getNodeInfo(nodeId); + node = getNodeInfo(nodeId); if((node.m_state.startLevel == NodeState::SL_SINGLEUSER)) return true; // Cluster is in single user modes } @@ -1669,12 +1673,10 @@ MgmtSrvr::exitSingleUser(int * stopCount * Status ****************************************************************************/ -#include - void MgmtSrvr::updateStatus() { - theFacade->theClusterMgr->forceHB(); + theFacade->ext_forceHB(); } int @@ -1696,8 +1698,7 @@ MgmtSrvr::status(int nodeId, *address= get_connect_address(nodeId); } - const trp_node node = - theFacade->theClusterMgr->getNodeInfo(nodeId); + const trp_node node = getNodeInfo(nodeId); if(!node.is_connected()){ * _status = NDB_MGM_NODE_STATUS_NO_CONTACT; @@ -1803,7 +1804,7 @@ MgmtSrvr::setEventReportingLevelImpl(int continue; if (okToSendTo(nodeId, true)) { - if (theFacade->theClusterMgr->getNodeInfo(nodeId).is_connected() == false) + if (getNodeInfo(nodeId).is_connected() == false) { // node not connected we can safely skip this one continue; @@ -1830,7 +1831,7 @@ MgmtSrvr::setEventReportingLevelImpl(int { if (nodeTypes[nodeId] != NODE_TYPE_DB) continue; - if (theFacade->theClusterMgr->getNodeInfo(nodeId).is_connected() == false) + if (getNodeInfo(nodeId).is_connected() == false) continue; // node is not connected, skip if (ss.sendSignal(nodeId, &ssig) == SEND_OK) nodes.set(nodeId); @@ -1884,6 +1885,7 @@ MgmtSrvr::setEventReportingLevelImpl(int } case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: continue; default: report_unknown_signal(signal); @@ -2032,6 +2034,7 @@ retry: } case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: break; default: report_unknown_signal(signal); @@ -2091,6 +2094,7 @@ MgmtSrvr::endSchemaTrans(SignalSender& s } case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: break; default: report_unknown_signal(signal); @@ -2186,6 +2190,7 @@ MgmtSrvr::createNodegroup(int *nodes, in } case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: break; default: report_unknown_signal(signal); @@ -2261,6 +2266,7 @@ MgmtSrvr::dropNodegroup(int ng) } case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: break; default: report_unknown_signal(signal); @@ -2493,16 +2499,53 @@ MgmtSrvr::trp_deliver_signal(const NdbAp case GSN_NF_COMPLETEREP: break; - case GSN_NODE_FAILREP: - break; - case GSN_TAMPER_ORD: ndbout << "TAMPER ORD" << endl; break; case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: break; + case GSN_CONNECT_REP:{ + Uint32 nodeId = signal->getDataPtr()[0]; + union { + Uint32 theData[25]; + EventReport repData; + }; + EventReport * rep = &repData; + theData[1] = nodeId; + rep->setEventType(NDB_LE_Connected); + + if (nodeTypes[nodeId] == NODE_TYPE_DB) + { + m_started_nodes.push_back(nodeId); + } + rep->setEventType(NDB_LE_Connected); + rep->setNodeId(_ownNodeId); + eventReport(theData, 1); + return; + } + case GSN_NODE_FAILREP: + { + union { + Uint32 theData[25]; + EventReport repData; + }; + EventReport * event = &repData; + event->setEventType(NDB_LE_Disconnected); + event->setNodeId(_ownNodeId); + + const NodeFailRep *rep = CAST_CONSTPTR(NodeFailRep, + signal->getDataPtr()); + for (Uint32 i = NdbNodeBitmask::find_first(rep->theNodes); + i != NdbNodeBitmask::NotFound; + i = NdbNodeBitmask::find_next(rep->theNodes, i + 1)) + { + theData[1] = i; + eventReport(theData, 1); + } + return; + } default: g_eventLogger->error("Unknown signal received. SignalNumber: " "%i from (%d, 0x%x)", @@ -2517,36 +2560,6 @@ MgmtSrvr::trp_deliver_signal(const NdbAp void MgmtSrvr::trp_node_status(Uint32 nodeId, Uint32 _event) { - DBUG_ENTER("MgmtSrvr::handleStatus"); - DBUG_PRINT("enter",("nodeid: %d, event: %u", nodeId, _event)); - - union { - Uint32 theData[25]; - EventReport repData; - }; - EventReport * rep = &repData; - NS_Event event = (NS_Event)_event; - - theData[1] = nodeId; - switch(event){ - case NS_CONNECTED: - DBUG_VOID_RETURN; - case NS_NODE_ALIVE: - if (nodeTypes[nodeId] == NODE_TYPE_DB) - { - m_started_nodes.push_back(nodeId); - } - rep->setEventType(NDB_LE_Connected); - break; - case NS_NODE_FAILED: - rep->setEventType(NDB_LE_Disconnected); - break; - case NS_NODE_NF_COMPLETE: - DBUG_VOID_RETURN; - } - rep->setNodeId(_ownNodeId); - eventReport(theData, 1); - DBUG_VOID_RETURN; } enum ndb_mgm_node_type @@ -2561,16 +2574,13 @@ MgmtSrvr::getNodeType(NodeId nodeId) con const char *MgmtSrvr::get_connect_address(Uint32 node_id) { if (m_connect_address[node_id].s_addr == 0 && - theFacade && theFacade->theTransporterRegistry && - theFacade->theClusterMgr && + theFacade && getNodeType(node_id) == NDB_MGM_NODE_TYPE_NDB) { - const trp_node &node= - theFacade->theClusterMgr->getNodeInfo(node_id); + const trp_node &node= getNodeInfo(node_id); if (node.is_connected()) { - m_connect_address[node_id]= - theFacade->theTransporterRegistry->get_connect_address(node_id); + m_connect_address[node_id] = theFacade->ext_get_connect_address(node_id); } } return inet_ntoa(m_connect_address[node_id]); @@ -2579,13 +2589,13 @@ const char *MgmtSrvr::get_connect_addres void MgmtSrvr::get_connected_nodes(NodeBitmask &connected_nodes) const { - if (theFacade && theFacade->theClusterMgr) + if (theFacade) { for(Uint32 i = 0; i < MAX_NDB_NODES; i++) { if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) { - const trp_node &node= theFacade->theClusterMgr->getNodeInfo(i); + const trp_node &node= getNodeInfo(i); connected_nodes.bitOR(node.m_state.m_connected_nodes); } } @@ -2619,7 +2629,7 @@ MgmtSrvr::alloc_node_id_req(NodeId free_ { bool next; while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && - theFacade->get_node_alive(nodeId) == false); + getNodeInfo(nodeId).m_alive == false); if (!next) return NO_CONTACT_WITH_DB_NODES; do_send = 1; @@ -2654,7 +2664,7 @@ MgmtSrvr::alloc_node_id_req(NodeId free_ { do_send = 1; nodeId = refToNode(ref->masterRef); - if (!theFacade->get_node_alive(nodeId)) + if (!getNodeInfo(nodeId).m_alive) nodeId = 0; if (ref->errorCode != AllocNodeIdRef::NotMaster) { @@ -2687,6 +2697,7 @@ MgmtSrvr::alloc_node_id_req(NodeId free_ } case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: continue; default: report_unknown_signal(signal); @@ -2894,9 +2905,7 @@ MgmtSrvr::try_alloc(unsigned id, const c /** * Make sure we're ready to accept connections from this node */ - theFacade->lock_mutex(); - theFacade->doConnect(id); - theFacade->unlock_mutex(); + theFacade->ext_doConnect(id); } g_eventLogger->info("Mgmt server state: nodeid %d reserved for ip %s, " @@ -3214,7 +3223,7 @@ MgmtSrvr::startBackup(Uint32& backupId, ndbout_c("I'm not master resending to %d", nodeId); #endif do_send = 1; // try again - if (!theFacade->get_node_alive(nodeId)) + if (!getNodeInfo(nodeId).m_alive) m_master_node = nodeId = 0; continue; } @@ -3253,6 +3262,7 @@ MgmtSrvr::startBackup(Uint32& backupId, } case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: continue; default: report_unknown_signal(signal); @@ -3270,7 +3280,7 @@ MgmtSrvr::abortBackup(Uint32 backupId) bool next; NodeId nodeId = 0; while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && - theFacade->get_node_alive(nodeId) == false); + getNodeInfo(nodeId).m_alive == false); if(!next){ return NO_CONTACT_WITH_DB_NODES; @@ -3526,9 +3536,7 @@ bool MgmtSrvr::transporter_connect(NDB_S with the new connection. Important for correct node id reservation handling */ - theFacade->lock_mutex(); - tr->update_connections(); - theFacade->unlock_mutex(); + theFacade->ext_update_connections(); DBUG_RETURN(true); } @@ -3642,6 +3650,7 @@ MgmtSrvr::change_config(Config& new_conf case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: // Ignore; break; @@ -3833,6 +3842,7 @@ MgmtSrvr::make_sync_req(SignalSender& ss } case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: break; default: return; === modified file 'storage/ndb/src/ndbapi/ClusterMgr.cpp' --- a/storage/ndb/src/ndbapi/ClusterMgr.cpp 2010-12-21 14:13:47 +0000 +++ b/storage/ndb/src/ndbapi/ClusterMgr.cpp 2011-01-10 13:30:14 +0000 @@ -73,8 +73,8 @@ ClusterMgr::ClusterMgr(TransporterFacade waitForHBCond= NdbCondition_Create(); m_auto_reconnect = -1; - int ret = this->open(&theFacade, API_CLUSTERMGR); - if (unlikely(ret < 0)) + Uint32 ret = this->open(&theFacade, API_CLUSTERMGR); + if (unlikely(ret == 0)) { ndbout_c("Failed to register ClusterMgr! ret: %d", ret); abort(); @@ -289,6 +289,14 @@ ClusterMgr::forceHB() } void +ClusterMgr::force_update_connections() +{ + theFacade.lock_mutex(); + theFacade.theTransporterRegistry->update_connections(); + theFacade.unlock_mutex(); +} + +void ClusterMgr::threadMain( ){ NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId())); @@ -427,9 +435,8 @@ ClusterMgr::trp_deliver_signal(const Ndb break; case GSN_NF_COMPLETEREP: - execNF_COMPLETEREP(theData); + execNF_COMPLETEREP(sig, ptr); break; - case GSN_ARBIT_STARTREQ: if (theArbitMgr != NULL) theArbitMgr->doStart(theData); @@ -499,11 +506,6 @@ ClusterMgr::trp_deliver_signal(const Ndb return; } -void -ClusterMgr::trp_node_status(Uint32 nodeId, Uint32 event) -{ -} - ClusterMgr::Node::Node() : hbFrequency(0), hbCounter(0) { @@ -752,17 +754,19 @@ ClusterMgr::execNODE_FAILREP(const Uint3 } void -ClusterMgr::execNF_COMPLETEREP(const Uint32 * theData){ - const NFCompleteRep * const nfComp = (NFCompleteRep *)theData; - +ClusterMgr::execNF_COMPLETEREP(const NdbApiSignal* signal, + const LinearSectionPtr ptr[3]) +{ + const NFCompleteRep * nfComp = CAST_CONSTPTR(NFCompleteRep, + signal->getDataPtr()); const NodeId nodeId = nfComp->failedNodeId; assert(nodeId > 0 && nodeId < MAX_NODES); trp_node & node = theNodes[nodeId]; if (node.nfCompleteRep == false) { - theFacade.trp_node_status(nodeId, NS_NODE_NF_COMPLETE); node.nfCompleteRep = true; + theFacade.for_each(this, signal, ptr); } } @@ -799,7 +803,13 @@ ClusterMgr::reportConnected(NodeId nodeI theNode.m_state.startLevel = NodeState::SL_NOTHING; theNode.minDbVersion = 0; - theFacade.trp_node_status(nodeId, NS_NODE_ALIVE); + NdbApiSignal signal(numberToRef(API_CLUSTERMGR, getOwnNodeId())); + signal.theVerId_signalNumber = GSN_CONNECT_REP; + signal.theReceiversBlockNumber = 0; + signal.theTrace = 0; + signal.theLength = 1; + signal.getDataPtrSend()[0] = nodeId; + theFacade.for_each(this, &signal, 0); DBUG_VOID_RETURN; } @@ -844,7 +854,19 @@ ClusterMgr::reportNodeFailed(NodeId node if (disconnect || report) { - theFacade.trp_node_status(nodeId, NS_NODE_FAILED); + NdbApiSignal signal(numberToRef(API_CLUSTERMGR, getOwnNodeId())); + signal.theVerId_signalNumber = GSN_NODE_FAILREP; + signal.theReceiversBlockNumber = 0; + signal.theTrace = 0; + signal.theLength = NodeFailRep::SignalLengthLong; + + NodeFailRep * rep = CAST_PTR(NodeFailRep, signal.getDataPtrSend()); + rep->failNo = 0; + rep->masterNodeId = 0; + rep->noOfNodes = 1; + NodeBitmask::clear(rep->theNodes); + NodeBitmask::set(rep->theNodes, nodeId); + theFacade.for_each(this, &signal, 0); } if (noOfConnectedNodes == 0) @@ -867,14 +889,25 @@ ClusterMgr::reportNodeFailed(NodeId node theNode.nfCompleteRep = false; if (noOfAliveNodes == 0) { - NFCompleteRep rep; + NdbApiSignal signal(numberToRef(API_CLUSTERMGR, getOwnNodeId())); + signal.theVerId_signalNumber = GSN_NF_COMPLETEREP; + signal.theReceiversBlockNumber = 0; + signal.theTrace = 0; + signal.theLength = NFCompleteRep::SignalLength; + + NFCompleteRep * rep = CAST_PTR(NFCompleteRep, signal.getDataPtrSend()); + rep->blockNo =0; + rep->nodeId = getOwnNodeId(); + rep->unused = 0; + rep->from = __LINE__; + for (Uint32 i = 1; i < MAX_NODES; i++) { trp_node& theNode = theNodes[i]; if (theNode.defined && theNode.nfCompleteRep == false) { - rep.failedNodeId = i; - execNF_COMPLETEREP((Uint32*)&rep); + rep->failedNodeId = i; + execNF_COMPLETEREP(&signal, 0); } } } === modified file 'storage/ndb/src/ndbapi/ClusterMgr.hpp' --- a/storage/ndb/src/ndbapi/ClusterMgr.hpp 2010-12-21 13:47:51 +0000 +++ b/storage/ndb/src/ndbapi/ClusterMgr.hpp 2011-01-10 13:30:14 +0000 @@ -56,6 +56,7 @@ public: void set_max_api_reg_req_interval(unsigned int millisec) { m_max_api_reg_req_interval = millisec; } + void force_update_connections(); private: void threadMain(); @@ -116,7 +117,7 @@ private: void execAPI_REGCONF (const Uint32 * theData); void execAPI_REGREF (const Uint32 * theData); void execNODE_FAILREP (const Uint32 * theData); - void execNF_COMPLETEREP(const Uint32 * theData); + void execNF_COMPLETEREP(const NdbApiSignal*, const LinearSectionPtr ptr[]); void check_wait_for_hb(NodeId nodeId); @@ -147,7 +148,6 @@ public: */ virtual void trp_deliver_signal(const NdbApiSignal*, const LinearSectionPtr p[3]); - virtual void trp_node_status(Uint32, Uint32); }; inline === modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp' --- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp 2010-12-03 05:53:47 +0000 +++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp 2011-01-12 08:04:39 +0000 @@ -44,6 +44,7 @@ #include #include #include +#include #define DEBUG_PRINT 0 #define INCOMPATIBLE_VERSION -2 @@ -2159,6 +2160,18 @@ NdbDictInterface::execSignal(void* dictI case GSN_CREATE_HASH_MAP_CONF: tmp->execCREATE_HASH_MAP_CONF(signal, ptr); break; + case GSN_NODE_FAILREP: + { + const NodeFailRep *rep = CAST_CONSTPTR(NodeFailRep, + signal->getDataPtr()); + for (Uint32 i = NdbNodeBitmask::find_first(rep->theNodes); + i != NdbNodeBitmask::NotFound; + i = NdbNodeBitmask::find_next(rep->theNodes, i + 1)) + { + tmp->m_impl->theWaiter.nodeFail(i); + } + break; + } default: abort(); } @@ -2167,16 +2180,6 @@ NdbDictInterface::execSignal(void* dictI void NdbDictInterface::execNodeStatus(void* dictImpl, Uint32 aNode, Uint32 ns_event) { - NdbDictInterface * tmp = (NdbDictInterface*)dictImpl; - NS_Event event = (NS_Event)ns_event; - - switch(event){ - case NS_NODE_FAILED: - tmp->m_impl->theWaiter.nodeFail(aNode); - break; - default: - break; - } } int @@ -5800,7 +5803,7 @@ NdbDictInterface::forceGCPWait(int type) continue; } - m_impl->forceSend(); + m_impl->do_forceSend(); m_impl->unlock(); } return m_error.code == 0 ? 0 : -1; === modified file 'storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp' --- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp 2010-11-28 11:34:01 +0000 +++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp 2011-01-10 11:22:17 +0000 @@ -2298,12 +2298,6 @@ NdbEventBuffer::set_total_buckets(Uint32 } void -NdbEventBuffer::report_node_connected(Uint32 node_id) -{ - return; -} - -void NdbEventBuffer::report_node_failure_completed(Uint32 node_id) { m_alive_node_bit_mask.clear(node_id); === modified file 'storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp' --- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp 2010-09-29 13:25:19 +0000 +++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp 2011-01-10 11:22:17 +0000 @@ -514,7 +514,6 @@ public: int complete_cluster_failure= 0); void complete_outof_order_gcis(); - void report_node_connected(Uint32 node_id); void report_node_failure_completed(Uint32 node_id); // used by user thread === modified file 'storage/ndb/src/ndbapi/NdbImpl.hpp' --- a/storage/ndb/src/ndbapi/NdbImpl.hpp 2011-01-06 21:19:05 +0000 +++ b/storage/ndb/src/ndbapi/NdbImpl.hpp 2011-01-17 12:08:49 +0000 @@ -152,8 +152,6 @@ public: */ virtual void trp_deliver_signal(const NdbApiSignal*, const LinearSectionPtr p[3]); - virtual void trp_node_status(Uint32, Uint32); - // Is node available for running transactions bool get_node_alive(NodeId nodeId) const; bool get_node_stopping(NodeId nodeId) const; === modified file 'storage/ndb/src/ndbapi/NdbInfoScanOperation.cpp' --- a/storage/ndb/src/ndbapi/NdbInfoScanOperation.cpp 2010-09-30 09:32:28 +0000 +++ b/storage/ndb/src/ndbapi/NdbInfoScanOperation.cpp 2011-01-10 11:22:17 +0000 @@ -347,6 +347,7 @@ int NdbInfoScanOperation::receive(void) case GSN_SUB_GCP_COMPLETE_REP: case GSN_API_REGCONF: case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: // ignore break; === modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.cpp' --- a/storage/ndb/src/ndbapi/NdbQueryOperation.cpp 2010-12-28 12:07:01 +0000 +++ b/storage/ndb/src/ndbapi/NdbQueryOperation.cpp 2011-01-17 12:08:49 +0000 @@ -2779,7 +2779,7 @@ NdbQueryImpl::sendFetchMore(NdbRootFragm setErrorCode(Err_NodeFailCausedAbort); return -1; } - impl->forceSend(forceSend); + impl->do_forceSend(forceSend); m_pendingFrags++; assert(m_pendingFrags <= getRootFragCount()); === modified file 'storage/ndb/src/ndbapi/Ndbif.cpp' --- a/storage/ndb/src/ndbapi/Ndbif.cpp 2011-01-06 21:19:05 +0000 +++ b/storage/ndb/src/ndbapi/Ndbif.cpp 2011-01-17 12:08:49 +0000 @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include #include #include @@ -73,14 +76,21 @@ Ndb::init(int aMaxNoOfTransactions) TransporterFacade * theFacade = theImpl->m_transporter_facade; theEventBuffer->m_mutex = theFacade->theMutexPtr; - const int tBlockNo = theImpl->open(theFacade); + const Uint32 tRef = theImpl->open(theFacade); - if ( tBlockNo == -1 ) { + if (tRef == 0) + { theError.code = 4105; DBUG_RETURN(-1); // no more free blocknumbers }//if - theNdbBlockNumber = tBlockNo; + Uint32 nodeId = refToNode(tRef); + theNdbBlockNumber = refToBlock(tRef); + + if (nodeId > 0) + { + connected(Uint32(tRef)); + } /* Init cached min node version */ theFacade->lock_mutex(); @@ -133,6 +143,7 @@ Ndb::init(int aMaxNoOfTransactions) for (i = 0; i < 16; i++) releaseSignal(tSignal[i]); theInitState = Initialised; + DBUG_RETURN(0); error_handler: @@ -194,44 +205,6 @@ void Ndb::connected(Uint32 ref) theNode= tmpTheNode; // flag that Ndb object is initialized } -void Ndb::report_node_connected(Uint32 nodeId) -{ - if (theEventBuffer) - { - // node connected - // eventOperations in the ndb object should be notified - theEventBuffer->report_node_connected(nodeId); - } -} - -void -NdbImpl::trp_node_status(Uint32 a_node, Uint32 _event) -{ - DBUG_ENTER("Ndb::statusMessage"); - NS_Event event = (NS_Event)_event; - DBUG_PRINT("info", ("a_node: %u event: %u", - a_node, _event)); - Ndb* tNdb = (Ndb*)&m_ndb; - switch(event){ - case NS_CONNECTED: - // cluster connect, a_node == own reference - tNdb->connected(a_node); - break; - case NS_NODE_ALIVE: - tNdb->report_node_connected(a_node); - break; - case NS_NODE_FAILED: - tNdb->report_node_failure(a_node); - break; - case NS_NODE_NF_COMPLETE: - tNdb->report_node_failure_completed(a_node); - break; - }//if - NdbDictInterface::execNodeStatus(&tNdb->theDictionary->m_receiver, - a_node, event); - DBUG_VOID_RETURN; -} - void Ndb::report_node_failure(Uint32 node_id) { @@ -934,12 +907,41 @@ Ndb::handleReceivedSignal(const NdbApiSi goto InvalidSignal; return; } - case GSN_API_REGCONF:{ + case GSN_API_REGCONF: + case GSN_CONNECT_REP: return; // Ignore + case GSN_NODE_FAILREP: + { + const NodeFailRep *rep = CAST_CONSTPTR(NodeFailRep, + aSignal->getDataPtr()); + for (Uint32 i = NdbNodeBitmask::find_first(rep->theNodes); + i != NdbNodeBitmask::NotFound; + i = NdbNodeBitmask::find_next(rep->theNodes, i + 1)) + { + report_node_failure(i); + } + + NdbDictInterface::execSignal(&theDictionary->m_receiver, aSignal, ptr); + break; + } + case GSN_NF_COMPLETEREP: + { + const NFCompleteRep *rep = CAST_CONSTPTR(NFCompleteRep, + aSignal->getDataPtr()); + report_node_failure_completed(rep->failedNodeId); + break; } case GSN_TAKE_OVERTCCONF: abortTransactionsAfterNodeFailure(tFirstData); // theData[0] break; + case GSN_ALLOC_NODEID_CONF: + { + const AllocNodeIdConf *rep = CAST_CONSTPTR(AllocNodeIdConf, + aSignal->getDataPtr()); + Uint32 nodeId = rep->nodeId; + connected(numberToRef(theNdbBlockNumber, nodeId)); + break; + } default: tFirstDataPtr = NULL; goto InvalidSignal; @@ -1246,7 +1248,7 @@ Ndb::sendPrepTrans(int forceSend) insert_completed_list(a_con); }//for theNoOfPreparedTransactions = 0; - theImpl->forceSend(forceSend); + theImpl->do_forceSend(forceSend); return; }//Ndb::sendPrepTrans() === modified file 'storage/ndb/src/ndbapi/SignalSender.cpp' --- a/storage/ndb/src/ndbapi/SignalSender.cpp 2010-12-22 19:11:38 +0000 +++ b/storage/ndb/src/ndbapi/SignalSender.cpp 2011-01-12 08:04:39 +0000 @@ -118,15 +118,17 @@ SimpleSignal::print(FILE * out) const { SignalSender::SignalSender(TransporterFacade *facade, int blockNo) { theFacade = facade; - m_blockNo = open(theFacade, blockNo); - assert(m_blockNo > 0); + Uint32 res = open(theFacade, blockNo); + assert(res != 0); + m_blockNo = refToBlock(res); } SignalSender::SignalSender(Ndb_cluster_connection* connection) { theFacade = connection->m_impl.m_transporter_facade; - m_blockNo = open(theFacade, -1); - assert(m_blockNo > 0); + Uint32 res = open(theFacade, -1); + assert(res != 0); + m_blockNo = refToBlock(res); } SignalSender::~SignalSender(){ @@ -159,12 +161,6 @@ SignalSender::getOwnRef() const { return numberToRef(m_blockNo, theFacade->ownId()); } -Uint32 -SignalSender::getNoOfConnectedNodes() const { - return theFacade->theClusterMgr->getNoOfConnectedNodes(); -} - - NodeBitmask SignalSender::broadcastSignal(NodeBitmask mask, SimpleSignal& sig, @@ -207,7 +203,7 @@ SignalSender::sendFragmentedSignal(Uint1 sig.header.m_noOfSections); if (ret == 0) { - forceSend(); + do_forceSend(); return SEND_OK; } return SEND_DISCONNECTED; @@ -222,7 +218,7 @@ SignalSender::sendSignal(Uint16 nodeId, s->header.m_noOfSections); if (ret == 0) { - forceSend(); + do_forceSend(); return SEND_OK; } return SEND_DISCONNECTED; @@ -306,58 +302,6 @@ SignalSender::trp_deliver_signal(const N m_jobBuffer.push_back(s); wakeup(); } - -void -SignalSender::trp_node_status(Uint32 nodeId, Uint32 _event) -{ - NS_Event event = (NS_Event)_event; - switch(event){ - case NS_CONNECTED: - case NS_NODE_ALIVE: - return; - case NS_NODE_FAILED: - case NS_NODE_NF_COMPLETE: - goto ok; - } - return; - -ok: - SimpleSignal * s = new SimpleSignal(true); - - // node disconnected - if (event == NS_NODE_NF_COMPLETE) - { - // node shutdown complete - s->header.theVerId_signalNumber = GSN_NF_COMPLETEREP; - s->header.theLength = NFCompleteRep::SignalLength; - NFCompleteRep *rep = (NFCompleteRep *)s->getDataPtrSend(); - rep->blockNo = 0; - rep->nodeId = 0; - rep->failedNodeId = nodeId; - rep->unused = 0; - rep->from = 0; - } - else - { - // node failure - s->header.theVerId_signalNumber = GSN_NODE_FAILREP; - s->header.theLength = NodeFailRep::SignalLength; - NodeFailRep *rep = (NodeFailRep *)s->getDataPtrSend(); - rep->failNo = 0; - rep->masterNodeId = 0; - rep->noOfNodes = 1; - NdbNodeBitmask::clear(rep->theNodes); - - // Mark ndb nodes as failed in bitmask - const trp_node node= getNodeInfo(nodeId); - if (node.m_info.getType() == NodeInfo::DB) - NdbNodeBitmask::set(rep->theNodes, nodeId); - } - - m_jobBuffer.push_back(s); - wakeup(); -} - template NodeId === modified file 'storage/ndb/src/ndbapi/SignalSender.hpp' --- a/storage/ndb/src/ndbapi/SignalSender.hpp 2010-12-16 15:34:35 +0000 +++ b/storage/ndb/src/ndbapi/SignalSender.hpp 2011-01-10 13:30:14 +0000 @@ -78,7 +78,6 @@ public: int unlock(); Uint32 getOwnRef() const; - Uint32 getNoOfConnectedNodes() const; NodeId find_confirmed_node(const NodeBitmask& mask); NodeId find_connected_node(const NodeBitmask& mask); @@ -109,8 +108,6 @@ public: virtual void trp_deliver_signal(const NdbApiSignal* signal, const struct LinearSectionPtr ptr[3]); - virtual void trp_node_status(Uint32 nodeId, Uint32 _event); - Vector m_jobBuffer; Vector m_usedBuffer; === modified file 'storage/ndb/src/ndbapi/TransporterFacade.cpp' --- a/storage/ndb/src/ndbapi/TransporterFacade.cpp 2011-01-06 21:19:05 +0000 +++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp 2011-01-17 12:08:49 +0000 @@ -39,6 +39,7 @@ #include #include #include +#include //#define REPORT_TRANSPORTER //#define API_TRACE @@ -686,38 +687,26 @@ void TransporterFacade::connected() { DBUG_ENTER("TransporterFacade::connected"); - Uint32 sz = m_threads.m_statusNext.size(); - for (Uint32 i = 0; i < sz ; i ++) - { - trp_client * clnt = m_threads.m_objectExecute[i]; - if (clnt != 0) - { - clnt->trp_node_status(numberToRef(indexToNumber(i), theOwnId), NS_CONNECTED); - } - } - DBUG_VOID_RETURN; -} + NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theOwnId)); + signal.theVerId_signalNumber = GSN_ALLOC_NODEID_CONF; + signal.theReceiversBlockNumber = 0; + signal.theTrace = 0; + signal.theLength = AllocNodeIdConf::SignalLength; + + AllocNodeIdConf * rep = CAST_PTR(AllocNodeIdConf, signal.getDataPtrSend()); + rep->senderRef = 0; + rep->senderData = 0; + rep->nodeId = theOwnId; + rep->secret_lo = 0; + rep->secret_hi = 0; -void -TransporterFacade::trp_node_status(NodeId tNodeId, Uint32 event) -{ - DBUG_ENTER("TransporterFacade::ReportNodeDead"); - DBUG_PRINT("enter",("nodeid= %d", tNodeId)); - /** - * When a node fails we must report this to each Ndb object. - * The function that is used for communicating node failures is called. - * This is to ensure that the Ndb objects do not think their connections - * are correct after a failure followed by a restart. - * After the restart the node is up again and the Ndb object - * might not have noticed the failure. - */ Uint32 sz = m_threads.m_statusNext.size(); for (Uint32 i = 0; i < sz ; i ++) { trp_client * clnt = m_threads.m_objectExecute[i]; if (clnt != 0) { - clnt->trp_node_status(tNodeId, event); + clnt->trp_deliver_signal(&signal, 0); } } DBUG_VOID_RETURN; @@ -744,7 +733,7 @@ TransporterFacade::close_clnt(trp_client return ret; } -int +Uint32 TransporterFacade::open_clnt(trp_client * clnt, int blockNo) { DBUG_ENTER("TransporterFacade::open"); @@ -752,7 +741,7 @@ TransporterFacade::open_clnt(trp_client int r= m_threads.open(clnt); if (r < 0) { - DBUG_RETURN(r); + DBUG_RETURN(0); } if (unlikely(blockNo != -1)) @@ -766,12 +755,14 @@ TransporterFacade::open_clnt(trp_client m_fixed2dynamic[fixed_index]= r; } -#if 1 if (theOwnId > 0) { - clnt->trp_node_status(numberToRef(r, theOwnId), NS_CONNECTED); + r = numberToRef(r, theOwnId); + } + else + { + r = numberToRef(r, 0); } -#endif DBUG_RETURN(r); } @@ -1413,7 +1404,6 @@ TransporterFacade::sendSignal(const NdbA /****************************************************************************** * CONNECTION METHODS Etc ******************************************************************************/ - void TransporterFacade::doConnect(int aNodeId){ theTransporterRegistry->setIOState(aNodeId, NoHalt); @@ -1978,3 +1968,42 @@ TransporterFacade::get_auto_reconnect() { return theClusterMgr->m_auto_reconnect; } + +void +TransporterFacade::ext_set_max_api_reg_req_interval(Uint32 interval) +{ + theClusterMgr->set_max_api_reg_req_interval(interval); +} + +void +TransporterFacade::ext_update_connections() +{ + theClusterMgr->force_update_connections(); +} + +struct in_addr +TransporterFacade::ext_get_connect_address(Uint32 nodeId) +{ + return theTransporterRegistry->get_connect_address(nodeId); +} + +void +TransporterFacade::ext_forceHB() +{ + theClusterMgr->forceHB(); +} + +bool +TransporterFacade::ext_isConnected(NodeId aNodeId) +{ + return theTransporterRegistry->is_connected(aNodeId); +} + +void +TransporterFacade::ext_doConnect(int aNodeId) +{ + lock_mutex(); + doConnect(aNodeId); + unlock_mutex(); +} + === modified file 'storage/ndb/src/ndbapi/TransporterFacade.hpp' --- a/storage/ndb/src/ndbapi/TransporterFacade.hpp 2011-01-06 21:19:05 +0000 +++ b/storage/ndb/src/ndbapi/TransporterFacade.hpp 2011-01-17 12:08:49 +0000 @@ -37,14 +37,6 @@ class NdbApiSignal; class NdbWaiter; class trp_client; -enum NS_Event -{ - NS_CONNECTED, // *we* are connected and have nodeId (report as NodeId) - NS_NODE_ALIVE, // *nodeId* is alive (connected and API_REGCONF) - NS_NODE_FAILED, // *nodeId* has failed - NS_NODE_NF_COMPLETE -}; - extern "C" { void* runSendRequest_C(void*); void* runReceiveResponse_C(void*); @@ -75,7 +67,7 @@ public: * @blockNo block number to use, -1 => any blockNumber * @return BlockNumber or -1 for failure */ - int open_clnt(trp_client*, int blockNo = -1); + Uint32 open_clnt(trp_client*, int blockNo = -1); int close_clnt(trp_client*); Uint32 get_active_ndb_objects() const; @@ -93,6 +85,16 @@ private: const GenericSectionPtr ptr[3], Uint32 secs); public: + /** + * These are functions used by ndb_mgmd + */ + void ext_set_max_api_reg_req_interval(Uint32 ms); + void ext_update_connections(); + struct in_addr ext_get_connect_address(Uint32 nodeId); + void ext_forceHB(); + bool ext_isConnected(NodeId aNodeId); + void ext_doConnect(int aNodeId); + // Is node available for running transactions private: bool get_node_alive(NodeId nodeId) const; @@ -201,11 +203,8 @@ private: friend class trp_client; friend class ClusterMgr; friend class ArbitMgr; - friend class MgmtSrvr; - friend class SignalSender; friend class Ndb_cluster_connection; friend class Ndb_cluster_connection_impl; - friend class NdbImpl; bool isConnected(NodeId aNodeId); void doStop(); === modified file 'storage/ndb/src/ndbapi/trp_client.cpp' --- a/storage/ndb/src/ndbapi/trp_client.cpp 2010-12-14 09:10:45 +0000 +++ b/storage/ndb/src/ndbapi/trp_client.cpp 2011-01-12 08:04:39 +0000 @@ -26,18 +26,18 @@ trp_client::~trp_client() NdbCondition_Destroy(m_poll.m_condition); } -int +Uint32 trp_client::open(TransporterFacade* tf, int blockNo) { - int res = -1; + Uint32 res = 0; assert(m_facade == 0); if (m_facade == 0) { m_facade = tf; res = tf->open_clnt(this, blockNo); - if (res >= 0) + if (res != 0) { - m_blockNo = Uint32(res); + m_blockNo = refToBlock(res); } else { @@ -100,7 +100,7 @@ trp_client::cond_wait(Uint32 timeout, Nd } void -trp_client::forceSend(int val) +trp_client::do_forceSend(int val) { if (val == 0) { @@ -157,7 +157,7 @@ int PollGuard::wait_scan(int wait_time, int PollGuard::wait_for_input_in_loop(int wait_time, bool forceSend) { int ret_val; - m_clnt->forceSend(forceSend ? 1 : 0); + m_clnt->do_forceSend(forceSend ? 1 : 0); NDB_TICKS curr_time = NdbTick_CurrentMillisecond(); NDB_TICKS max_time = curr_time + (NDB_TICKS)wait_time; === modified file 'storage/ndb/src/ndbapi/trp_client.hpp' --- a/storage/ndb/src/ndbapi/trp_client.hpp 2010-12-18 08:36:08 +0000 +++ b/storage/ndb/src/ndbapi/trp_client.hpp 2011-01-12 08:04:39 +0000 @@ -35,9 +35,8 @@ public: virtual void trp_deliver_signal(const NdbApiSignal *, const LinearSectionPtr ptr[3]) = 0; - virtual void trp_node_status(Uint32, Uint32 event) = 0; - int open(class TransporterFacade*, int blockNo = -1); + Uint32 open(class TransporterFacade*, int blockNo = -1); void close(); void start_poll(); @@ -45,7 +44,7 @@ public: void complete_poll(); void wakeup(); - void forceSend(int val = 1); + void do_forceSend(int val = 1); int raw_sendSignal(const NdbApiSignal*, Uint32 nodeId); int raw_sendSignal(const NdbApiSignal*, Uint32 nodeId, === modified file 'storage/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp' --- a/storage/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp 2009-09-25 21:26:33 +0000 +++ b/storage/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp 2011-01-16 06:24:02 +0000 @@ -278,6 +278,7 @@ print_stats(const char *title, ndbout_c(" Transactions: %d", gen->totalTransactions); ndbout_c(" Outer : %.0f TPS",gen->outerTps); ndbout_c("\n"); + ndbout_c("NDBT_Observation;tps;%.0f", gen->outerTps); } } === modified file 'storage/ndb/test/ndbapi/testBasic.cpp' --- a/storage/ndb/test/ndbapi/testBasic.cpp 2010-11-28 11:34:01 +0000 +++ b/storage/ndb/test/ndbapi/testBasic.cpp 2011-01-14 12:05:51 +0000 @@ -2188,6 +2188,86 @@ runBug54944(NDBT_Context* ctx, NDBT_Step return NDBT_OK; } +int +runBug59496_scan(NDBT_Context* ctx, NDBT_Step* step) +{ + Ndb* pNdb = GETNDB(step); + const NdbDictionary::Table * pTab = ctx->getTab(); + NdbRestarter res; + int rowcount = ctx->getProperty("CHECK_ROWCOUNT", Uint32(0)); + int records = ctx->getNumRecords(); + if (rowcount == 0) + records = 0; + + HugoTransactions hugoTrans(*pTab); + while (!ctx->isTestStopped()) + { + if (hugoTrans.scanReadRecords(pNdb, + records, 0, 0, + NdbOperation::LM_CommittedRead, + (int)NdbScanOperation::SF_TupScan) != NDBT_OK) + return NDBT_FAILED; + } + return NDBT_OK; +} + +int +runBug59496_case1(NDBT_Context* ctx, NDBT_Step* step) +{ + Ndb* pNdb = GETNDB(step); + NdbRestarter res; + + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + + HugoOperations hugoOps(*ctx->getTab()); + for (int i = 0; i < loops; i++) + { + hugoOps.startTransaction(pNdb); + hugoOps.pkInsertRecord(pNdb, 0, records, 0); + hugoOps.execute_NoCommit(pNdb); + hugoOps.pkUpdateRecord(pNdb, 0, records, rand()); + hugoOps.execute_NoCommit(pNdb); + hugoOps.pkUpdateRecord(pNdb, 0, records, rand()); + hugoOps.execute_NoCommit(pNdb); + res.insertErrorInAllNodes(8089); + hugoOps.execute_Commit(pNdb); + res.insertErrorInAllNodes(0); + hugoOps.closeTransaction(pNdb); + hugoOps.clearTable(pNdb); + } + ctx->stopTest(); + return NDBT_OK; +} + +int +runBug59496_case2(NDBT_Context* ctx, NDBT_Step* step) +{ + Ndb* pNdb = GETNDB(step); + NdbRestarter res; + + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + + HugoOperations hugoOps(*ctx->getTab()); + for (int i = 0; i < loops; i++) + { + hugoOps.startTransaction(pNdb); + hugoOps.pkDeleteRecord(pNdb, 0, records); + hugoOps.execute_NoCommit(pNdb); + hugoOps.pkInsertRecord(pNdb, 0, records, 0); + hugoOps.execute_NoCommit(pNdb); + + res.insertErrorInAllNodes(8089); + hugoOps.execute_Rollback(pNdb); + res.insertErrorInAllNodes(0); + + hugoOps.closeTransaction(pNdb); + } + ctx->stopTest(); + return NDBT_OK; +} + NDBT_TESTSUITE(testBasic); TESTCASE("PkInsert", "Verify that we can insert and delete from this table using PK" @@ -2527,6 +2607,18 @@ TESTCASE("Bug54944", "") { INITIALIZER(runBug54944); } +TESTCASE("Bug59496_case1", "") +{ + STEP(runBug59496_case1); + STEPS(runBug59496_scan, 10); +} +TESTCASE("Bug59496_case2", "") +{ + TC_PROPERTY("CHECK_ROWCOUNT", 1); + INITIALIZER(runLoadTable); + STEP(runBug59496_case2); + STEPS(runBug59496_scan, 10); +} NDBT_TESTSUITE_END(testBasic); #if 0 === modified file 'storage/ndb/test/run-test/daily-basic-tests.txt' --- a/storage/ndb/test/run-test/daily-basic-tests.txt 2011-01-06 21:19:05 +0000 +++ b/storage/ndb/test/run-test/daily-basic-tests.txt 2011-01-17 12:08:49 +0000 @@ -271,6 +271,14 @@ max-time: 500 cmd: testBasic args: -n Bug54944 T1 +max-time: 600 +cmd: testBasic +args: -r 10 -n Bug59496_case1 T2 + +max-time: 600 +cmd: testBasic +args: -r 10 -n Bug59496_case2 T2 + # # INDEX # No bundle (reason: revision is a merge).