diff --git a/mysql-test/r/ndb_autodiscover3.result b/mysql-test/r/ndb_autodiscover3.result new file mode 100644 index 00000000000..8bc1b968436 --- /dev/null +++ b/mysql-test/r/ndb_autodiscover3.result @@ -0,0 +1,45 @@ +drop table if exists t1, t2; +create table t1 (a int key) engine=ndbcluster; +begin; +insert into t1 values (1); +insert into t1 values (2); +ERROR HY000: Got temporary error 4025 'Node failure caused abort of transaction' from ndbcluster +commit; +ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster +drop table t1; +create table t2 (a int, b int, primary key(a,b)) engine=ndbcluster; +insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1); +select * from t2 order by a limit 3; +a b +1 1 +2 1 +3 1 +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; +a +1 +2 +3 +select * from t2 order by a limit 3; +ERROR HY000: Can't lock file (errno: 241) +select * from t2 order by a limit 3; +a +1 +2 +3 +show tables; +Tables_in_test +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; +a +1 +2 +3 +select * from t2 order by a limit 3; +a +1 +2 +3 +drop table t2; diff --git a/mysql-test/t/ndb_autodiscover3.test b/mysql-test/t/ndb_autodiscover3.test new file mode 100644 index 00000000000..73b4bf8b94f --- /dev/null +++ b/mysql-test/t/ndb_autodiscover3.test @@ -0,0 +1,65 @@ +-- source include/have_ndb.inc +-- source include/have_multi_ndb.inc +-- source include/not_embedded.inc + + +--disable_warnings +drop table if exists t1, t2; +--enable_warnings + +# +# Transaction ongoing while cluster is restarted +# +--connection server1 +create table t1 (a int key) engine=ndbcluster; + +begin; +insert into t1 values (1); + +--exec $NDB_MGM --no-defaults -e "all restart" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT + +--error 1297 +insert into t1 values (2); +--error 1296 +commit; + +drop table t1; + +# +# Stale cache after restart -i +# +--connection server1 +create table t2 (a int, b int, primary key(a,b)) engine=ndbcluster; +insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1); +select * from t2 order by a limit 3; + +--exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT + +--connection server2 +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; + +# server 1 should have a stale cache, and in this case wrong frm, transaction must be retried +--connection server1 +--error 1015 +select * from t2 order by a limit 3; +select * from t2 order by a limit 3; + +--exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT + +--connection server1 +show tables; +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; + +# server 2 should have a stale cache, but with right frm, transaction need not be retried +--connection server2 +select * from t2 order by a limit 3; + +drop table t2; +# End of 4.1 tests diff --git a/ndb/include/mgmapi/mgmapi_config_parameters.h b/ndb/include/mgmapi/mgmapi_config_parameters.h index 9076f18c5ac..ec69be74d12 100644 --- a/ndb/include/mgmapi/mgmapi_config_parameters.h +++ b/ndb/include/mgmapi/mgmapi_config_parameters.h @@ -65,6 +65,7 @@ #define CFG_DB_BACKUP_DATA_BUFFER_MEM 134 #define CFG_DB_BACKUP_LOG_BUFFER_MEM 135 #define CFG_DB_BACKUP_WRITE_SIZE 136 +#define CFG_DB_BACKUP_MAX_WRITE_SIZE 139 #define CFG_LOG_DESTINATION 147 diff --git a/ndb/include/ndbapi/ndb_cluster_connection.hpp b/ndb/include/ndbapi/ndb_cluster_connection.hpp index 0e559700716..3fe66bd2d44 100644 --- a/ndb/include/ndbapi/ndb_cluster_connection.hpp +++ b/ndb/include/ndbapi/ndb_cluster_connection.hpp @@ -83,6 +83,7 @@ public: void set_optimized_node_selection(int val); unsigned no_db_nodes(); + unsigned get_connect_count() const; #endif private: diff --git a/ndb/include/util/SocketServer.hpp b/ndb/include/util/SocketServer.hpp index ee2dd31c41f..02a0a6b5d92 100644 --- a/ndb/include/util/SocketServer.hpp +++ b/ndb/include/util/SocketServer.hpp @@ -74,7 +74,7 @@ public: /** * Constructor / Destructor */ - SocketServer(int maxSessions = 32); + SocketServer(unsigned maxSessions = ~(unsigned)0); ~SocketServer(); /** diff --git a/ndb/src/common/transporter/Transporter.cpp b/ndb/src/common/transporter/Transporter.cpp index 328ce2816de..902dfea9c8e 100644 --- a/ndb/src/common/transporter/Transporter.cpp +++ b/ndb/src/common/transporter/Transporter.cpp @@ -100,10 +100,10 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) { } { - struct sockaddr addr; + struct sockaddr_in addr; SOCKET_SIZE_TYPE addrlen= sizeof(addr); - int r= getpeername(sockfd, &addr, &addrlen); - m_connect_address= ((struct sockaddr_in *)&addr)->sin_addr; + int r= getpeername(sockfd, (struct sockaddr*)&addr, &addrlen); + m_connect_address= (&addr)->sin_addr; } bool res = connect_server_impl(sockfd); @@ -173,10 +173,10 @@ Transporter::connect_client() { } { - struct sockaddr addr; + struct sockaddr_in addr; SOCKET_SIZE_TYPE addrlen= sizeof(addr); - int r= getpeername(sockfd, &addr, &addrlen); - m_connect_address= ((struct sockaddr_in *)&addr)->sin_addr; + int r= getpeername(sockfd, (struct sockaddr*)&addr, &addrlen); + m_connect_address= (&addr)->sin_addr; } bool res = connect_client_impl(sockfd); diff --git a/ndb/src/common/util/SocketServer.cpp b/ndb/src/common/util/SocketServer.cpp index db5c03f925a..755764c7700 100644 --- a/ndb/src/common/util/SocketServer.cpp +++ b/ndb/src/common/util/SocketServer.cpp @@ -27,7 +27,7 @@ #define DEBUG(x) ndbout << x << endl; -SocketServer::SocketServer(int maxSessions) : +SocketServer::SocketServer(unsigned maxSessions) : m_sessions(10), m_services(5) { @@ -124,7 +124,7 @@ SocketServer::setup(SocketServer::Service * service, DBUG_RETURN(false); } - if (listen(sock, m_maxSessions) == -1){ + if (listen(sock, m_maxSessions > 32 ? 32 : m_maxSessions) == -1){ DBUG_PRINT("error",("listen() - %d - %s", errno, strerror(errno))); NDB_CLOSE_SOCKET(sock); diff --git a/ndb/src/kernel/blocks/backup/BackupInit.cpp b/ndb/src/kernel/blocks/backup/BackupInit.cpp index 7cd9c61f010..dfda31e9b48 100644 --- a/ndb/src/kernel/blocks/backup/BackupInit.cpp +++ b/ndb/src/kernel/blocks/backup/BackupInit.cpp @@ -66,15 +66,16 @@ Backup::Backup(const Configuration & conf) : Uint32 szDataBuf = (2 * 1024 * 1024); Uint32 szLogBuf = (2 * 1024 * 1024); - Uint32 szWrite = 32768; + Uint32 szWrite = 32768, maxWriteSize = (256 * 1024); ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_DATA_BUFFER_MEM, &szDataBuf); ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_LOG_BUFFER_MEM, &szLogBuf); ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_WRITE_SIZE, &szWrite); + ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_MAX_WRITE_SIZE, &maxWriteSize); c_defaults.m_logBufferSize = szLogBuf; c_defaults.m_dataBufferSize = szDataBuf; c_defaults.m_minWriteSize = szWrite; - c_defaults.m_maxWriteSize = szWrite; + c_defaults.m_maxWriteSize = maxWriteSize; { // Init all tables ArrayList tables(c_tablePool); diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 36a72dcb975..66a400a3e22 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -1191,7 +1191,19 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { false, ConfigInfo::CI_INT, "32K", - "0", + "2K", + STR_VALUE(MAX_INT_RNIL) }, + + { + CFG_DB_BACKUP_MAX_WRITE_SIZE, + "BackupMaxWriteSize", + DB_TOKEN, + "Max size of filesystem writes made by backup (in bytes)", + ConfigInfo::CI_USED, + false, + ConfigInfo::CI_INT, + "256K", + "2K", STR_VALUE(MAX_INT_RNIL) }, /*************************************************************************** diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 47d156c1f9e..c9e8535b75c 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -2107,6 +2107,7 @@ int MgmtSrvr::abortBackup(Uint32 backupId) { SignalSender ss(theFacade); + ss.lock(); // lock will be released on exit bool next; NodeId nodeId = 0; diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 1a5b0592066..0ce89aacefc 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -427,9 +427,9 @@ MgmApiSession::get_nodeid(Parser_t::Context &, return; } - struct sockaddr addr; + struct sockaddr_in addr; SOCKET_SIZE_TYPE addrlen= sizeof(addr); - int r = getpeername(m_socket, &addr, &addrlen); + int r = getpeername(m_socket, (struct sockaddr*)&addr, &addrlen); if (r != 0 ) { m_output->println(cmd); m_output->println("result: getpeername(%d) failed, err= %d", m_socket, r); @@ -441,7 +441,7 @@ MgmApiSession::get_nodeid(Parser_t::Context &, if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){ BaseString error_string; if (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype, - &addr, &addrlen, error_string)){ + (struct sockaddr*)&addr, &addrlen, error_string)){ const char *alias; const char *str; alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type) diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp index 543bdf1155e..cd559a544a8 100644 --- a/ndb/src/ndbapi/ClusterMgr.cpp +++ b/ndb/src/ndbapi/ClusterMgr.cpp @@ -70,6 +70,7 @@ ClusterMgr::ClusterMgr(TransporterFacade & _facade): noOfAliveNodes= 0; noOfConnectedNodes= 0; theClusterMgrThread= 0; + m_connect_count = 0; DBUG_VOID_RETURN; } @@ -456,6 +457,10 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){ theNode.nfCompleteRep = false; if(noOfAliveNodes == 0){ + theFacade.m_globalDictCache.lock(); + theFacade.m_globalDictCache.invalidate_all(); + theFacade.m_globalDictCache.unlock(); + m_connect_count ++; NFCompleteRep rep; for(Uint32 i = 1; i > * curr = m_tableHash.getNext(0); + int sz = 0; + while(curr != 0){ + sz += curr->theData->size(); + curr = m_tableHash.getNext(curr); + } + return sz; +} + +void +GlobalDictCache::invalidate_all() +{ + DBUG_ENTER("GlobalDictCache::invalidate_all"); + NdbElement_t > * curr = m_tableHash.getNext(0); + while(curr != 0){ + Vector * vers = curr->theData; + if (vers->size()) + { + TableVersion * ver = & vers->back(); + ver->m_impl->m_status = NdbDictionary::Object::Invalid; + ver->m_status = DROPPED; + if (ver->m_refCount == 0) + { + delete ver->m_impl; + vers->erase(vers->size() - 1); + } + } + curr = m_tableHash.getNext(curr); + } + DBUG_VOID_RETURN; +} + void GlobalDictCache::release(NdbTableImpl * tab){ unsigned i; diff --git a/ndb/src/ndbapi/DictCache.hpp b/ndb/src/ndbapi/DictCache.hpp index 7f2ee457476..52bd57ea217 100644 --- a/ndb/src/ndbapi/DictCache.hpp +++ b/ndb/src/ndbapi/DictCache.hpp @@ -71,6 +71,9 @@ public: void alter_table_rep(const char * name, Uint32 tableId, Uint32 tableVersion, bool altered); + + unsigned get_size(); + void invalidate_all(); public: enum Status { OK = 0, diff --git a/ndb/src/ndbapi/SignalSender.cpp b/ndb/src/ndbapi/SignalSender.cpp index a29fe68937b..0ecc98f5f29 100644 --- a/ndb/src/ndbapi/SignalSender.cpp +++ b/ndb/src/ndbapi/SignalSender.cpp @@ -75,7 +75,9 @@ SignalSender::SignalSender(TransporterFacade *facade) { m_cond = NdbCondition_Create(); theFacade = facade; + lock(); m_blockNo = theFacade->open(this, execSignal, execNodeStatus); + unlock(); assert(m_blockNo > 0); } diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp index 7e010d45945..b8963b8d0e1 100644 --- a/ndb/src/ndbapi/TransporterFacade.hpp +++ b/ndb/src/ndbapi/TransporterFacade.hpp @@ -264,6 +264,12 @@ TransporterFacade::unlock_mutex() #include "ClusterMgr.hpp" +inline +unsigned Ndb_cluster_connection_impl::get_connect_count() const +{ + return TransporterFacade::instance()->theClusterMgr->m_connect_count; +} + inline bool TransporterFacade::check_send_size(Uint32 node_id, Uint32 send_size) diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index a313a973a42..df744fb3261 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -236,6 +236,12 @@ Ndb_cluster_connection::wait_until_ready(int timeout, } while (1); } +unsigned Ndb_cluster_connection::get_connect_count() const +{ + return m_impl.get_connect_count(); +} + + /* diff --git a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp index 620eac296a3..ee561c1d6af 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp +++ b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp @@ -49,6 +49,7 @@ class Ndb_cluster_connection_impl : public Ndb_cluster_connection void init_get_next_node(Ndb_cluster_connection_node_iter &iter); Uint32 get_next_node(Ndb_cluster_connection_node_iter &iter); + inline unsigned get_connect_count() const; private: friend class Ndb; friend class NdbImpl; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 876d5d2f8fd..c0eae685a52 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3306,8 +3306,23 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) { m_table= (void *)tab; m_table_version = tab->getObjectVersion(); - if (!(my_errno= build_index_list(ndb, table, ILBP_OPEN))) + if ((my_errno= build_index_list(ndb, table, ILBP_OPEN))) DBUG_RETURN(my_errno); + + const void *data, *pack_data; + uint length, pack_length; + if (readfrm(table->path, &data, &length) || + packfrm(data, length, &pack_data, &pack_length) || + pack_length != tab->getFrmLength() || + memcmp(pack_data, tab->getFrmData(), pack_length)) + { + my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR)); + NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT); + DBUG_RETURN(ndb_to_mysql_error(&err)); + } + my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR)); } m_table_info= tab_info; } diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 737a0d3899d..9471e2228ed 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -644,6 +644,7 @@ fi %attr(755, root, root) %{_bindir}/ndb_desc %attr(755, root, root) %{_bindir}/ndb_show_tables %attr(755, root, root) %{_bindir}/ndb_test_platform +%attr(755, root, root) %{_bindir}/ndb_config %files ndb-extra %defattr(-,root,root,0755)