summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/include/have_multi_ndb.inc32
-rw-r--r--mysql-test/suite/ndb/r/ndb_basic.result24
-rw-r--r--mysql-test/suite/ndb/r/ndb_multi.result1
-rw-r--r--mysql-test/suite/ndb/r/ndb_multi_row.result1
-rw-r--r--mysql-test/suite/ndb/t/ndb_basic.test22
-rw-r--r--mysql-test/suite/ndb/t/ndb_multi.test4
-rw-r--r--mysql-test/suite/ndb/t/ndb_multi_row.test3
-rw-r--r--sql/ha_ndbcluster.cc2
-rw-r--r--sql/ha_ndbcluster_binlog.cc84
-rw-r--r--storage/ndb/src/common/transporter/Transporter.cpp4
-rw-r--r--storage/ndb/src/common/transporter/TransporterRegistry.cpp3
-rw-r--r--storage/ndb/src/kernel/blocks/ERROR_codes.txt7
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp10
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp60
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp19
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp4
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp214
-rw-r--r--storage/ndb/src/kernel/blocks/suma/Suma.cpp48
-rw-r--r--storage/ndb/src/ndbapi/TransporterFacade.cpp2
-rw-r--r--storage/ndb/test/ndbapi/testDict.cpp10
-rw-r--r--storage/ndb/test/ndbapi/testNodeRestart.cpp48
-rw-r--r--storage/ndb/test/ndbapi/testSystemRestart.cpp41
-rw-r--r--storage/ndb/test/run-test/daily-basic-tests.txt7
-rw-r--r--storage/ndb/test/tools/Makefile.am3
-rw-r--r--storage/ndb/test/tools/connect.cpp152
-rw-r--r--storage/ndb/tools/restore/Restore.cpp156
-rw-r--r--storage/ndb/tools/restore/Restore.hpp4
27 files changed, 666 insertions, 299 deletions
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/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_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/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_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/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index bf2b19bfc9c..adc78f26938 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -618,7 +618,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);
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index be75eff2575..990c00261a8 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_thread_id= thd->variables.pseudo_thread_id;
+ ulong save_thd_query_length= thd->query_length;
+ char *save_thd_query= thd->query;
+ struct system_variables save_thd_variables= thd->variables;
+ 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->variables.pseudo_thread_id= save_thread_id;
- thd->net= save_net;
+ thd->query_length= save_thd_query_length;
+ thd->query= save_thd_query;
+ thd->variables= save_thd_variables;
+ 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/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/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..28378c41f25 100644
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -5181,11 +5181,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 +6122,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);
}
@@ -6432,6 +6450,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 +6593,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 +10564,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);
}
@@ -10765,6 +10793,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 +10989,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;
@@ -14500,6 +14540,14 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal)
("immediateLcpStart = %d masterLcpNodeId = %d",
c_lcpState.immediateLcpStart,
refToNode(c_lcpState.m_masterLcpDihRef));
+
+ for (Uint32 i = 0; i<10; i++)
+ {
+ infoEvent("%u : status: %u place: %u", i,
+ c_lcpState.m_saveState[i].m_status,
+ c_lcpState.m_saveState[i].m_place);
+ }
+
infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
}
diff --git a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index 95cad98b81c..62add0cf503 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -585,7 +585,6 @@ public:
enum ExecSrStatus {
IDLE = 0,
- ACTIVE_REMOVE_AFTER = 1,
ACTIVE = 2
};
/**
@@ -869,11 +868,6 @@ public:
* heard of.
*/
Uint8 fragDistributionKey;
- /**
- * The identity of the next local checkpoint this fragment
- * should perform.
- */
- Uint8 nextLcp;
/**
* How many local checkpoints does the fragment contain
*/
@@ -2097,10 +2091,6 @@ private:
void execEXEC_SRCONF(Signal* signal);
void execREAD_PSEUDO_REQ(Signal* signal);
- void build_acc(Signal*, Uint32 fragPtrI);
- void execBUILDINDXREF(Signal*signal);
- void execBUILDINDXCONF(Signal*signal);
-
void execDUMP_STATE_ORD(Signal* signal);
void execACC_ABORTCONF(Signal* signal);
void execNODE_FAILREP(Signal* signal);
@@ -2780,7 +2770,13 @@ private:
/*THIS VARIABLE KEEPS TRACK OF HOW MANY FRAGMENTS THAT PARTICIPATE IN */
/*EXECUTING THE LOG. IF ZERO WE DON'T NEED TO EXECUTE THE LOG AT ALL. */
/* ------------------------------------------------------------------------- */
- UintR cnoFragmentsExecSr;
+ Uint32 cnoFragmentsExecSr;
+
+ /**
+ * This is no of sent GSN_EXEC_FRAGREQ during this log phase
+ */
+ Uint32 cnoOutstandingExecFragReq;
+
/* ------------------------------------------------------------------------- */
/*THIS VARIABLE KEEPS TRACK OF WHICH OF THE FIRST TWO RESTART PHASES THAT */
/*HAVE COMPLETED. */
@@ -2801,7 +2797,6 @@ private:
DLFifoList<Fragrecord> c_lcp_waiting_fragments; // StartFragReq'ed
DLFifoList<Fragrecord> c_lcp_restoring_fragments; // Restoring as we speek
DLFifoList<Fragrecord> c_lcp_complete_fragments; // Restored
- DLFifoList<Fragrecord> 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..6efa1b1b116 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<Fragrecord> 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,
@@ -1121,7 +1120,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 +1212,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 +8936,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 +14141,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 +14178,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 +14382,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 +14403,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 +14421,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 +14448,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 +14469,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 +14503,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 +14541,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 +14562,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 +14619,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 +14693,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 +15871,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 +15898,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 +16143,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 +17251,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 +18339,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/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
index 7845b83693c..a4e886b14b6 100644
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
@@ -974,6 +974,54 @@ Suma::execDUMP_STATE_ORD(Signal* signal){
}
return;
}
+
+ if (tCase == 8011)
+ {
+ jam();
+ Uint32 bucket = signal->theData[1];
+ KeyTable<Table>::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; i<RT_BREAK || it.bucket == bucket; i++)
+ {
+ jam();
+ if(it.curr.i == RNIL)
+ {
+ jam();
+ infoEvent("-- Ending dump of subscribers --");
+ return;
+ }
+
+ infoEvent("Table: %u ver: %u #n: %u (ref,data,subscritopn)",
+ it.curr.p->m_tableId,
+ it.curr.p->m_schemaVersion,
+ it.curr.p->n_subscribers);
+
+ Ptr<Subscriber> ptr;
+ LocalDLList<Subscriber> 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;
+ }
}
/*************************************************************
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/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..2a5febb7ae9 100644
--- a/storage/ndb/test/ndbapi/testNodeRestart.cpp
+++ b/storage/ndb/test/ndbapi/testNodeRestart.cpp
@@ -1832,6 +1832,51 @@ runBug31525(NDBT_Context* ctx, NDBT_Step* step)
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;
return NDBT_OK;
}
@@ -2205,6 +2250,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 <ndb_global.h>
+#include <ndb_opts.h>
+#include <NDBT.hpp>
+#include <NdbApi.hpp>
+#include <NdbSleep.h>
+
+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<NdbEventOperation*> 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<ops.size(); i++)
+ {
+ switch(_drop){
+ case 0:
+ break;
+ do_drop:
+ case 1:
+ if (MyNdb.dropEventOperation(ops[i]))
+ {
+ ndbout << "drop event operation failed "
+ << MyNdb.getNdbError() << endl;
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ break;
+ default:
+ if ((rand() % 100) > 50)
+ goto do_drop;
+ }
+ }
+ }
+
+ return NDBT_ProgramExit(NDBT_OK);
+}
+
+template class Vector<NdbEventOperation*>;
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 {