diff options
Diffstat (limited to 'ndb')
38 files changed, 515 insertions, 215 deletions
diff --git a/ndb/config/type_ndbapitest.mk.am b/ndb/config/type_ndbapitest.mk.am index f1fd8286337..392c4e9fc70 100644 --- a/ndb/config/type_ndbapitest.mk.am +++ b/ndb/config/type_ndbapitest.mk.am @@ -5,7 +5,7 @@ LDADD += $(top_builddir)/ndb/test/src/libNDBT.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ -INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \ +INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/include \ -I$(top_srcdir)/ndb/include \ -I$(top_srcdir)/ndb/include/ndbapi \ -I$(top_srcdir)/ndb/include/util \ diff --git a/ndb/include/Makefile.am b/ndb/include/Makefile.am index b29433a59b7..38b9d870fbc 100644 --- a/ndb/include/Makefile.am +++ b/ndb/include/Makefile.am @@ -2,6 +2,7 @@ include $(top_srcdir)/ndb/config/common.mk.am ndbinclude_HEADERS = \ +ndb_init.h \ ndb_types.h \ ndb_version.h diff --git a/ndb/include/logger/LogHandler.hpp b/ndb/include/logger/LogHandler.hpp index ca4bd4c0668..7df6ad864e5 100644 --- a/ndb/include/logger/LogHandler.hpp +++ b/ndb/include/logger/LogHandler.hpp @@ -19,7 +19,6 @@ #include "Logger.hpp" - /** * This class is the base class for all log handlers. A log handler is * responsible for formatting and writing log messages to a specific output. @@ -68,7 +67,8 @@ public: /** * Append a log message to the output stream/file whatever. * append() will call writeHeader(), writeMessage() and writeFooter() for - * a child class and in that order. + * a child class and in that order. Append checks for repeated messages. + * append_impl() does not check for repeats. * * @param pCategory the category/name to tag the log entry with. * @param level the log level. @@ -76,6 +76,8 @@ public: */ void append(const char* pCategory, Logger::LoggerLevel level, const char* pMsg); + void append_impl(const char* pCategory, Logger::LoggerLevel level, + const char* pMsg); /** * Returns a default formatted header. It currently has the @@ -112,14 +114,6 @@ public: void setDateTimeFormat(const char* pFormat); /** - * Returns a string date and time string. - * - * @param pStr a string. - * @return a string with date and time. - */ - char* getTimeAsString(char* pStr) const; - - /** * Returns the error code. */ int getErrorCode() const; @@ -185,6 +179,15 @@ protected: virtual void writeFooter() = 0; private: + /** + * Returns a string date and time string. + * @note does not update time, uses m_now as time + * @param pStr a string. + * @return a string with date and time. + */ + char* getTimeAsString(char* pStr) const; + time_t m_now; + /** Prohibit */ LogHandler(const LogHandler&); LogHandler* operator = (const LogHandler&); @@ -192,6 +195,14 @@ private: const char* m_pDateTimeFormat; int m_errorCode; + + // for handling repeated messages + unsigned m_count_repeated_messages; + unsigned m_max_repeat_frequency; + time_t m_last_log_time; + char m_last_category[MAX_HEADER_LENGTH]; + char m_last_message[MAX_LOG_MESSAGE_SIZE]; + Logger::LoggerLevel m_last_level; }; #endif diff --git a/ndb/include/logger/Logger.hpp b/ndb/include/logger/Logger.hpp index f12297023b7..ee762098fb6 100644 --- a/ndb/include/logger/Logger.hpp +++ b/ndb/include/logger/Logger.hpp @@ -20,6 +20,8 @@ #include <ndb_global.h> #include <BaseString.hpp> +#define MAX_LOG_MESSAGE_SIZE 1024 + class LogHandler; class LogHandlerList; diff --git a/ndb/include/ndb_global.h.in b/ndb/include/ndb_global.h.in index aefb319730c..aca67239719 100644 --- a/ndb/include/ndb_global.h.in +++ b/ndb/include/ndb_global.h.in @@ -1,3 +1,18 @@ +/* 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 */ #ifndef NDBGLOBAL_H #define NDBGLOBAL_H @@ -96,15 +111,12 @@ extern "C" { #include <assert.h> -/* call in main() - does not return on error */ -extern int ndb_init(void); -extern void ndb_end(int); -#define NDB_INIT(prog_name) {my_progname=(prog_name); ndb_init();} - #ifdef __cplusplus } #endif +#include "ndb_init.h" + #ifdef SCO #ifndef PATH_MAX diff --git a/ndb/include/ndb_init.h b/ndb/include/ndb_init.h new file mode 100644 index 00000000000..0ff53e6a2af --- /dev/null +++ b/ndb/include/ndb_init.h @@ -0,0 +1,32 @@ +/* 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 */ + + +#ifndef NDB_INIT_H +#define NDB_INIT_H + +#ifdef __cplusplus +extern "C" { +#endif +/* call in main() - does not return on error */ +extern int ndb_init(void); +extern void ndb_end(int); +#define NDB_INIT(prog_name) {my_progname=(prog_name); ndb_init();} +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ndb/include/ndbapi/NdbApi.hpp b/ndb/include/ndbapi/NdbApi.hpp index add733cccd7..ae7025f560a 100644 --- a/ndb/include/ndbapi/NdbApi.hpp +++ b/ndb/include/ndbapi/NdbApi.hpp @@ -17,6 +17,8 @@ #ifndef NdbApi_H #define NdbApi_H +#include "ndb_init.h" +#include "ndb_cluster_connection.hpp" #include "ndbapi_limits.h" #include "Ndb.hpp" #include "NdbConnection.hpp" diff --git a/ndb/include/ndbapi/NdbBlob.hpp b/ndb/include/ndbapi/NdbBlob.hpp index 0fb63015da2..b145c69b04b 100644 --- a/ndb/include/ndbapi/NdbBlob.hpp +++ b/ndb/include/ndbapi/NdbBlob.hpp @@ -182,27 +182,12 @@ public: /** * Get blob parts table name. Useful only to test programs. */ - STATIC_CONST( BlobTableNameSize = 40 ); static int getBlobTableName(char* btname, Ndb* anNdb, const char* tableName, const char* columnName); /** * Return error object. The error may be blob specific (below) or may * be copied from a failed implicit operation. */ const NdbError& getNdbError() const; - // "Invalid blob attributes or invalid blob parts table" - STATIC_CONST( ErrTable = 4263 ); - // "Invalid usage of blob attribute" - STATIC_CONST( ErrUsage = 4264 ); - // "Method is not valid in current blob state" - STATIC_CONST( ErrState = 4265 ); - // "Invalid blob seek position" - STATIC_CONST( ErrSeek = 4266 ); - // "Corrupted blob value" - STATIC_CONST( ErrCorrupt = 4267 ); - // "Error in blob head update forced rollback of transaction" - STATIC_CONST( ErrAbort = 4268 ); - // "Unknown blob error" - STATIC_CONST( ErrUnknown = 4269 ); /** * Return info about all blobs in this operation. */ diff --git a/ndb/include/ndbapi/NdbReceiver.hpp b/ndb/include/ndbapi/NdbReceiver.hpp index b95313db274..af624f69bd3 100644 --- a/ndb/include/ndbapi/NdbReceiver.hpp +++ b/ndb/include/ndbapi/NdbReceiver.hpp @@ -19,7 +19,6 @@ #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL // Not part of public interface #include <ndb_types.h> -#include <ndb_global.h> class Ndb; class NdbConnection; @@ -131,7 +130,9 @@ int NdbReceiver::execTCOPCONF(Uint32 len){ Uint32 tmp = m_received_result_length; m_expected_result_length = len; +#ifdef assert assert(!(tmp && !len)); +#endif return ((bool)len ^ (bool)tmp ? 0 : 1); } diff --git a/ndb/include/ndbapi/ndb_cluster_connection.hpp b/ndb/include/ndbapi/ndb_cluster_connection.hpp index 1b1c8575656..0e559700716 100644 --- a/ndb/include/ndbapi/ndb_cluster_connection.hpp +++ b/ndb/include/ndbapi/ndb_cluster_connection.hpp @@ -18,28 +18,72 @@ #ifndef CLUSTER_CONNECTION_HPP #define CLUSTER_CONNECTION_HPP -struct Ndb_cluster_connection_node_iter; - +/** + * @class Ndb_cluster_connection + * @brief Represents a connection to a cluster of storage nodes + * + * Always start your application program by creating a + * Ndb_cluster_connection object. Your application should contain + * only one Ndb_cluster_connection. Your application connects to + * a cluster management server when method connect() is called. + * With the method wait_until_ready() it is possible to wait + * for the connection to one or several storage nodes. + */ class Ndb_cluster_connection { public: + /** + * Create a connection to a cluster of storage nodes + * + * @param specify the connectstring for where to find the + * management server + */ Ndb_cluster_connection(const char * connect_string = 0); ~Ndb_cluster_connection(); - int connect(int no_retries, int retry_delay_in_seconds, int verbose); + + /** + * Connect to a cluster management server + * + * @param no_retries specifies the number of retries to perform + * if the connect fails, negative number results in infinite + * number of retries + * @param retry_delay_in_seconds specifies how often retries should + * be performed + * @param verbose specifies if the method should print progess + * + * @return 0 if success, + * 1 if retriable error, + * -1 if non-retriable error + */ + int connect(int no_retries=0, int retry_delay_in_seconds=1, int verbose=0); + +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL int start_connect_thread(int (*connect_callback)(void)= 0); +#endif - // add check coupled to init state of cluster connection - // timeout_after_first_alive negative - ok only if all alive - // timeout_after_first_alive positive - ok if some alive + /** + * Wait until one or several storage nodes are connected + * + * @param time_out_for_first_alive number of seconds to wait until + * first alive node is detected + * @param timeout_after_first_alive number of seconds to wait after + * first alive node is detected + * + * @return 0 all nodes alive, + * > 0 at least one node alive, + * < 0 error + */ int wait_until_ready(int timeout_for_first_alive, int timeout_after_first_alive); +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL const char *get_connectstring(char *buf, int buf_sz) const; int get_connected_port() const; const char *get_connected_host() const; void set_optimized_node_selection(int val); - Uint32 no_db_nodes(); + unsigned no_db_nodes(); +#endif private: friend class Ndb; diff --git a/ndb/include/transporter/TransporterDefinitions.hpp b/ndb/include/transporter/TransporterDefinitions.hpp index a8da8068552..4ff6b2073eb 100644 --- a/ndb/include/transporter/TransporterDefinitions.hpp +++ b/ndb/include/transporter/TransporterDefinitions.hpp @@ -68,6 +68,8 @@ struct TCP_TransporterConfiguration { */ struct SHM_TransporterConfiguration { Uint32 port; + const char *remoteHostName; + const char *localHostName; NodeId remoteNodeId; NodeId localNodeId; bool checksum; diff --git a/ndb/include/transporter/TransporterRegistry.hpp b/ndb/include/transporter/TransporterRegistry.hpp index 96da7eef2cb..7487d6b1e80 100644 --- a/ndb/include/transporter/TransporterRegistry.hpp +++ b/ndb/include/transporter/TransporterRegistry.hpp @@ -99,7 +99,12 @@ public: unsigned sizeOfLongSignalMemory = 100); bool init(NodeId localNodeId); - + + /** + * after a connect from client, perform connection using correct transporter + */ + bool connect_server(NDB_SOCKET_TYPE sockfd); + /** * Remove all transporters */ diff --git a/ndb/include/util/ndb_opts.h b/ndb/include/util/ndb_opts.h index 4bac36f5e5e..dc95149f706 100644 --- a/ndb/include/util/ndb_opts.h +++ b/ndb/include/util/ndb_opts.h @@ -34,7 +34,7 @@ OPT_NDB_OPTIMIZED_NODE_SELECTION #define OPT_NDB_CONNECTSTRING 'c' -#ifdef NDB_SHM_TRANSPORTER +#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 #define OPT_NDB_SHM_DEFAULT 1 #else #define OPT_NDB_SHM_DEFAULT 0 diff --git a/ndb/src/common/logger/LogHandler.cpp b/ndb/src/common/logger/LogHandler.cpp index a76cb622878..e038b05401e 100644 --- a/ndb/src/common/logger/LogHandler.cpp +++ b/ndb/src/common/logger/LogHandler.cpp @@ -24,7 +24,13 @@ LogHandler::LogHandler() : m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"), m_errorCode(0) -{ +{ + m_max_repeat_frequency= 3; // repeat messages maximum every 3 seconds + m_count_repeated_messages= 0; + m_last_category[0]= 0; + m_last_message[0]= 0; + m_last_log_time= 0; + m_now= 0; } LogHandler::~LogHandler() @@ -34,11 +40,53 @@ LogHandler::~LogHandler() void LogHandler::append(const char* pCategory, Logger::LoggerLevel level, const char* pMsg) -{ +{ + time_t now; + now= ::time((time_t*)NULL); + + if (level != m_last_level || + strcmp(pCategory, m_last_category) || + strcmp(pMsg, m_last_message)) + { + if (m_count_repeated_messages > 0) // print that message + append_impl(m_last_category, m_last_level, m_last_message); + + m_last_level= level; + strncpy(m_last_category, pCategory, sizeof(m_last_category)); + strncpy(m_last_message, pMsg, sizeof(m_last_message)); + } + else // repeated message + { + if (now < m_last_log_time+m_max_repeat_frequency) + { + m_count_repeated_messages++; + m_now= now; + return; + } + } + + m_now= now; + + append_impl(pCategory, level, pMsg); + m_last_log_time= now; +} + +void +LogHandler::append_impl(const char* pCategory, Logger::LoggerLevel level, + const char* pMsg) +{ writeHeader(pCategory, level); - writeMessage(pMsg); + if (m_count_repeated_messages == 0) + writeMessage(pMsg); + else + { + BaseString str(pMsg); + str.appfmt(" - Repeated %d times", m_count_repeated_messages); + writeMessage(str.c_str()); + m_count_repeated_messages= 0; + } writeFooter(); -} +} const char* LogHandler::getDefaultHeader(char* pStr, const char* pCategory, @@ -76,12 +124,10 @@ char* LogHandler::getTimeAsString(char* pStr) const { struct tm* tm_now; - time_t now; - now = ::time((time_t*)NULL); #ifdef NDB_WIN32 - tm_now = localtime(&now); + tm_now = localtime(&m_now); #else - tm_now = ::localtime(&now); //uses the "current" timezone + tm_now = ::localtime(&m_now); //uses the "current" timezone #endif BaseString::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH, diff --git a/ndb/src/common/logger/Logger.cpp b/ndb/src/common/logger/Logger.cpp index 4fa7b462563..7f18f5bd3ec 100644 --- a/ndb/src/common/logger/Logger.cpp +++ b/ndb/src/common/logger/Logger.cpp @@ -355,11 +355,11 @@ Logger::log(LoggerLevel logLevel, const char* pMsg, va_list ap) const LogHandler* pHandler = NULL; while ( (pHandler = m_pHandlerList->next()) != NULL) { - char buf[1024]; + char buf[MAX_LOG_MESSAGE_SIZE]; BaseString::vsnprintf(buf, sizeof(buf), pMsg, ap); pHandler->append(m_pCategory, logLevel, buf); } - } + } } // diff --git a/ndb/src/common/mgmcommon/IPCConfig.cpp b/ndb/src/common/mgmcommon/IPCConfig.cpp index 780504d2c62..1da03e3eaf2 100644 --- a/ndb/src/common/mgmcommon/IPCConfig.cpp +++ b/ndb/src/common/mgmcommon/IPCConfig.cpp @@ -383,6 +383,8 @@ IPCConfig::configureTransporters(Uint32 nodeId, if(iter.get(CFG_SHM_BUFFER_MEM, &conf.shmSize)) break; conf.port= server_port; + conf.localHostName = localHostName; + conf.remoteHostName = remoteHostName; if(!tr.createTransporter(&conf)){ DBUG_PRINT("error", ("Failed to create SHM Transporter from %d to %d", diff --git a/ndb/src/common/transporter/Makefile.am b/ndb/src/common/transporter/Makefile.am index d76b1b6048b..b902012e56d 100644 --- a/ndb/src/common/transporter/Makefile.am +++ b/ndb/src/common/transporter/Makefile.am @@ -13,7 +13,7 @@ EXTRA_libtransporter_la_SOURCES = SHM_Transporter.cpp SHM_Transporter.unix.cpp S libtransporter_la_LIBADD = @ndb_transporter_opt_objs@ libtransporter_la_DEPENDENCIES = @ndb_transporter_opt_objs@ -INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel -I$(top_srcdir)/ndb/include/transporter @NDB_SCI_INCLUDES@ +INCLUDES_LOC = -I$(top_srcdir)/ndb/include/mgmapi -I$(top_srcdir)/ndb/include/debugger -I$(top_srcdir)/ndb/include/kernel -I$(top_srcdir)/ndb/include/transporter @NDB_SCI_INCLUDES@ include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_util.mk.am diff --git a/ndb/src/common/transporter/SCI_Transporter.cpp b/ndb/src/common/transporter/SCI_Transporter.cpp index 73fbb064599..e7807c972b1 100644 --- a/ndb/src/common/transporter/SCI_Transporter.cpp +++ b/ndb/src/common/transporter/SCI_Transporter.cpp @@ -44,7 +44,8 @@ SCI_Transporter::SCI_Transporter(TransporterRegistry &t_reg, bool chksm, bool signalId, Uint32 reportFreq) : - Transporter(t_reg, lHostName, rHostName, r_port, _localNodeId, + Transporter(t_reg, tt_SCI_TRANSPORTER, + lHostName, rHostName, r_port, _localNodeId, _remoteNodeId, 0, false, chksm, signalId) { DBUG_ENTER("SCI_Transporter::SCI_Transporter"); diff --git a/ndb/src/common/transporter/SHM_Transporter.cpp b/ndb/src/common/transporter/SHM_Transporter.cpp index e4051519b86..ffb51bf1326 100644 --- a/ndb/src/common/transporter/SHM_Transporter.cpp +++ b/ndb/src/common/transporter/SHM_Transporter.cpp @@ -38,7 +38,8 @@ SHM_Transporter::SHM_Transporter(TransporterRegistry &t_reg, bool signalId, key_t _shmKey, Uint32 _shmSize) : - Transporter(t_reg, lHostName, rHostName, r_port, lNodeId, rNodeId, + Transporter(t_reg, tt_SHM_TRANSPORTER, + lHostName, rHostName, r_port, lNodeId, rNodeId, 0, false, checksum, signalId), shmKey(_shmKey), shmSize(_shmSize) @@ -256,6 +257,9 @@ SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd) SocketOutputStream s_output(sockfd); char buf[256]; +#if 1 +#endif + // Wait for server to create and attach if (s_input.gets(buf, 256) == 0) { NDB_CLOSE_SOCKET(sockfd); diff --git a/ndb/src/common/transporter/TCP_Transporter.cpp b/ndb/src/common/transporter/TCP_Transporter.cpp index 524ecd653e0..a629b620157 100644 --- a/ndb/src/common/transporter/TCP_Transporter.cpp +++ b/ndb/src/common/transporter/TCP_Transporter.cpp @@ -72,7 +72,8 @@ TCP_Transporter::TCP_Transporter(TransporterRegistry &t_reg, NodeId rNodeId, bool chksm, bool signalId, Uint32 _reportFreq) : - Transporter(t_reg, lHostName, rHostName, r_port, lNodeId, rNodeId, + Transporter(t_reg, tt_TCP_TRANSPORTER, + lHostName, rHostName, r_port, lNodeId, rNodeId, 0, false, chksm, signalId), m_sendBuffer(sendBufSize) { diff --git a/ndb/src/common/transporter/Transporter.cpp b/ndb/src/common/transporter/Transporter.cpp index ee25d97feef..b84f8f6fb5e 100644 --- a/ndb/src/common/transporter/Transporter.cpp +++ b/ndb/src/common/transporter/Transporter.cpp @@ -24,7 +24,11 @@ #include <InputStream.hpp> #include <OutputStream.hpp> +#include <EventLogger.hpp> +extern EventLogger g_eventLogger; + Transporter::Transporter(TransporterRegistry &t_reg, + TransporterType _type, const char *lHostName, const char *rHostName, int r_port, @@ -35,8 +39,10 @@ Transporter::Transporter(TransporterRegistry &t_reg, : m_r_port(r_port), remoteNodeId(rNodeId), localNodeId(lNodeId), isServer(lNodeId < rNodeId), m_packer(_signalId, _checksum), + m_type(_type), m_transporter_registry(t_reg) { + DBUG_ENTER("Transporter::Transporter"); if (rHostName && strlen(rHostName) > 0){ strncpy(remoteHostName, rHostName, sizeof(remoteHostName)); Ndb_getInAddr(&remoteHostAddress, rHostName); @@ -55,6 +61,11 @@ Transporter::Transporter(TransporterRegistry &t_reg, if (strlen(lHostName) > 0) Ndb_getInAddr(&localHostAddress, lHostName); + DBUG_PRINT("info",("rId=%d lId=%d isServer=%d rHost=%s lHost=%s r_port=%d", + remoteNodeId, localNodeId, isServer, + remoteHostName, localHostName, + r_port)); + byteOrder = _byteorder; compressionUsed = _compression; checksumUsed = _checksum; @@ -67,7 +78,9 @@ Transporter::Transporter(TransporterRegistry &t_reg, m_socket_client= 0; else m_socket_client= new SocketClient(remoteHostName, r_port, - new SocketAuthSimple("ndbd", "ndbd passwd")); + new SocketAuthSimple("ndbd", + "ndbd passwd")); + DBUG_VOID_RETURN; } Transporter::~Transporter(){ @@ -77,8 +90,13 @@ Transporter::~Transporter(){ bool Transporter::connect_server(NDB_SOCKET_TYPE sockfd) { + // all initial negotiation is done in TransporterRegistry::connect_server + DBUG_ENTER("Transporter::connect_server"); + if(m_connected) - return true; // TODO assert(0); + { + DBUG_RETURN(true); // TODO assert(0); + } bool res = connect_server_impl(sockfd); if(res){ @@ -86,7 +104,7 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) { m_errorCount = 0; } - return res; + DBUG_RETURN(res); } bool @@ -98,27 +116,60 @@ Transporter::connect_client() { if (sockfd == NDB_INVALID_SOCKET) return false; - // send info about own id + DBUG_ENTER("Transporter::connect_client"); + + // send info about own id + // send info about own transporter type SocketOutputStream s_output(sockfd); - s_output.println("%d", localNodeId); + s_output.println("%d %d", localNodeId, m_type); // get remote id - int nodeId; + int nodeId, remote_transporter_type= -1; SocketInputStream s_input(sockfd); char buf[256]; if (s_input.gets(buf, 256) == 0) { NDB_CLOSE_SOCKET(sockfd); - return false; + DBUG_RETURN(false); } - if (sscanf(buf, "%d", &nodeId) != 1) { + + int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type); + switch (r) { + case 2: + break; + case 1: + // we're running version prior to 4.1.9 + // ok, but with no checks on transporter configuration compatability + break; + default: NDB_CLOSE_SOCKET(sockfd); - return false; + DBUG_RETURN(false); } + + DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d", + nodeId, remote_transporter_type)); + + if (remote_transporter_type != -1) + { + if (remote_transporter_type != m_type) + { + DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d", + m_type, remote_transporter_type)); + NDB_CLOSE_SOCKET(sockfd); + g_eventLogger.error("Incompatible configuration: transporter type " + "mismatch with node %d", nodeId); + DBUG_RETURN(false); + } + } + else if (m_type == tt_SHM_TRANSPORTER) + { + g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId); + } + bool res = connect_client_impl(sockfd); if(res){ m_connected = true; m_errorCount = 0; } - return res; + DBUG_RETURN(res); } void diff --git a/ndb/src/common/transporter/Transporter.hpp b/ndb/src/common/transporter/Transporter.hpp index 9a39f8788bc..baff6d53dd8 100644 --- a/ndb/src/common/transporter/Transporter.hpp +++ b/ndb/src/common/transporter/Transporter.hpp @@ -71,6 +71,7 @@ public: protected: Transporter(TransporterRegistry &, + TransporterType, const char *lHostName, const char *rHostName, int r_port, @@ -127,6 +128,7 @@ protected: protected: bool m_connected; // Are we connected + TransporterType m_type; TransporterRegistry &m_transporter_registry; void *get_callback_obj() { return m_transporter_registry.callbackObj; }; @@ -149,7 +151,7 @@ Transporter::getRemoteNodeId() const { inline NodeId Transporter::getLocalNodeId() const { - return remoteNodeId; + return localNodeId; } inline diff --git a/ndb/src/common/transporter/TransporterRegistry.cpp b/ndb/src/common/transporter/TransporterRegistry.cpp index be51e9223ba..2eb81b2b35d 100644 --- a/ndb/src/common/transporter/TransporterRegistry.cpp +++ b/ndb/src/common/transporter/TransporterRegistry.cpp @@ -47,6 +47,9 @@ #include <InputStream.hpp> #include <OutputStream.hpp> +#include <EventLogger.hpp> +extern EventLogger g_eventLogger; + int g_shm_pid = 0; SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd) @@ -57,49 +60,10 @@ SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd) DBUG_RETURN(0); } + if (!m_transporter_registry->connect_server(sockfd)) { - // read node id from client - int nodeId; - SocketInputStream s_input(sockfd); - char buf[256]; - if (s_input.gets(buf, 256) == 0) { - NDB_CLOSE_SOCKET(sockfd); - DBUG_PRINT("error", ("Could not get node id from client")); - DBUG_RETURN(0); - } - if (sscanf(buf, "%d", &nodeId) != 1) { - NDB_CLOSE_SOCKET(sockfd); - DBUG_PRINT("error", ("Error in node id from client")); - DBUG_RETURN(0); - } - - //check that nodeid is valid and that there is an allocated transporter - if ( nodeId < 0 || nodeId >= (int)m_transporter_registry->maxTransporters) { - NDB_CLOSE_SOCKET(sockfd); - DBUG_PRINT("error", ("Node id out of range from client")); - DBUG_RETURN(0); - } - if (m_transporter_registry->theTransporters[nodeId] == 0) { - NDB_CLOSE_SOCKET(sockfd); - DBUG_PRINT("error", ("No transporter for this node id from client")); - DBUG_RETURN(0); - } - - //check that the transporter should be connected - if (m_transporter_registry->performStates[nodeId] != TransporterRegistry::CONNECTING) { - NDB_CLOSE_SOCKET(sockfd); - DBUG_PRINT("error", ("Transporter in wrong state for this node id from client")); - DBUG_RETURN(0); - } - - Transporter *t= m_transporter_registry->theTransporters[nodeId]; - - // send info about own id (just as response to acknowledge connection) - SocketOutputStream s_output(sockfd); - s_output.println("%d", t->getLocalNodeId()); - - // setup transporter (transporter responsible for closing sockfd) - t->connect_server(sockfd); + NDB_CLOSE_SOCKET(sockfd); + DBUG_RETURN(0); } DBUG_RETURN(0); @@ -196,6 +160,91 @@ TransporterRegistry::init(NodeId nodeId) { } bool +TransporterRegistry::connect_server(NDB_SOCKET_TYPE sockfd) +{ + DBUG_ENTER("TransporterRegistry::connect_server"); + + // read node id from client + // read transporter type + int nodeId, remote_transporter_type= -1; + SocketInputStream s_input(sockfd); + char buf[256]; + if (s_input.gets(buf, 256) == 0) { + DBUG_PRINT("error", ("Could not get node id from client")); + DBUG_RETURN(false); + } + int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type); + switch (r) { + case 2: + break; + case 1: + // we're running version prior to 4.1.9 + // ok, but with no checks on transporter configuration compatability + break; + default: + DBUG_PRINT("error", ("Error in node id from client")); + DBUG_RETURN(false); + } + + DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d", + nodeId,remote_transporter_type)); + + //check that nodeid is valid and that there is an allocated transporter + if ( nodeId < 0 || nodeId >= (int)maxTransporters) { + DBUG_PRINT("error", ("Node id out of range from client")); + DBUG_RETURN(false); + } + if (theTransporters[nodeId] == 0) { + DBUG_PRINT("error", ("No transporter for this node id from client")); + DBUG_RETURN(false); + } + + //check that the transporter should be connected + if (performStates[nodeId] != TransporterRegistry::CONNECTING) { + DBUG_PRINT("error", ("Transporter in wrong state for this node id from client")); + DBUG_RETURN(false); + } + + Transporter *t= theTransporters[nodeId]; + + // send info about own id (just as response to acknowledge connection) + // send info on own transporter type + SocketOutputStream s_output(sockfd); + s_output.println("%d %d", t->getLocalNodeId(), t->m_type); + + if (remote_transporter_type != -1) + { + if (remote_transporter_type != t->m_type) + { + DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d", + t->m_type, remote_transporter_type)); + g_eventLogger.error("Incompatible configuration: Transporter type " + "mismatch with node %d", nodeId); + + // wait for socket close for 1 second to let message arrive at client + { + fd_set a_set; + FD_ZERO(&a_set); + FD_SET(sockfd, &a_set); + struct timeval timeout; + timeout.tv_sec = 1; timeout.tv_usec = 0; + select(sockfd+1, &a_set, 0, 0, &timeout); + } + DBUG_RETURN(false); + } + } + else if (t->m_type == tt_SHM_TRANSPORTER) + { + g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId); + } + + // setup transporter (transporter responsible for closing sockfd) + t->connect_server(sockfd); + + DBUG_RETURN(true); +} + +bool TransporterRegistry::createTransporter(TCP_TransporterConfiguration *config) { #ifdef NDB_TCP_TRANSPORTER @@ -358,8 +407,8 @@ TransporterRegistry::createTransporter(SHM_TransporterConfiguration *config) { return false; SHM_Transporter * t = new SHM_Transporter(*this, - "localhost", - "localhost", + config->localHostName, + config->remoteHostName, config->port, localNodeId, config->remoteNodeId, diff --git a/ndb/src/kernel/main.cpp b/ndb/src/kernel/main.cpp index 44fe1725c9e..448bdd9a1fa 100644 --- a/ndb/src/kernel/main.cpp +++ b/ndb/src/kernel/main.cpp @@ -58,7 +58,7 @@ int main(int argc, char** argv) // Print to stdout/console g_eventLogger.createConsoleHandler(); g_eventLogger.setCategory("NDB"); - g_eventLogger.enable(Logger::LL_INFO, Logger::LL_ALERT); // Log INFO to ALERT + g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR); globalEmulatorData.create(); diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 3fcde997cb0..f698099141a 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -133,8 +133,7 @@ MgmtSrvr::signalRecvThreadRun() } } - -EventLogger g_EventLogger; +extern EventLogger g_eventLogger; static NdbOut& operator<<(NdbOut& out, const LogLevel & ll) @@ -200,7 +199,7 @@ MgmtSrvr::logLevelThreadRun() void MgmtSrvr::startEventLog() { - g_EventLogger.setCategory("MgmSrvr"); + g_eventLogger.setCategory("MgmSrvr"); ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator ((ndb_mgm_configuration*)_config->m_configValues, CFG_SECTION_NODE); @@ -226,7 +225,7 @@ MgmtSrvr::startEventLog() logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6", clusterLog); } - if(!g_EventLogger.addHandler(logdest)) { + if(!g_eventLogger.addHandler(logdest)) { ndbout << "Warning: could not add log destination \"" << logdest.c_str() << "\"" << endl; } @@ -250,21 +249,21 @@ MgmtSrvr::setEventLogFilter(int severity, int enable) { Logger::LoggerLevel level = (Logger::LoggerLevel)severity; if (enable > 0) { - g_EventLogger.enable(level); + g_eventLogger.enable(level); } else if (enable == 0) { - g_EventLogger.disable(level); - } else if (g_EventLogger.isEnable(level)) { - g_EventLogger.disable(level); + g_eventLogger.disable(level); + } else if (g_eventLogger.isEnable(level)) { + g_eventLogger.disable(level); } else { - g_EventLogger.enable(level); + g_eventLogger.enable(level); } - return g_EventLogger.isEnable(level); + return g_eventLogger.isEnable(level); } bool MgmtSrvr::isEventLogFilterEnabled(int severity) { - return g_EventLogger.isEnable((Logger::LoggerLevel)severity); + return g_eventLogger.isEnable((Logger::LoggerLevel)severity); } static ErrorItem errorTable[] = @@ -1990,7 +1989,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) } default: - g_EventLogger.error("Unknown signal received. SignalNumber: " + g_eventLogger.error("Unknown signal received. SignalNumber: " "%i from (%d, %x)", gsn, refToNode(signal->theSendersBlockRef), @@ -2066,7 +2065,7 @@ MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode) error: if(errCode != 0){ - g_EventLogger.error("Unexpected signal received. SignalNumber: %i from %d", + g_eventLogger.error("Unexpected signal received. SignalNumber: %i from %d", GSN_STOP_REF, nodeId); } } @@ -2286,7 +2285,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, m_reserved_nodes.set(id_found); char tmp_str[128]; m_reserved_nodes.getText(tmp_str); - g_EventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, m_reserved_nodes %s.", + g_eventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, m_reserved_nodes %s.", id_found, get_connect_address(id_found), tmp_str); DBUG_RETURN(true); } @@ -2346,7 +2345,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, *nodeId); } - g_EventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s. " + g_eventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s. " "Returned error string \"%s\"", *nodeId, client_addr != 0 ? inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr) : "<none>", @@ -2369,10 +2368,10 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, } } if (tmp_connected.length() > 0) - g_EventLogger.info("Mgmt server state: node id's %s connected but not reserved", + g_eventLogger.info("Mgmt server state: node id's %s connected but not reserved", tmp_connected.c_str()); if (tmp_not_connected.length() > 0) - g_EventLogger.info("Mgmt server state: node id's %s not connected but reserved", + g_eventLogger.info("Mgmt server state: node id's %s not connected but reserved", tmp_not_connected.c_str()); } DBUG_RETURN(false); @@ -2404,7 +2403,7 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData) EventReport::EventType type = eventReport->getEventType(); // Log event - g_EventLogger.log(type, theData, nodeId, + g_eventLogger.log(type, theData, nodeId, &m_event_listner[0].m_logLevel); m_event_listner.log(type, theData, nodeId); } @@ -2647,7 +2646,7 @@ MgmtSrvr::Allocated_resources::~Allocated_resources() char tmp_str[128]; m_mgmsrv.m_reserved_nodes.getText(tmp_str); - g_EventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.", + g_eventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.", get_nodeid(), tmp_str); } } diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index aa2cefae38c..4a8b79d3ddc 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -86,7 +86,7 @@ static MgmGlobals glob; * Global variables */ bool g_StopServer; -extern EventLogger g_EventLogger; +extern EventLogger g_eventLogger; extern int global_mgmt_server_check; @@ -284,12 +284,12 @@ int main(int argc, char** argv) BaseString::snprintf(msg, sizeof(msg), "NDB Cluster Management Server. %s", NDB_VERSION_STRING); ndbout_c(msg); - g_EventLogger.info(msg); + g_eventLogger.info(msg); BaseString::snprintf(msg, 256, "Id: %d, Command port: %d", glob.localNodeId, glob.port); ndbout_c(msg); - g_EventLogger.info(msg); + g_eventLogger.info(msg); g_StopServer = false; glob.socketServer->startServer(); @@ -305,10 +305,10 @@ int main(int argc, char** argv) NdbSleep_MilliSleep(500); } - g_EventLogger.info("Shutting down server..."); + g_eventLogger.info("Shutting down server..."); glob.socketServer->stopServer(); glob.socketServer->stopSessions(); - g_EventLogger.info("Shutdown complete"); + g_eventLogger.info("Shutdown complete"); return 0; error_end: return 1; diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index e9a125922c6..b5493622b70 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -282,7 +282,7 @@ Ndb::waitUntilReady(int timeout) } if (theImpl->m_ndb_cluster_connection.wait_until_ready - (timeout-secondsCounter,30)) + (timeout-secondsCounter,30) < 0) { theError.code = 4009; DBUG_RETURN(-1); diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp index 0a1433c71f3..c72568f7201 100644 --- a/ndb/src/ndbapi/NdbBlob.cpp +++ b/ndb/src/ndbapi/NdbBlob.cpp @@ -21,6 +21,7 @@ #include <NdbIndexOperation.hpp> #include <NdbRecAttr.hpp> #include <NdbBlob.hpp> +#include "NdbBlobImpl.hpp" #include <NdbScanOperation.hpp> #ifdef NDB_BLOB_DEBUG @@ -85,14 +86,14 @@ void NdbBlob::getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c) { assert(t != 0 && c != 0 && c->getBlobType()); - memset(btname, 0, BlobTableNameSize); + memset(btname, 0, NdbBlobImpl::BlobTableNameSize); sprintf(btname, "NDB$BLOB_%d_%d", (int)t->m_tableId, (int)c->m_attrId); } void NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c) { - char btname[BlobTableNameSize]; + char btname[NdbBlobImpl::BlobTableNameSize]; getBlobTableName(btname, t, c); bt.setName(btname); bt.setLogging(t->getLogging()); @@ -450,15 +451,15 @@ NdbBlob::getValue(void* data, Uint32 bytes) { DBG("getValue data=" << hex << data << " bytes=" << dec << bytes); if (theGetFlag || theState != Prepared) { - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } if (! isReadOp() && ! isScanOp()) { - setErrorCode(ErrUsage); + setErrorCode(NdbBlobImpl::ErrUsage); return -1; } if (data == NULL && bytes != 0) { - setErrorCode(ErrUsage); + setErrorCode(NdbBlobImpl::ErrUsage); return -1; } theGetFlag = true; @@ -472,15 +473,15 @@ NdbBlob::setValue(const void* data, Uint32 bytes) { DBG("setValue data=" << hex << data << " bytes=" << dec << bytes); if (theSetFlag || theState != Prepared) { - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } if (! isInsertOp() && ! isUpdateOp() && ! isWriteOp()) { - setErrorCode(ErrUsage); + setErrorCode(NdbBlobImpl::ErrUsage); return -1; } if (data == NULL && bytes != 0) { - setErrorCode(ErrUsage); + setErrorCode(NdbBlobImpl::ErrUsage); return -1; } theSetFlag = true; @@ -512,7 +513,7 @@ NdbBlob::setActiveHook(ActiveHook activeHook, void* arg) { DBG("setActiveHook hook=" << hex << (void*)activeHook << " arg=" << hex << arg); if (theState != Prepared) { - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } theActiveHook = activeHook; @@ -531,7 +532,7 @@ NdbBlob::getNull(bool& isNull) return 0; } if (theNullFlag == -1) { - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } isNull = theNullFlag; @@ -546,7 +547,7 @@ NdbBlob::setNull() if (theState == Prepared) { return setValue(0, 0); } - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } if (theNullFlag) @@ -568,7 +569,7 @@ NdbBlob::getLength(Uint64& len) return 0; } if (theNullFlag == -1) { - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } len = theLength; @@ -580,7 +581,7 @@ NdbBlob::truncate(Uint64 length) { DBG("truncate [in] length=" << length); if (theNullFlag == -1) { - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } if (theLength > length) { @@ -608,7 +609,7 @@ NdbBlob::getPos(Uint64& pos) { DBG("getPos"); if (theNullFlag == -1) { - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } pos = thePos; @@ -620,11 +621,11 @@ NdbBlob::setPos(Uint64 pos) { DBG("setPos pos=" << pos); if (theNullFlag == -1) { - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } if (pos > theLength) { - setErrorCode(ErrSeek); + setErrorCode(NdbBlobImpl::ErrSeek); return -1; } thePos = pos; @@ -637,7 +638,7 @@ int NdbBlob::readData(void* data, Uint32& bytes) { if (theState != Active) { - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } char* buf = static_cast<char*>(data); @@ -666,7 +667,7 @@ NdbBlob::readDataPrivate(char* buf, Uint32& bytes) } } if (len > 0 && thePartSize == 0) { - setErrorCode(ErrSeek); + setErrorCode(NdbBlobImpl::ErrSeek); return -1; } if (len > 0) { @@ -731,7 +732,7 @@ int NdbBlob::writeData(const void* data, Uint32 bytes) { if (theState != Active) { - setErrorCode(ErrState); + setErrorCode(NdbBlobImpl::ErrState); return -1; } const char* buf = static_cast<const char*>(data); @@ -764,7 +765,7 @@ NdbBlob::writeDataPrivate(const char* buf, Uint32 bytes) } } if (len > 0 && thePartSize == 0) { - setErrorCode(ErrSeek); + setErrorCode(NdbBlobImpl::ErrSeek); return -1; } if (len > 0) { @@ -1081,7 +1082,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* theFillChar = 0x20; break; default: - setErrorCode(ErrUsage); + setErrorCode(NdbBlobImpl::ErrUsage); return -1; } // sizes @@ -1099,7 +1100,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* (bc = bt->getColumn("DATA")) == NULL || bc->getType() != partType || bc->getLength() != (int)thePartSize) { - setErrorCode(ErrTable); + setErrorCode(NdbBlobImpl::ErrTable); return -1; } theBlobTable = &NdbTableImpl::getImpl(*bt); @@ -1120,7 +1121,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* Uint32* data = (Uint32*)theKeyBuf.data; unsigned size = theTable->m_keyLenInWords; if (theNdbOp->getKeyFromTCREQ(data, size) == -1) { - setErrorCode(ErrUsage); + setErrorCode(NdbBlobImpl::ErrUsage); return -1; } } @@ -1129,7 +1130,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* Uint32* data = (Uint32*)theAccessKeyBuf.data; unsigned size = theAccessTable->m_keyLenInWords; if (theNdbOp->getKeyFromTCREQ(data, size) == -1) { - setErrorCode(ErrUsage); + setErrorCode(NdbBlobImpl::ErrUsage); return -1; } } @@ -1158,7 +1159,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* supportedOp = true; } if (! supportedOp) { - setErrorCode(ErrUsage); + setErrorCode(NdbBlobImpl::ErrUsage); return -1; } setState(Prepared); @@ -1204,7 +1205,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch) tOp->updateTuple() == -1 || setTableKeyValue(tOp) == -1 || setHeadInlineValue(tOp) == -1) { - setErrorCode(ErrAbort); + setErrorCode(NdbBlobImpl::ErrAbort); return -1; } DBG("add op to update head+inline"); @@ -1434,7 +1435,7 @@ NdbBlob::postExecute(ExecType anExecType) tOp->updateTuple() == -1 || setTableKeyValue(tOp) == -1 || setHeadInlineValue(tOp) == -1) { - setErrorCode(ErrAbort); + setErrorCode(NdbBlobImpl::ErrAbort); return -1; } tOp->m_abortOption = AbortOnError; @@ -1464,7 +1465,7 @@ NdbBlob::preCommit() tOp->updateTuple() == -1 || setTableKeyValue(tOp) == -1 || setHeadInlineValue(tOp) == -1) { - setErrorCode(ErrAbort); + setErrorCode(NdbBlobImpl::ErrAbort); return -1; } tOp->m_abortOption = AbortOnError; @@ -1489,7 +1490,7 @@ NdbBlob::atNextResult() { Uint32* data = (Uint32*)theKeyBuf.data; unsigned size = theTable->m_keyLenInWords; if (((NdbScanOperation*)theNdbOp)->getKeyFromKEYINFO20(data, size) == -1) { - setErrorCode(ErrUsage); + setErrorCode(NdbBlobImpl::ErrUsage); return -1; } } @@ -1545,7 +1546,7 @@ NdbBlob::setErrorCode(NdbOperation* anOp, bool invalidFlag) else if ((code = theNdb->theError.code) != 0) ; else - code = ErrUnknown; + code = NdbBlobImpl::ErrUnknown; setErrorCode(code, invalidFlag); } @@ -1558,7 +1559,7 @@ NdbBlob::setErrorCode(NdbConnection* aCon, bool invalidFlag) else if ((code = theNdb->theError.code) != 0) ; else - code = ErrUnknown; + code = NdbBlobImpl::ErrUnknown; setErrorCode(code, invalidFlag); } diff --git a/ndb/src/ndbapi/NdbBlobImpl.hpp b/ndb/src/ndbapi/NdbBlobImpl.hpp new file mode 100644 index 00000000000..0030e910c52 --- /dev/null +++ b/ndb/src/ndbapi/NdbBlobImpl.hpp @@ -0,0 +1,39 @@ +/* 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 */ + +#ifndef NdbBlobImpl_H +#define NdbBlobImpl_H + +class NdbBlobImpl { +public: + STATIC_CONST( BlobTableNameSize = 40 ); + // "Invalid blob attributes or invalid blob parts table" + STATIC_CONST( ErrTable = 4263 ); + // "Invalid usage of blob attribute" + STATIC_CONST( ErrUsage = 4264 ); + // "Method is not valid in current blob state" + STATIC_CONST( ErrState = 4265 ); + // "Invalid blob seek position" + STATIC_CONST( ErrSeek = 4266 ); + // "Corrupted blob value" + STATIC_CONST( ErrCorrupt = 4267 ); + // "Error in blob head update forced rollback of transaction" + STATIC_CONST( ErrAbort = 4268 ); + // "Unknown blob error" + STATIC_CONST( ErrUnknown = 4269 ); +}; + +#endif diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index 29959a4ed7e..aa4f68a85b4 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -361,11 +361,10 @@ NdbConnection::execute(ExecType aTypeOfExec, if (executeNoBlobs(tExecType, abortOption, forceSend) == -1) ret = -1; -#ifndef VM_TRACE - // can happen in complex abort cases - theFirstOpInList = theLastOpInList = NULL; -#else +#ifdef ndb_api_crash_on_complex_blob_abort assert(theFirstOpInList == NULL && theLastOpInList == NULL); +#else + theFirstOpInList = theLastOpInList = NULL; #endif { diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index d39b921072b..b3b8e48edd1 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -34,7 +34,8 @@ #include <AttributeList.hpp> #include <NdbEventOperation.hpp> #include "NdbEventOperationImpl.hpp" -#include "NdbBlob.hpp" +#include <NdbBlob.hpp> +#include "NdbBlobImpl.hpp" #include <AttributeHeader.hpp> #include <my_sys.h> @@ -1381,7 +1382,7 @@ NdbDictionaryImpl::addBlobTables(NdbTableImpl &t) if (! c.getBlobType() || c.getPartSize() == 0) continue; n--; - char btname[NdbBlob::BlobTableNameSize]; + char btname[NdbBlobImpl::BlobTableNameSize]; NdbBlob::getBlobTableName(btname, &t, &c); // Save BLOB table handle NdbTableImpl * cachedBlobTable = getTable(btname); @@ -1789,7 +1790,7 @@ NdbDictionaryImpl::dropBlobTables(NdbTableImpl & t) NdbColumnImpl & c = *t.m_columns[i]; if (! c.getBlobType() || c.getPartSize() == 0) continue; - char btname[NdbBlob::BlobTableNameSize]; + char btname[NdbBlobImpl::BlobTableNameSize]; NdbBlob::getBlobTableName(btname, &t, &c); if (dropTable(btname) != 0) { if (m_error.code != 709){ diff --git a/ndb/src/ndbapi/NdbOperationDefine.cpp b/ndb/src/ndbapi/NdbOperationDefine.cpp index d9aa860f71f..bc960a72d2e 100644 --- a/ndb/src/ndbapi/NdbOperationDefine.cpp +++ b/ndb/src/ndbapi/NdbOperationDefine.cpp @@ -523,7 +523,9 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, CHARSET_INFO* cs = tAttrInfo->m_cs; // invalid data can crash kernel if (cs != NULL && - (*cs->cset->well_formed_len)(cs, + // fast fix bug#7340 + tAttrInfo->m_type != NdbDictionary::Column::Text && + (*cs->cset->well_formed_len)(cs, aValue, aValue + sizeInBytes, sizeInBytes) != sizeInBytes) { diff --git a/ndb/src/ndbapi/NdbOperationInt.cpp b/ndb/src/ndbapi/NdbOperationInt.cpp index ee7b8132cd1..ace90e35ca4 100644 --- a/ndb/src/ndbapi/NdbOperationInt.cpp +++ b/ndb/src/ndbapi/NdbOperationInt.cpp @@ -15,21 +15,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/************************************************************************************************ -Name: NdbOperationInt.C -Include: -Link: -Author: UABRONM Mikael Ronström UAB/M/MT -Date: 991029 -Version: 0.1 -Description: Interpreted operations in NDB API -Documentation: -Adjust: 991029 UABRONM First version. -************************************************************************************************/ -#include "NdbOperation.hpp" +#include <ndb_global.h> +#include <NdbOperation.hpp> #include "NdbApiSignal.hpp" -#include "NdbConnection.hpp" -#include "Ndb.hpp" +#include <NdbConnection.hpp> +#include <Ndb.hpp> #include "NdbRecAttr.hpp" #include "NdbUtil.hpp" #include "Interpreter.hpp" diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp index e1af7bd4cc5..a11dd842495 100644 --- a/ndb/src/ndbapi/Ndbinit.cpp +++ b/ndb/src/ndbapi/Ndbinit.cpp @@ -204,14 +204,6 @@ Ndb::~Ndb() TransporterFacade::instance()->close(theNdbBlockNumber, theFirstTransId); } - if (global_ndb_cluster_connection != 0) { - theNoOfNdbObjects--; - if(theNoOfNdbObjects == 0){ - delete global_ndb_cluster_connection; - global_ndb_cluster_connection= 0; - } - }//if - // if (theSchemaConToNdbList != NULL) // closeSchemaTransaction(theSchemaConToNdbList); while ( theConIdleList != NULL ) @@ -249,6 +241,19 @@ Ndb::~Ndb() delete theImpl; + /** + * This needs to be put after delete theImpl + * as TransporterFacade::instance is delete by global_ndb_cluster_connection + * and used by theImpl + */ + if (global_ndb_cluster_connection != 0) { + theNoOfNdbObjects--; + if(theNoOfNdbObjects == 0){ + delete global_ndb_cluster_connection; + global_ndb_cluster_connection= 0; + } + }//if + /** * This sleep is to make sure that the transporter * send thread will come in and send any diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index 98a52786aab..5df707e211d 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -31,6 +31,9 @@ #include <Vector.hpp> #include <md5_hash.hpp> +#include <EventLogger.hpp> +EventLogger g_eventLogger; + static int g_run_connect_thread= 0; #include <NdbMutex.h> @@ -174,7 +177,7 @@ Ndb_cluster_connection_impl::get_next_node(Ndb_cluster_connection_node_iter &ite return node.id; } -Uint32 +unsigned Ndb_cluster_connection::no_db_nodes() { return m_impl.m_all_nodes.size(); @@ -219,16 +222,8 @@ Ndb_cluster_connection::wait_until_ready(int timeout, else if (foundAliveNode > 0) { noChecksSinceFirstAliveFound++; - if (timeout_after_first_alive >= 0) - { - if (noChecksSinceFirstAliveFound > timeout_after_first_alive) - DBUG_RETURN(0); - } - else // timeout_after_first_alive < 0 - { - if (noChecksSinceFirstAliveFound > -timeout_after_first_alive) - DBUG_RETURN(-1); - } + if (noChecksSinceFirstAliveFound > timeout_after_first_alive) + DBUG_RETURN(1); } else if (secondsCounter >= timeout) { // no alive nodes and timed out @@ -256,6 +251,11 @@ Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char * { DBUG_ENTER("Ndb_cluster_connection"); DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%x", this)); + + g_eventLogger.createConsoleHandler(); + g_eventLogger.setCategory("NdbApi"); + g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR); + m_transporter_facade= TransporterFacade::theFacadeInstance= new TransporterFacade(); diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp index 4b532856709..7b30777456f 100644 --- a/ndb/test/ndbapi/testBlobs.cpp +++ b/ndb/test/ndbapi/testBlobs.cpp @@ -23,13 +23,14 @@ #include <NdbOut.hpp> #include <NdbTest.hpp> #include <NdbTick.h> +#include <ndb/src/ndbapi/NdbBlobImpl.hpp> struct Bcol { bool m_nullable; unsigned m_inline; unsigned m_partsize; unsigned m_stripe; - char m_btname[NdbBlob::BlobTableNameSize]; + char m_btname[NdbBlobImpl::BlobTableNameSize]; Bcol(bool a, unsigned b, unsigned c, unsigned d) : m_nullable(a), m_inline(b), @@ -153,6 +154,7 @@ testcase(char x) (g_opt.m_skip == 0 || strchr(g_opt.m_skip, x) == 0); } +static Ndb_cluster_connection* g_ncc = 0; static Ndb* g_ndb = 0; static NdbDictionary::Dictionary* g_dic = 0; static NdbConnection* g_con = 0; @@ -1258,7 +1260,7 @@ deleteScan(bool idx) static int testmain() { - g_ndb = new Ndb("TEST_DB"); + g_ndb = new Ndb(g_ncc, "TEST_DB"); CHK(g_ndb->init() == 0); CHK(g_ndb->waitUntilReady() == 0); g_dic = g_ndb->getDictionary(); @@ -1447,7 +1449,7 @@ testperf() if (! testcase('p')) return 0; DBG("=== perf test ==="); - g_ndb = new Ndb("TEST_DB"); + g_ndb = new Ndb(g_ncc, "TEST_DB"); CHK(g_ndb->init() == 0); CHK(g_ndb->waitUntilReady() == 0); g_dic = g_ndb->getDictionary(); @@ -1859,10 +1861,13 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) strcat(b, "r"); g_opt.m_skip = strdup(b); } - if (testmain() == -1 || testperf() == -1) { + g_ncc = new Ndb_cluster_connection(); + if (g_ncc->connect(30) != 0 || testmain() == -1 || testperf() == -1) { ndbout << "line " << __LINE__ << " FAIL loop=" << g_loop << endl; return NDBT_ProgramExit(NDBT_FAILED); } + delete g_ncc; + g_ncc = 0; return NDBT_ProgramExit(NDBT_OK); } diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp index 41f0686e63b..e6d3844d18e 100644 --- a/ndb/test/ndbapi/testOIBasic.cpp +++ b/ndb/test/ndbapi/testOIBasic.cpp @@ -59,7 +59,7 @@ struct Opt { unsigned m_subloop; const char* m_table; unsigned m_threads; - unsigned m_v; + int m_v; Opt() : m_batch(32), m_bound("01234"), @@ -672,6 +672,8 @@ tabcount = sizeof(tablist) / sizeof(tablist[0]); // connections +static Ndb_cluster_connection* g_ncc = 0; + struct Con { Ndb* m_ndb; NdbDictionary::Dictionary* m_dic; @@ -720,7 +722,7 @@ int Con::connect() { assert(m_ndb == 0); - m_ndb = new Ndb("TEST_DB"); + m_ndb = new Ndb(g_ncc, "TEST_DB"); CHKCON(m_ndb->init() == 0, *this); CHKCON(m_ndb->waitUntilReady(30) == 0, *this); m_tx = 0, m_op = 0; @@ -3514,8 +3516,11 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) } { Par par(g_opt); - if (runtest(par) < 0) + g_ncc = new Ndb_cluster_connection(); + if (g_ncc->connect(30) != 0 || runtest(par) < 0) goto failed; + delete g_ncc; + g_ncc = 0; } // always exit with NDBT code ok: diff --git a/ndb/test/run-test/main.cpp b/ndb/test/run-test/main.cpp index ac7710d9546..fb6754dae7a 100644 --- a/ndb/test/run-test/main.cpp +++ b/ndb/test/run-test/main.cpp @@ -275,6 +275,7 @@ parse_args(int argc, const char** argv){ int tmp = Logger::LL_WARNING - g_verbosity; tmp = (tmp < Logger::LL_DEBUG ? Logger::LL_DEBUG : tmp); g_logger.disable(Logger::LL_ALL); + g_logger.enable(Logger::LL_ON); g_logger.enable((Logger::LoggerLevel)tmp, Logger::LL_ALERT); } |