diff options
author | unknown <joreland@mysql.com> | 2004-12-17 10:36:14 +0100 |
---|---|---|
committer | unknown <joreland@mysql.com> | 2004-12-17 10:36:14 +0100 |
commit | 72c28731e9f7eade53ba7394305b05ac1b66bb20 (patch) | |
tree | 415dace493b0f4c1982e36cb17b6a6008150149b /ndb | |
parent | b181f610e1c5bd29a21a4b73bb2fa58b37a18d6b (diff) | |
parent | 4630d406d11a8e7c0e8dc4b8601fc8dd94e8a343 (diff) | |
download | mariadb-git-72c28731e9f7eade53ba7394305b05ac1b66bb20.tar.gz |
merge
BitKeeper/etc/logging_ok:
auto-union
configure.in:
Auto merged
ndb/include/Makefile.am:
Auto merged
ndb/include/kernel/LogLevel.hpp:
Auto merged
ndb/include/mgmapi/mgmapi.h:
Auto merged
ndb/include/ndbapi/NdbConnection.hpp:
Auto merged
ndb/include/ndbapi/NdbDictionary.hpp:
Auto merged
ndb/src/common/debugger/EventLogger.cpp:
Auto merged
ndb/src/common/logger/FileLogHandler.cpp:
Auto merged
ndb/src/common/logger/Logger.cpp:
Auto merged
ndb/src/common/mgmcommon/ConfigRetriever.cpp:
Auto merged
ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp:
Auto merged
ndb/src/kernel/blocks/dbdict/Dbdict.cpp:
Auto merged
ndb/src/kernel/blocks/dbdih/Dbdih.hpp:
Auto merged
ndb/src/kernel/blocks/dbdih/DbdihMain.cpp:
Auto merged
ndb/src/kernel/main.cpp:
Auto merged
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp:
Auto merged
ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp:
Auto merged
ndb/src/kernel/vm/Configuration.cpp:
Auto merged
ndb/src/mgmapi/mgmapi.cpp:
Auto merged
ndb/src/mgmsrv/InitConfigFileParser.cpp:
Auto merged
ndb/src/mgmsrv/MgmtSrvr.cpp:
Auto merged
ndb/src/mgmsrv/MgmtSrvr.hpp:
Auto merged
ndb/src/mgmsrv/Services.cpp:
Auto merged
ndb/src/mgmsrv/Services.hpp:
Auto merged
ndb/src/mgmsrv/main.cpp:
Auto merged
ndb/src/ndbapi/NdbConnection.cpp:
Auto merged
ndb/src/ndbapi/TransporterFacade.cpp:
Auto merged
ndb/src/ndbapi/ndberror.c:
Auto merged
ndb/tools/Makefile.am:
Auto merged
Diffstat (limited to 'ndb')
104 files changed, 2287 insertions, 1542 deletions
diff --git a/ndb/include/Makefile.am b/ndb/include/Makefile.am index b1e72dacffd..b29433a59b7 100644 --- a/ndb/include/Makefile.am +++ b/ndb/include/Makefile.am @@ -28,15 +28,14 @@ ndbapi/NdbIndexScanOperation.hpp \ ndbapi/ndberror.h mgmapiinclude_HEADERS = \ -mgmapi/LocalConfig.hpp \ mgmapi/mgmapi.h \ -mgmapi/mgmapi_debug.h +mgmapi/mgmapi_debug.h \ +mgmapi/mgmapi_config_parameters.h \ +mgmapi/mgmapi_config_parameters_debug.h noinst_HEADERS = \ ndb_global.h \ -ndb_net.h \ -mgmapi/mgmapi_config_parameters.h \ -mgmapi/mgmapi_config_parameters_debug.h +ndb_net.h EXTRA_DIST = debugger editline kernel logger mgmcommon \ portlib transporter util diff --git a/ndb/include/debugger/EventLogger.hpp b/ndb/include/debugger/EventLogger.hpp index 686989089ae..ddf21b79f5f 100644 --- a/ndb/include/debugger/EventLogger.hpp +++ b/ndb/include/debugger/EventLogger.hpp @@ -48,6 +48,10 @@ public: static const EventRepLogLevelMatrix matrix[]; static const Uint32 matrixSize; + static int event_lookup(int eventType, + LogLevel::EventCategory &cat, + Uint32 &threshold, + Logger::LoggerLevel &severity); }; /** diff --git a/ndb/include/kernel/LogLevel.hpp b/ndb/include/kernel/LogLevel.hpp index 5981ca4701a..3c2f349e0e1 100644 --- a/ndb/include/kernel/LogLevel.hpp +++ b/ndb/include/kernel/LogLevel.hpp @@ -73,7 +73,7 @@ public: /** * Note level is valid as 0-15 */ - void setLogLevel(EventCategory ec, Uint32 level = 7); + int setLogLevel(EventCategory ec, Uint32 level = 7); /** * Get the loglevel (0-15) for a category @@ -119,10 +119,14 @@ LogLevel::clear(){ } inline -void +int LogLevel::setLogLevel(EventCategory ec, Uint32 level){ - assert(ec >= 0 && (Uint32) ec < LOGLEVEL_CATEGORIES); - logLevelData[ec] = (Uint8)level; + if (ec >= 0 && (Uint32) ec < LOGLEVEL_CATEGORIES) + { + logLevelData[ec] = (Uint8)level; + return 0; + } + return 1; } inline diff --git a/ndb/include/kernel/signaldata/ArbitSignalData.hpp b/ndb/include/kernel/signaldata/ArbitSignalData.hpp index f255b8dcbbe..34b73644a13 100644 --- a/ndb/include/kernel/signaldata/ArbitSignalData.hpp +++ b/ndb/include/kernel/signaldata/ArbitSignalData.hpp @@ -94,13 +94,14 @@ public: // arbitration result LoseNodes = 41, // lose on ndb node count - WinGroups = 42, // we win, no need for arbitration - LoseGroups = 43, // we lose, missing node group - Partitioning = 44, // possible network partitioning - WinChoose = 45, // positive reply - LoseChoose = 46, // negative reply - LoseNorun = 47, // arbitrator required but not running - LoseNocfg = 48, // arbitrator required but none configured + WinNodes = 42, // win on ndb node count + WinGroups = 43, // we win, no need for arbitration + LoseGroups = 44, // we lose, missing node group + Partitioning = 45, // possible network partitioning + WinChoose = 46, // positive reply + LoseChoose = 47, // negative reply + LoseNorun = 48, // arbitrator required but not running + LoseNocfg = 49, // arbitrator required but none configured // general error codes ErrTicket = 91, // invalid arbitrator-ticket diff --git a/ndb/include/kernel/signaldata/BackupImpl.hpp b/ndb/include/kernel/signaldata/BackupImpl.hpp index 1872069daa7..2ac91570aad 100644 --- a/ndb/include/kernel/signaldata/BackupImpl.hpp +++ b/ndb/include/kernel/signaldata/BackupImpl.hpp @@ -78,15 +78,15 @@ public: STATIC_CONST( SignalLength = 3 ); enum ErrorCode { - Undefined = 200, - FailedToAllocateBuffers = 202, - FailedToSetupFsBuffers = 203, - FailedToAllocateTables = 204, - FailedInsertFileHeader = 205, - FailedInsertTableList = 206, - FailedAllocateTableMem = 207, - FailedToAllocateFileRecord = 208, - FailedToAllocateAttributeRecord = 209 + Undefined = 1340, + FailedToAllocateBuffers = 1342, + FailedToSetupFsBuffers = 1343, + FailedToAllocateTables = 1344, + FailedInsertFileHeader = 1345, + FailedInsertTableList = 1346, + FailedAllocateTableMem = 1347, + FailedToAllocateFileRecord = 1348, + FailedToAllocateAttributeRecord = 1349 }; private: Uint32 backupId; diff --git a/ndb/include/kernel/signaldata/BackupSignalData.hpp b/ndb/include/kernel/signaldata/BackupSignalData.hpp index 42eb8464d53..fb018026a49 100644 --- a/ndb/include/kernel/signaldata/BackupSignalData.hpp +++ b/ndb/include/kernel/signaldata/BackupSignalData.hpp @@ -119,12 +119,13 @@ public: private: enum ErrorCodes { - Undefined = 100, - IAmNotMaster = 101, - OutOfBackupRecord = 102, - OutOfResources = 103, - SequenceFailure = 104, - BackupDefinitionNotImplemented = 105 + Undefined = 1300, + IAmNotMaster = 1301, + OutOfBackupRecord = 1302, + OutOfResources = 1303, + SequenceFailure = 1304, + BackupDefinitionNotImplemented = 1305, + CannotBackupDiskless = 1306 }; Uint32 senderData; Uint32 errorCode; @@ -232,13 +233,13 @@ public: STATIC_CONST( SignalLength = 3 ); enum RequestType { - ClientAbort = 1, - BackupComplete = 2, - BackupFailure = 3, // General backup failure coordinator -> slave - LogBufferFull = 4, // slave -> coordinator - FileOrScanError = 5, // slave -> coordinator - BackupFailureDueToNodeFail = 6, // slave -> slave - OkToClean = 7 // master -> slave + ClientAbort = 1321, + BackupComplete = 1322, + BackupFailure = 1323, // General backup failure coordinator -> slave + LogBufferFull = 1324, // slave -> coordinator + FileOrScanError = 1325, // slave -> coordinator + BackupFailureDueToNodeFail = 1326, // slave -> slave + OkToClean = 1327 // master -> slave }; private: Uint32 requestType; diff --git a/ndb/include/kernel/signaldata/CreateEvnt.hpp b/ndb/include/kernel/signaldata/CreateEvnt.hpp index 65a07c122a2..e911fa36ce6 100644 --- a/ndb/include/kernel/signaldata/CreateEvnt.hpp +++ b/ndb/include/kernel/signaldata/CreateEvnt.hpp @@ -475,14 +475,14 @@ struct CreateEvntRef { } }; inline bool CreateEvntRef::isTemporary() const -{ return (errorCode & CreateEvntRef::Temporary) > 0; }; +{ return (errorCode & CreateEvntRef::Temporary) > 0; } inline void CreateEvntRef::setTemporary() -{ errorCode |= CreateEvntRef::Temporary; }; +{ errorCode |= CreateEvntRef::Temporary; } inline CreateEvntRef::ErrorCode CreateEvntRef::setTemporary(ErrorCode ec) { return (CreateEvntRef::ErrorCode) - (errorCode = ((Uint32) ec | (Uint32)CreateEvntRef::Temporary)); }; + (errorCode = ((Uint32) ec | (Uint32)CreateEvntRef::Temporary)); } inline CreateEvntRef::ErrorCode CreateEvntRef::makeTemporary(ErrorCode ec) { return (CreateEvntRef::ErrorCode) - ( (Uint32) ec | (Uint32)CreateEvntRef::Temporary ); }; + ( (Uint32) ec | (Uint32)CreateEvntRef::Temporary ); } #endif diff --git a/ndb/include/kernel/signaldata/PackedSignal.hpp b/ndb/include/kernel/signaldata/PackedSignal.hpp index 057bb39b25a..ea0ff6db526 100644 --- a/ndb/include/kernel/signaldata/PackedSignal.hpp +++ b/ndb/include/kernel/signaldata/PackedSignal.hpp @@ -38,6 +38,6 @@ class PackedSignal { }; inline -Uint32 PackedSignal::getSignalType(Uint32 data) { return data >> 28; }; +Uint32 PackedSignal::getSignalType(Uint32 data) { return data >> 28; } #endif diff --git a/ndb/include/kernel/signaldata/SumaImpl.hpp b/ndb/include/kernel/signaldata/SumaImpl.hpp index 089132cd9aa..89ade067dcd 100644 --- a/ndb/include/kernel/signaldata/SumaImpl.hpp +++ b/ndb/include/kernel/signaldata/SumaImpl.hpp @@ -159,12 +159,12 @@ public: Uint32 subscriberRef; }; inline bool SubStartRef::isTemporary() const -{ return (errorCode & SubStartRef::Temporary) > 0; }; +{ return (errorCode & SubStartRef::Temporary) > 0; } inline void SubStartRef::setTemporary() -{ errorCode |= SubStartRef::Temporary; }; +{ errorCode |= SubStartRef::Temporary; } inline SubStartRef::ErrorCode SubStartRef::setTemporary(ErrorCode ec) { return (SubStartRef::ErrorCode) - (errorCode = ((Uint32) ec | (Uint32)SubStartRef::Temporary)); }; + (errorCode = ((Uint32) ec | (Uint32)SubStartRef::Temporary)); } class SubStartConf { /** @@ -239,12 +239,12 @@ public: }; }; inline bool SubStopRef::isTemporary() const -{ return (errorCode & SubStopRef::Temporary) > 0; }; +{ return (errorCode & SubStopRef::Temporary) > 0; } inline void SubStopRef::setTemporary() -{ errorCode |= SubStopRef::Temporary; }; +{ errorCode |= SubStopRef::Temporary; } inline SubStopRef::ErrorCode SubStopRef::setTemporary(ErrorCode ec) { return (SubStopRef::ErrorCode) - (errorCode = ((Uint32) ec | (Uint32)SubStopRef::Temporary)); }; + (errorCode = ((Uint32) ec | (Uint32)SubStopRef::Temporary)); } class SubStopConf { /** @@ -515,12 +515,12 @@ public: }; }; inline bool SubRemoveRef::isTemporary() const -{ return (err & SubRemoveRef::Temporary) > 0; }; +{ return (err & SubRemoveRef::Temporary) > 0; } inline void SubRemoveRef::setTemporary() -{ err |= SubRemoveRef::Temporary; }; +{ err |= SubRemoveRef::Temporary; } inline SubRemoveRef::ErrorCode SubRemoveRef::setTemporary(ErrorCode ec) { return (SubRemoveRef::ErrorCode) - (errorCode = ((Uint32) ec | (Uint32)SubRemoveRef::Temporary)); }; + (errorCode = ((Uint32) ec | (Uint32)SubRemoveRef::Temporary)); } class SubRemoveConf { /** diff --git a/ndb/include/logger/Logger.hpp b/ndb/include/logger/Logger.hpp index c6145f2091a..f12297023b7 100644 --- a/ndb/include/logger/Logger.hpp +++ b/ndb/include/logger/Logger.hpp @@ -101,7 +101,7 @@ public: /** The log levels. NOTE: Could not use the name LogLevel since * it caused conflicts with another class. */ - enum LoggerLevel {LL_OFF, LL_DEBUG, LL_INFO, LL_WARNING, LL_ERROR, + enum LoggerLevel {LL_ON, LL_DEBUG, LL_INFO, LL_WARNING, LL_ERROR, LL_CRITICAL, LL_ALERT, LL_ALL}; /** diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h index 6b261bd8751..3d4a34d6488 100644 --- a/ndb/include/mgmapi/mgmapi.h +++ b/ndb/include/mgmapi/mgmapi.h @@ -245,7 +245,9 @@ extern "C" { * Log severities (used to filter the cluster log) */ enum ndb_mgm_clusterlog_level { - NDB_MGM_CLUSTERLOG_OFF = 0, /*< Cluster log off*/ + NDB_MGM_ILLEGAL_CLUSTERLOG_LEVEL = -1, + /* must range from 0 and up, indexes into an array */ + NDB_MGM_CLUSTERLOG_ON = 0, /*< Cluster log on*/ NDB_MGM_CLUSTERLOG_DEBUG = 1, /*< Used in NDB Cluster *< developement */ @@ -265,7 +267,8 @@ extern "C" { *< corrected immediately, *< such as a corrupted system */ - NDB_MGM_CLUSTERLOG_ALL = 7 /*< All severities on*/ + /* must be next number, works as bound in loop */ + NDB_MGM_CLUSTERLOG_ALL = 7 /*< All severities */ }; /** @@ -357,11 +360,27 @@ extern "C" { /** * Create a handle to a management server * - * @return A management handle<br> - * or NULL if no management handle could be created. + * @return A management handle<br> + * or NULL if no management handle could be created. */ NdbMgmHandle ndb_mgm_create_handle(); + /** + * Set connecst string to management server + * + * @param handle Management handle + * @param connect_string Connect string to the management server, + * + * @return -1 on error. + */ + int ndb_mgm_set_connectstring(NdbMgmHandle handle, + const char *connect_string); + + int ndb_mgm_get_configuration_nodeid(NdbMgmHandle handle); + int ndb_mgm_get_connected_port(NdbMgmHandle handle); + const char *ndb_mgm_get_connected_host(NdbMgmHandle handle); + const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz); + /** * Destroy a management server handle * @@ -379,11 +398,10 @@ extern "C" { * Connect to a management server * * @param handle Management handle. - * @param mgmsrv Hostname and port of the management server, - * "hostname:port". * @return -1 on error. */ - int ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv); + int ndb_mgm_connect(NdbMgmHandle handle, int no_retries, + int retry_delay_in_seconds, int verbose); /** * Disconnect from a management server @@ -566,11 +584,13 @@ extern "C" { * * @param handle NDB management handle. * @param level A cluster log level to filter. + * @param enable set 1=enable 0=disable * @param reply Reply message. * @return -1 on error. */ int ndb_mgm_filter_clusterlog(NdbMgmHandle handle, enum ndb_mgm_clusterlog_level level, + int enable, struct ndb_mgm_reply* reply); /** @@ -606,6 +626,11 @@ extern "C" { int level, struct ndb_mgm_reply* reply); + ndb_mgm_clusterlog_level + ndb_mgm_match_clusterlog_level(const char * name); + const char * + ndb_mgm_get_clusterlog_level_string(enum ndb_mgm_clusterlog_level level); + /** * Set log category and levels for the Node * @@ -642,11 +667,15 @@ extern "C" { * Start backup * * @param handle NDB management handle. + * @param wait_completed 0=don't wait for confirmation + 1=wait for backup started + 2=wait for backup completed * @param backup_id Backup id is returned from function. * @param reply Reply message. * @return -1 on error. */ - int ndb_mgm_start_backup(NdbMgmHandle handle, unsigned int* backup_id, + int ndb_mgm_start_backup(NdbMgmHandle handle, int wait_completed, + unsigned int* backup_id, struct ndb_mgm_reply* reply); /** @@ -710,9 +739,7 @@ extern "C" { void ndb_mgm_destroy_configuration(struct ndb_mgm_configuration *); int ndb_mgm_alloc_nodeid(NdbMgmHandle handle, - unsigned version, - unsigned *pnodeid, - int nodetype); + unsigned version, int nodetype); /** * Config iterator */ @@ -735,6 +762,7 @@ extern "C" { int ndb_mgm_get_string_parameter(const ndb_mgm_configuration_iterator*, int param, const char ** value); int ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **); + int ndb_mgm_check_connection(NdbMgmHandle handle); #ifdef __cplusplus } #endif diff --git a/ndb/include/mgmcommon/ConfigRetriever.hpp b/ndb/include/mgmcommon/ConfigRetriever.hpp index 6c32255e921..8461658748e 100644 --- a/ndb/include/mgmcommon/ConfigRetriever.hpp +++ b/ndb/include/mgmcommon/ConfigRetriever.hpp @@ -20,7 +20,6 @@ #include <ndb_types.h> #include <mgmapi.h> #include <BaseString.hpp> -#include <LocalConfig.hpp> /** * @class ConfigRetriever @@ -28,10 +27,11 @@ */ class ConfigRetriever { public: - ConfigRetriever(LocalConfig &local_config, Uint32 version, Uint32 nodeType); + ConfigRetriever(const char * _connect_string, + Uint32 version, Uint32 nodeType); ~ConfigRetriever(); - int do_connect(int exit_on_connect_failure= false); + int do_connect(int no_retries, int retry_delay_in_seconds, int verbose); /** * Get configuration for current node. @@ -46,12 +46,14 @@ public: */ struct ndb_mgm_configuration * getConfig(); + void resetError(); + int hasError(); const char * getErrorString(); /** * @return Node id of this node (as stated in local config or connectString) */ - Uint32 allocNodeId(); + Uint32 allocNodeId(int no_retries, int retry_delay_in_seconds); /** * Get config using socket @@ -68,22 +70,27 @@ public: */ bool verifyConfig(const struct ndb_mgm_configuration *, Uint32 nodeid); - Uint32 get_mgmd_port() const {return m_mgmd_port;}; - const char *get_mgmd_host() const {return m_mgmd_host;}; + Uint32 get_mgmd_port() const; + const char *get_mgmd_host() const; + const char *get_connectstring(char *buf, int buf_sz) const; + + Uint32 get_configuration_nodeid() const; private: BaseString errorString; enum ErrorType { - CR_ERROR = 0, - CR_RETRY = 1 + CR_NO_ERROR = 0, + CR_ERROR = 1, + CR_RETRY = 2 }; ErrorType latestErrorType; void setError(ErrorType, const char * errorMsg); - struct LocalConfig& _localConfig; - Uint32 _ownNodeId; + Uint32 _ownNodeId; + /* Uint32 m_mgmd_port; const char *m_mgmd_host; + */ Uint32 m_version; Uint32 m_node_type; diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp index 5043cb0e26d..166355cae17 100644 --- a/ndb/include/ndbapi/NdbConnection.hpp +++ b/ndb/include/ndbapi/NdbConnection.hpp @@ -607,8 +607,8 @@ private: NdbOperation* theLastExecOpInList; // Last executing operation in list. - NdbOperation* theCompletedFirstOp; // First operation in completed - // operation list. + NdbOperation* theCompletedFirstOp; // First & last operation in completed + NdbOperation* theCompletedLastOp; // operation list. Uint32 theNoOfOpSent; // How many operations have been sent Uint32 theNoOfOpCompleted; // How many operations have completed diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp index 217243071d0..f0c8a10f488 100644 --- a/ndb/include/ndbapi/NdbDictionary.hpp +++ b/ndb/include/ndbapi/NdbDictionary.hpp @@ -982,13 +982,6 @@ public: */ const Table * getTable(const char * name); - /** - * Get table with given name for alteration. - * @param name Name of table to alter - * @return table if successful. NULL if undefined - */ - Table getTableForAlteration(const char * name); - #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL /** * Invalidate cached table object diff --git a/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/ndb/include/ndbapi/NdbIndexScanOperation.hpp index 66b3fc9d43b..a3388f62f58 100644 --- a/ndb/include/ndbapi/NdbIndexScanOperation.hpp +++ b/ndb/include/ndbapi/NdbIndexScanOperation.hpp @@ -113,7 +113,7 @@ public: * Reset bounds and put operation in list that will be * sent on next execute */ - int reset_bounds(); + int reset_bounds(bool forceSend = false); bool getSorted() const { return m_ordered; } private: @@ -127,8 +127,8 @@ private: virtual NdbRecAttr* getValue_impl(const NdbColumnImpl*, char*); void fix_get_values(); - int next_result_ordered(bool fetchAllowed); - int send_next_scan_ordered(Uint32 idx); + int next_result_ordered(bool fetchAllowed, bool forceSend = false); + int send_next_scan_ordered(Uint32 idx, bool forceSend = false); int compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*); Uint32 m_sort_columns; diff --git a/ndb/include/ndbapi/NdbResultSet.hpp b/ndb/include/ndbapi/NdbResultSet.hpp index 478daf8aad2..dc0288a380c 100644 --- a/ndb/include/ndbapi/NdbResultSet.hpp +++ b/ndb/include/ndbapi/NdbResultSet.hpp @@ -89,17 +89,17 @@ public: * - 1: if there are no more tuples to scan. * - 2: if there are no more cached records in NdbApi */ - int nextResult(bool fetchAllowed = true); + int nextResult(bool fetchAllowed = true, bool forceSend = false); /** * Close result set (scan) */ - void close(); + void close(bool forceSend = false); /** * Restart */ - int restart(); + int restart(bool forceSend = false); /** * Transfer scan operation to an updating transaction. Use this function diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp index 5689b62526c..f25f9405033 100644 --- a/ndb/include/ndbapi/NdbScanOperation.hpp +++ b/ndb/include/ndbapi/NdbScanOperation.hpp @@ -90,11 +90,11 @@ protected: NdbScanOperation(Ndb* aNdb); virtual ~NdbScanOperation(); - int nextResult(bool fetchAllowed = true); + int nextResult(bool fetchAllowed = true, bool forceSend = false); virtual void release(); - void closeScan(); - int close_impl(class TransporterFacade*); + void closeScan(bool forceSend = false); + int close_impl(class TransporterFacade*, bool forceSend = false); // Overloaded methods from NdbCursorOperation int executeCursor(int ProcessorId); @@ -103,6 +103,7 @@ protected: int init(const NdbTableImpl* tab, NdbConnection* myConnection); int prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId); int doSend(int ProcessorId); + void checkForceSend(bool forceSend); virtual void setErrorCode(int aErrorCode); virtual void setErrorCodeAbort(int aErrorCode); @@ -147,7 +148,7 @@ protected: Uint32 m_sent_receivers_count; // NOTE needs mutex to access NdbReceiver** m_sent_receivers; // receive thread puts them here - int send_next_scan(Uint32 cnt, bool close); + int send_next_scan(Uint32 cnt, bool close, bool forceSend = false); void receiver_delivered(NdbReceiver*); void receiver_completed(NdbReceiver*); void execCLOSE_SCAN_REP(); @@ -157,7 +158,7 @@ protected: Uint32 m_ordered; - int restart(); + int restart(bool forceSend = false); }; inline diff --git a/ndb/include/ndbapi/ndb_cluster_connection.hpp b/ndb/include/ndbapi/ndb_cluster_connection.hpp index 6e24e084f58..db1cd0b119e 100644 --- a/ndb/include/ndbapi/ndb_cluster_connection.hpp +++ b/ndb/include/ndbapi/ndb_cluster_connection.hpp @@ -19,7 +19,6 @@ #define CLUSTER_CONNECTION_HPP class TransporterFacade; -struct LocalConfig; class ConfigRetriever; struct NdbThread; @@ -31,14 +30,15 @@ class Ndb_cluster_connection { public: Ndb_cluster_connection(const char * connect_string = 0); ~Ndb_cluster_connection(); - int connect(int reconnect= 0); + int connect(int no_retries, int retry_delay_in_seconds, int verbose); int start_connect_thread(int (*connect_callback)(void)= 0); + const char *get_connectstring(char *buf, int buf_sz) const; + int get_connected_port() const; + const char *get_connected_host() const; private: friend void* run_ndb_cluster_connection_connect_thread(void*); void connect_thread(); - char *m_connect_string; TransporterFacade *m_facade; - LocalConfig *m_local_config; ConfigRetriever *m_config_retriever; NdbThread *m_connect_thread; int (*m_connect_callback)(void); diff --git a/ndb/include/ndbapi/ndberror.h b/ndb/include/ndbapi/ndberror.h index 5c2d85b82a6..ceb1881a4cc 100644 --- a/ndb/include/ndbapi/ndberror.h +++ b/ndb/include/ndbapi/ndberror.h @@ -46,7 +46,8 @@ typedef enum ndberror_cl_internal_error = 12, ndberror_cl_function_not_implemented = 13, ndberror_cl_unknown_error_code = 14, - ndberror_cl_node_shutdown = 15 + ndberror_cl_node_shutdown = 15, + ndberror_cl_configuration = 16 } ndberror_classification_enum; diff --git a/ndb/include/util/BaseString.hpp b/ndb/include/util/BaseString.hpp index 066a24f294e..02a6a3b3e66 100644 --- a/ndb/include/util/BaseString.hpp +++ b/ndb/include/util/BaseString.hpp @@ -48,10 +48,10 @@ public: bool empty() const; /** @brief Convert to uppercase */ - void ndb_toupper(); + BaseString& ndb_toupper(); /** @brief Convert to lowercase */ - void ndb_tolower(); + BaseString& ndb_tolower(); /** @brief Assigns from a char * */ BaseString& assign(const char* s); @@ -206,16 +206,18 @@ BaseString::empty() const return m_len == 0; } -inline void +inline BaseString& BaseString::ndb_toupper() { for(unsigned i = 0; i < length(); i++) m_chr[i] = toupper(m_chr[i]); + return *this; } -inline void +inline BaseString& BaseString::ndb_tolower() { for(unsigned i = 0; i < length(); i++) m_chr[i] = tolower(m_chr[i]); + return *this; } inline bool diff --git a/ndb/include/util/ndb_opts.h b/ndb/include/util/ndb_opts.h index 6cba9c04449..f7ae3b5489e 100644 --- a/ndb/include/util/ndb_opts.h +++ b/ndb/include/util/ndb_opts.h @@ -32,10 +32,13 @@ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \ { "version", 'V', "Output version information and exit.", 0, 0, 0, \ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \ - { "connect-string", 'c', \ + { "ndb-connectstring", 'c', \ "Set connect string for connecting to ndb_mgmd. " \ - "<constr>=\"host=<hostname:port>[;nodeid=<id>]\". " \ - "Overides specifying entries in NDB_CONNECTSTRING and config file", \ + "Syntax: \"[nodeid=<id>;][host=]<hostname>[:<port>]\". " \ + "Overides specifying entries in NDB_CONNECTSTRING and Ndb.cfg", \ + (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, \ + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },\ + { "connect-string", 'c', "same as --ndb-connectstring",\ (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, \ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 } #else @@ -46,11 +49,14 @@ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \ { "version", 'V', "Output version information and exit.", 0, 0, 0, \ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, \ - { "connect-string", 'c', \ + { "ndb-connectstring", 'c', \ "Set connect string for connecting to ndb_mgmd. " \ - "<constr>=\"host=<hostname:port>[;nodeid=<id>]\". " \ - "Overides specifying entries in NDB_CONNECTSTRING and config file", \ + "Syntax: \"[nodeid=<id>;][host=]<hostname>[:<port>]\". " \ + "Overides specifying entries in NDB_CONNECTSTRING and Ndb.cfg", \ (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, \ + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },\ + { "connect-string", 'c', "same as --ndb-connectstring",\ + (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0,\ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 } #endif diff --git a/ndb/src/common/debugger/EventLogger.cpp b/ndb/src/common/debugger/EventLogger.cpp index 8f186a9efe7..97945394690 100644 --- a/ndb/src/common/debugger/EventLogger.cpp +++ b/ndb/src/common/debugger/EventLogger.cpp @@ -421,6 +421,11 @@ EventLogger::getText(char * m_text, size_t m_text_len, "%sArbitration check lost - less than 1/2 nodes left", theNodeId); break; + case ArbitCode::WinNodes: + BaseString::snprintf(m_text, m_text_len, + "%sArbitration check won - all node groups and more than 1/2 nodes left", + theNodeId); + break; case ArbitCode::WinGroups: BaseString::snprintf(m_text, m_text_len, "%sArbitration check won - node group majority", @@ -1275,10 +1280,10 @@ EventLogger::getText(char * m_text, size_t m_text_len, case EventReport::BackupCompleted: BaseString::snprintf(m_text, m_text_len, - "%sBackup %d started from node %d completed\n" - " StartGCP: %d StopGCP: %d\n" - " #Records: %d #LogRecords: %d\n" - " Data: %d bytes Log: %d bytes", + "%sBackup %u started from node %u completed\n" + " StartGCP: %u StopGCP: %u\n" + " #Records: %u #LogRecords: %u\n" + " Data: %u bytes Log: %u bytes", theNodeId, theData[2], refToNode(theData[1]), theData[3], theData[4], theData[6], theData[8], theData[5], theData[7]); @@ -1337,27 +1342,41 @@ operator<<(NdbOut& out, const LogLevel & ll) return out; } -void -EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId, - const LogLevel* ll) +int +EventLoggerBase::event_lookup(int eventType, + LogLevel::EventCategory &cat, + Uint32 &threshold, + Logger::LoggerLevel &severity) { - Uint32 threshold = 0; - Logger::LoggerLevel severity = Logger::LL_WARNING; - LogLevel::EventCategory cat= LogLevel::llInvalid; - for(unsigned i = 0; i<EventLoggerBase::matrixSize; i++){ if(EventLoggerBase::matrix[i].eventType == eventType){ cat = EventLoggerBase::matrix[i].eventCategory; threshold = EventLoggerBase::matrix[i].threshold; severity = EventLoggerBase::matrix[i].severity; - break; + return 0; } } + return 1; +} + +void +EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId, + const LogLevel* ll) +{ + Uint32 threshold = 0; + Logger::LoggerLevel severity = Logger::LL_WARNING; + LogLevel::EventCategory cat= LogLevel::llInvalid; + + DBUG_ENTER("EventLogger::log"); + DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId)); - if (cat == LogLevel::llInvalid) - return; + if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity)) + DBUG_VOID_RETURN; Uint32 set = ll?ll->getLogLevel(cat) : m_logLevel.getLogLevel(cat); + DBUG_PRINT("info",("threshold=%d, set=%d", threshold, set)); + if (ll) + DBUG_PRINT("info",("m_logLevel.getLogLevel=%d", m_logLevel.getLogLevel(cat))); if (threshold <= set){ switch (severity){ case Logger::LL_ALERT: @@ -1396,6 +1415,7 @@ EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId, break; } } // if (.. + DBUG_VOID_RETURN; } int diff --git a/ndb/src/common/debugger/signaldata/DictTabInfo.cpp b/ndb/src/common/debugger/signaldata/DictTabInfo.cpp index 7e7bf87e2db..c6165532ddb 100644 --- a/ndb/src/common/debugger/signaldata/DictTabInfo.cpp +++ b/ndb/src/common/debugger/signaldata/DictTabInfo.cpp @@ -152,4 +152,4 @@ DictTabInfo::Attribute::init(){ AttributeExtLength = 0, AttributeAutoIncrement = false; memset(AttributeDefaultValue, 0, sizeof(AttributeDefaultValue));//AttributeDefaultValue[0] = 0; -}; +} diff --git a/ndb/src/common/debugger/signaldata/NFCompleteRep.cpp b/ndb/src/common/debugger/signaldata/NFCompleteRep.cpp index 20f7ea99871..f2d6f2f104a 100644 --- a/ndb/src/common/debugger/signaldata/NFCompleteRep.cpp +++ b/ndb/src/common/debugger/signaldata/NFCompleteRep.cpp @@ -41,4 +41,4 @@ printNF_COMPLETE_REP(FILE * output, sig->from); return true; -}; +} diff --git a/ndb/src/common/logger/FileLogHandler.cpp b/ndb/src/common/logger/FileLogHandler.cpp index 98b2848feba..8678b999b6f 100644 --- a/ndb/src/common/logger/FileLogHandler.cpp +++ b/ndb/src/common/logger/FileLogHandler.cpp @@ -198,7 +198,7 @@ FileLogHandler::setFilename(const BaseString &filename) { m_pLogFile = new File_class(filename.c_str(), "a+"); open(); return true; -}; +} bool FileLogHandler::setMaxSize(const BaseString &size) { @@ -214,7 +214,7 @@ FileLogHandler::setMaxSize(const BaseString &size) { m_maxFileSize = val; return true; -}; +} bool FileLogHandler::setMaxFiles(const BaseString &files) { @@ -225,7 +225,7 @@ FileLogHandler::setMaxFiles(const BaseString &files) { m_maxNoFiles = val; return true; -}; +} bool FileLogHandler::checkParams() { diff --git a/ndb/src/common/logger/LogHandler.cpp b/ndb/src/common/logger/LogHandler.cpp index 4fab957fc50..a76cb622878 100644 --- a/ndb/src/common/logger/LogHandler.cpp +++ b/ndb/src/common/logger/LogHandler.cpp @@ -117,10 +117,9 @@ LogHandler::parseParams(const BaseString &_params) { _params.split(v_args, ","); for(size_t i=0; i < v_args.size(); i++) { Vector<BaseString> v_param_value; - - v_args[i].split(v_param_value, "=", 2); - if(v_param_value.size() == 2 && - !setParam(v_param_value[0], v_param_value[1])) + if(v_args[i].split(v_param_value, "=", 2) != 2) + ret = false; + else if (!setParam(v_param_value[0], v_param_value[1])) ret = false; } diff --git a/ndb/src/common/logger/Logger.cpp b/ndb/src/common/logger/Logger.cpp index 0e2d204cefa..4fa7b462563 100644 --- a/ndb/src/common/logger/Logger.cpp +++ b/ndb/src/common/logger/Logger.cpp @@ -30,7 +30,7 @@ // // PUBLIC // -const char* Logger::LoggerLevelNames[] = { "OFF ", +const char* Logger::LoggerLevelNames[] = { "ON ", "DEBUG ", "INFO ", "WARNING ", @@ -46,7 +46,9 @@ Logger::Logger() : m_pSyslogHandler(NULL) { m_pHandlerList = new LogHandlerList(); - m_logLevels[LL_INFO] = true; + disable(LL_ALL); + enable(LL_ON); + enable(LL_INFO); } Logger::~Logger() @@ -169,10 +171,13 @@ Logger::addHandler(const BaseString &logstring) { size_t i; Vector<BaseString> logdest; Vector<LogHandler *>loghandlers; + DBUG_ENTER("Logger::addHandler"); logstring.split(logdest, ";"); for(i = 0; i < logdest.size(); i++) { + DBUG_PRINT("info",("adding: %s",logdest[i].c_str())); + Vector<BaseString> v_type_args; logdest[i].split(v_type_args, ":", 2); @@ -195,16 +200,16 @@ Logger::addHandler(const BaseString &logstring) { handler = new ConsoleLogHandler(); if(handler == NULL) - return false; + DBUG_RETURN(false); if(!handler->parseParams(params)) - return false; + DBUG_RETURN(false); loghandlers.push_back(handler); } for(i = 0; i < loghandlers.size(); i++) addHandler(loghandlers[i]); - return true; /* @todo handle errors */ + DBUG_RETURN(true); /* @todo handle errors */ } bool @@ -228,6 +233,13 @@ Logger::removeAllHandlers() bool Logger::isEnable(LoggerLevel logLevel) const { + if (logLevel == LL_ALL) + { + for (unsigned i = 1; i < MAX_LOG_LEVELS; i++) + if (!m_logLevels[i]) + return false; + return true; + } return m_logLevels[logLevel]; } @@ -236,7 +248,7 @@ Logger::enable(LoggerLevel logLevel) { if (logLevel == LL_ALL) { - for (unsigned i = 1; i < MAX_LOG_LEVELS; i++) + for (unsigned i = 0; i < MAX_LOG_LEVELS; i++) { m_logLevels[i] = true; } @@ -338,7 +350,7 @@ Logger::debug(const char* pMsg, ...) const void Logger::log(LoggerLevel logLevel, const char* pMsg, va_list ap) const { - if (m_logLevels[LL_OFF] == false && m_logLevels[logLevel]) + if (m_logLevels[LL_ON] && m_logLevels[logLevel]) { LogHandler* pHandler = NULL; while ( (pHandler = m_pHandlerList->next()) != NULL) diff --git a/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/ndb/src/common/mgmcommon/ConfigRetriever.cpp index 06cc7a9cce0..db00cc1510f 100644 --- a/ndb/src/common/mgmcommon/ConfigRetriever.cpp +++ b/ndb/src/common/mgmcommon/ConfigRetriever.cpp @@ -20,7 +20,6 @@ #include <ConfigRetriever.hpp> #include <SocketServer.hpp> -#include "LocalConfig.hpp" #include <NdbSleep.h> #include <NdbOut.hpp> @@ -45,90 +44,67 @@ //**************************************************************************** //**************************************************************************** -ConfigRetriever::ConfigRetriever(LocalConfig &local_config, +ConfigRetriever::ConfigRetriever(const char * _connect_string, Uint32 version, Uint32 node_type) - : _localConfig(local_config) { - m_handle= 0; m_version = version; m_node_type = node_type; - _ownNodeId = _localConfig._ownNodeId; -} + _ownNodeId= 0; + + m_handle= ndb_mgm_create_handle(); -ConfigRetriever::~ConfigRetriever(){ + if (m_handle == 0) { + setError(CR_ERROR, "Unable to allocate mgm handle"); + return; + } + + if (ndb_mgm_set_connectstring(m_handle, _connect_string)) + { + setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle)); + return; + } + resetError(); +} +ConfigRetriever::~ConfigRetriever() +{ if (m_handle) { ndb_mgm_disconnect(m_handle); ndb_mgm_destroy_handle(&m_handle); } } +Uint32 +ConfigRetriever::get_configuration_nodeid() const +{ + return ndb_mgm_get_configuration_nodeid(m_handle); +} + +Uint32 ConfigRetriever::get_mgmd_port() const +{ + return ndb_mgm_get_connected_port(m_handle); +} + +const char *ConfigRetriever::get_mgmd_host() const +{ + return ndb_mgm_get_connected_host(m_handle); +} + +const char *ConfigRetriever::get_connectstring(char *buf, int buf_sz) const +{ + return ndb_mgm_get_connectstring(m_handle, buf, buf_sz); +} //**************************************************************************** //**************************************************************************** int -ConfigRetriever::do_connect(int exit_on_connect_failure){ - - m_mgmd_port= 0; - m_mgmd_host= 0; - - if(!m_handle) - m_handle= ndb_mgm_create_handle(); - - if (m_handle == 0) { - setError(CR_ERROR, "Unable to allocate mgm handle"); - return -1; - } - - int retry = 1; - int retry_max = 12; // Max number of retry attempts - int retry_interval= 5; // Seconds between each retry - while(retry < retry_max){ - Uint32 type = CR_ERROR; - BaseString tmp; - for (unsigned int i = 0; i<_localConfig.ids.size(); i++){ - MgmtSrvrId * m = &_localConfig.ids[i]; - DBUG_PRINT("info",("trying %s:%d", - m->name.c_str(), - m->port)); - switch(m->type){ - case MgmId_TCP: - tmp.assfmt("%s:%d", m->name.c_str(), m->port); - if (ndb_mgm_connect(m_handle, tmp.c_str()) == 0) { - m_mgmd_port= m->port; - m_mgmd_host= m->name.c_str(); - DBUG_PRINT("info",("connected to ndb_mgmd at %s:%d", - m_mgmd_host, - m_mgmd_port)); - return 0; - } - setError(CR_RETRY, ndb_mgm_get_latest_error_desc(m_handle)); - case MgmId_File: - break; - } - } - if(latestErrorType == CR_RETRY){ - DBUG_PRINT("info",("CR_RETRY")); - if (exit_on_connect_failure) - return 1; - REPORT_WARNING("Failed to retrieve cluster configuration"); - ndbout << "(Cause of failure: " << getErrorString() << ")" << endl; - ndbout << "Attempt " << retry << " of " << retry_max << ". " - << "Trying again in "<< retry_interval <<" seconds..." - << endl << endl; - NdbSleep_SecSleep(retry_interval); - } else { - break; - } - retry++; - } - - ndb_mgm_destroy_handle(&m_handle); - m_handle= 0; - m_mgmd_port= 0; - m_mgmd_host= 0; - return -1; +ConfigRetriever::do_connect(int no_retries, + int retry_delay_in_seconds, int verbose) +{ + return + (ndb_mgm_connect(m_handle,no_retries,retry_delay_in_seconds,verbose)==0) ? + 0 : -1; } //**************************************************************************** @@ -140,22 +116,9 @@ ConfigRetriever::getConfig() { struct ndb_mgm_configuration * p = 0; - if(m_handle != 0){ + if(m_handle != 0) p = getConfig(m_handle); - } else { - for (unsigned int i = 0; i<_localConfig.ids.size(); i++){ - MgmtSrvrId * m = &_localConfig.ids[i]; - switch(m->type){ - case MgmId_File: - p = getConfig(m->name.c_str()); - break; - case MgmId_TCP: - break; - } - if(p) - break; - } - } + if(p == 0) return 0; @@ -230,6 +193,16 @@ ConfigRetriever::setError(ErrorType et, const char * s){ latestErrorType = et; } +void +ConfigRetriever::resetError(){ + setError(CR_NO_ERROR,0); +} + +int +ConfigRetriever::hasError() +{ + return latestErrorType != CR_NO_ERROR; +} const char * ConfigRetriever::getErrorString(){ @@ -344,16 +317,23 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 } Uint32 -ConfigRetriever::allocNodeId(){ - unsigned nodeid= _ownNodeId; - - if(m_handle != 0){ - int res= ndb_mgm_alloc_nodeid(m_handle, m_version, &nodeid, m_node_type); - if(res != 0) { - setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle)); - return 0; +ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds) +{ + _ownNodeId= 0; + if(m_handle != 0) + { + while (1) + { + int res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type); + if(res >= 0) + return _ownNodeId= (Uint32)res; + if (no_retries == 0) + break; + no_retries--; + NdbSleep_SecSleep(retry_delay_in_seconds); } - } - - return _ownNodeId= nodeid; + setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle)); + } else + setError(CR_ERROR, "management server handle not initialized"); + return 0; } diff --git a/ndb/src/common/portlib/NdbTCP.cpp b/ndb/src/common/portlib/NdbTCP.cpp index 35b0c8c21e4..a63f5a7ba27 100644 --- a/ndb/src/common/portlib/NdbTCP.cpp +++ b/ndb/src/common/portlib/NdbTCP.cpp @@ -22,7 +22,7 @@ extern "C" int Ndb_getInAddr(struct in_addr * dst, const char *address) { - DBUG_ENTER("Ndb_getInAddr"); + // DBUG_ENTER("Ndb_getInAddr"); { int tmp_errno; struct hostent tmp_hostent, *hp; @@ -33,7 +33,7 @@ Ndb_getInAddr(struct in_addr * dst, const char *address) { { memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length)); my_gethostbyname_r_free(); - DBUG_RETURN(0); + return 0; //DBUG_RETURN(0); } my_gethostbyname_r_free(); } @@ -47,11 +47,11 @@ Ndb_getInAddr(struct in_addr * dst, const char *address) { #endif ) { - DBUG_RETURN(0); + return 0; //DBUG_RETURN(0); } - DBUG_PRINT("error",("inet_addr(%s) - %d - %s", - address, errno, strerror(errno))); - DBUG_RETURN(-1); + // DBUG_PRINT("error",("inet_addr(%s) - %d - %s", + // address, errno, strerror(errno))); + return -1; //DBUG_RETURN(-1); } #if 0 diff --git a/ndb/src/common/util/NdbOut.cpp b/ndb/src/common/util/NdbOut.cpp index fa74cb364f3..e20119a7987 100644 --- a/ndb/src/common/util/NdbOut.cpp +++ b/ndb/src/common/util/NdbOut.cpp @@ -54,7 +54,7 @@ NdbOut& NdbOut::operator<<(unsigned long int v) { return *this << (Uint64) v; } NdbOut& -NdbOut::operator<<(const char* val){ m_out->print("%s", val); return * this; } +NdbOut::operator<<(const char* val){ m_out->print("%s", val ? val : "(null)"); return * this; } NdbOut& NdbOut::operator<<(const void* val){ m_out->print("%p", val); return * this; } NdbOut& diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt index 7ff03684cff..5193d3eae9d 100644 --- a/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/ndb/src/kernel/blocks/ERROR_codes.txt @@ -1,7 +1,7 @@ Next QMGR 1 Next NDBCNTR 1000 Next NDBFS 2000 -Next DBACC 3001 +Next DBACC 3002 Next DBTUP 4013 Next DBLQH 5042 Next DBDICT 6006 @@ -393,6 +393,7 @@ Failed Create Table: -------------------- 7173: Create table failed due to not sufficient number of fragment or replica records. +3001: Fail create 1st fragment 4007 12001: Fail create 1st fragment 4008 12002: Fail create 2nd fragment 4009 12003: Fail create 1st attribute in 1st fragment diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp index e7ec6c71196..07aeb771c97 100644 --- a/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/ndb/src/kernel/blocks/backup/Backup.cpp @@ -863,6 +863,13 @@ Backup::execBACKUP_REQ(Signal* signal) sendBackupRef(senderRef, signal, senderData, BackupRef::IAmNotMaster); return; }//if + + if (m_diskless) + { + sendBackupRef(senderRef, signal, senderData, + BackupRef::CannotBackupDiskless); + return; + } if(dataLen32 != 0) { jam(); diff --git a/ndb/src/kernel/blocks/backup/Backup.hpp b/ndb/src/kernel/blocks/backup/Backup.hpp index 9cc6255af11..1a5d6c7a925 100644 --- a/ndb/src/kernel/blocks/backup/Backup.hpp +++ b/ndb/src/kernel/blocks/backup/Backup.hpp @@ -516,6 +516,7 @@ public: NdbNodeBitmask c_aliveNodes; DLList<BackupRecord> c_backups; Config c_defaults; + Uint32 m_diskless; STATIC_CONST(NO_OF_PAGES_META_FILE = 2); diff --git a/ndb/src/kernel/blocks/backup/BackupInit.cpp b/ndb/src/kernel/blocks/backup/BackupInit.cpp index a02e068687b..e0171c61eca 100644 --- a/ndb/src/kernel/blocks/backup/BackupInit.cpp +++ b/ndb/src/kernel/blocks/backup/BackupInit.cpp @@ -42,8 +42,10 @@ Backup::Backup(const Configuration & conf) : ndbrequire(p != 0); Uint32 noBackups = 0, noTables = 0, noAttribs = 0; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &m_diskless)); ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_BACKUPS, &noBackups); - ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TABLES, &noTables)); + // ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TABLES, &noTables)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &noTables)); ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_ATTRIBUTES, &noAttribs)); noAttribs++; //RT 527 bug fix @@ -203,7 +205,7 @@ Backup::~Backup() { } -BLOCK_FUNCTIONS(Backup); +BLOCK_FUNCTIONS(Backup) template class ArrayPool<Backup::Page32>; template class ArrayPool<Backup::Attribute>; diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index c4127ba9283..c1dca184466 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -195,21 +195,11 @@ void Cmvmi::execEVENT_REP(Signal* signal) /** * If entry is not found */ - Uint32 threshold = 16; - LogLevel::EventCategory eventCategory = (LogLevel::EventCategory)0; - - for(unsigned int i = 0; i< EventLoggerBase::matrixSize; i++){ - if(EventLoggerBase::matrix[i].eventType == eventType){ - eventCategory = EventLoggerBase::matrix[i].eventCategory; - threshold = EventLoggerBase::matrix[i].threshold; - break; - } - } - - if(threshold > 15){ - // No entry found in matrix (or event that should never be printed) + Uint32 threshold; + LogLevel::EventCategory eventCategory; + Logger::LoggerLevel severity; + if (EventLoggerBase::event_lookup(eventType,eventCategory,threshold,severity)) return; - } SubscriberPtr ptr; for(subscribers.first(ptr); ptr.i != RNIL; subscribers.next(ptr)){ @@ -227,14 +217,15 @@ void Cmvmi::execEVENT_REP(Signal* signal) // Print the event info g_eventLogger.log(eventReport->getEventType(), signal->theData); + return; }//execEVENT_REP() void Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){ EventSubscribeReq * subReq = (EventSubscribeReq *)&signal->theData[0]; SubscriberPtr ptr; - jamEntry(); + DBUG_ENTER("Cmvmi::execEVENT_SUBSCRIBE_REQ"); /** * Search for subcription @@ -271,11 +262,13 @@ Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){ category = (LogLevel::EventCategory)(subReq->theData[i] >> 16); level = subReq->theData[i] & 0xFFFF; ptr.p->logLevel.setLogLevel(category, level); + DBUG_PRINT("info",("entry %d: level=%d, category= %d", i, level, category)); } } signal->theData[0] = ptr.i; sendSignal(ptr.p->blockRef, GSN_EVENT_SUBSCRIBE_CONF, signal, 1, JBB); + DBUG_VOID_RETURN; } void @@ -1119,7 +1112,7 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) }//Cmvmi::execDUMP_STATE_ORD() -BLOCK_FUNCTIONS(Cmvmi); +BLOCK_FUNCTIONS(Cmvmi) static Uint32 g_print; static LinearSectionPtr g_test[3]; diff --git a/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp b/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp index 2705f95f6dd..95b336a0a65 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp @@ -264,4 +264,4 @@ Dbacc::~Dbacc() }//Dbacc::~Dbacc() -BLOCK_FUNCTIONS(Dbacc); +BLOCK_FUNCTIONS(Dbacc) diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp index c275e5382f7..5c7cc597672 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp @@ -1062,7 +1062,21 @@ void Dbacc::execACCFRAGREQ(Signal* signal) { const AccFragReq * const req = (AccFragReq*)&signal->theData[0]; jamEntry(); + if (ERROR_INSERTED(3001)) { + jam(); + addFragRefuse(signal, 1); + CLEAR_ERROR_INSERT_VALUE; + return; + } tabptr.i = req->tableId; +#ifndef VM_TRACE + // config mismatch - do not crash if release compiled + if (tabptr.i >= ctablesize) { + jam(); + addFragRefuse(signal, 800); + return; + } +#endif ptrCheckGuard(tabptr, ctablesize, tabrec); ndbrequire((req->reqInfo & 0xF) == ZADDFRAG); ndbrequire(!getrootfragmentrec(signal, rootfragrecptr, req->fragId)); diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 8dca303f7f8..432b2617f65 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -1192,7 +1192,7 @@ Dbdict::~Dbdict() { }//Dbdict::~Dbdict() -BLOCK_FUNCTIONS(Dbdict); +BLOCK_FUNCTIONS(Dbdict) void Dbdict::initCommonData() { diff --git a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp index 7ca45ef4b43..b823dbcd952 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp @@ -314,7 +314,7 @@ Dbdih::~Dbdih() }//Dbdih::~Dbdih() -BLOCK_FUNCTIONS(Dbdih); +BLOCK_FUNCTIONS(Dbdih) diff --git a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp index d0fef8753cb..0577aa4d344 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp @@ -454,5 +454,5 @@ Dblqh::~Dblqh() ctcNodeFailrecFileSize); }//Dblqh::~Dblqh() -BLOCK_FUNCTIONS(Dblqh); +BLOCK_FUNCTIONS(Dblqh) diff --git a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp index e38089242c3..5c66ba776b0 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp @@ -365,5 +365,5 @@ Dbtc::~Dbtc() capiConnectFilesize); }//Dbtc::~Dbtc() -BLOCK_FUNCTIONS(Dbtc); +BLOCK_FUNCTIONS(Dbtc) diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index 49de0d80bcd..8e3ca6528c2 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -1113,6 +1113,7 @@ Dbtup::updateStartLab(Signal* signal, regOperPtr->attrinbufLen); if (retValue == -1) { tupkeyErrorLab(signal); + return -1; }//if } else { jam(); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index d33adcd08e1..8e1cba24359 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -215,7 +215,7 @@ Dbtup::~Dbtup() }//Dbtup::~Dbtup() -BLOCK_FUNCTIONS(Dbtup); +BLOCK_FUNCTIONS(Dbtup) /* **************************************************************** */ /* ---------------------------------------------------------------- */ diff --git a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp index 914dba00674..405f790954e 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp @@ -69,6 +69,17 @@ void Dbtup::execTUPFRAGREQ(Signal* signal) Uint32 noOfAttributeGroups = signal->theData[12]; Uint32 globalCheckpointIdIndicator = signal->theData[13]; +#ifndef VM_TRACE + // config mismatch - do not crash if release compiled + if (regTabPtr.i >= cnoOfTablerec) { + ljam(); + signal->theData[0] = userptr; + signal->theData[1] = 800; + sendSignal(userblockref, GSN_TUPFRAGREF, signal, 2, JBB); + return; + } +#endif + ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec); if (cfirstfreeFragopr == RNIL) { ljam(); diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp index 8f49b7fa6d6..8af83e3c056 100644 --- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp +++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp @@ -1066,7 +1066,7 @@ Dbtux::Index::Index() : m_fragId[i] = ZNIL; m_fragPtrI[i] = RNIL; }; -}; +} // Dbtux::Frag @@ -1103,7 +1103,7 @@ Dbtux::FragOp::FragOp() : m_fragNo(ZNIL), m_numAttrsRecvd(ZNIL) { -}; +} // Dbtux::NodeHandle diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp index 18aa914de05..8990d6c86b6 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp @@ -293,4 +293,4 @@ Dbtux::copyAttrs(const Frag& frag, ConstData data1, Data data2, unsigned maxlen2 #endif } -BLOCK_FUNCTIONS(Dbtux); +BLOCK_FUNCTIONS(Dbtux) diff --git a/ndb/src/kernel/blocks/dbutil/DbUtil.cpp b/ndb/src/kernel/blocks/dbutil/DbUtil.cpp index f7e8981e122..b94bb8e6d7e 100644 --- a/ndb/src/kernel/blocks/dbutil/DbUtil.cpp +++ b/ndb/src/kernel/blocks/dbutil/DbUtil.cpp @@ -158,7 +158,7 @@ DbUtil::~DbUtil() { } -BLOCK_FUNCTIONS(DbUtil); +BLOCK_FUNCTIONS(DbUtil) void DbUtil::releasePrepare(PreparePtr prepPtr) { diff --git a/ndb/src/kernel/blocks/grep/GrepInit.cpp b/ndb/src/kernel/blocks/grep/GrepInit.cpp index cfb454a1f9b..36855f86568 100644 --- a/ndb/src/kernel/blocks/grep/GrepInit.cpp +++ b/ndb/src/kernel/blocks/grep/GrepInit.cpp @@ -132,7 +132,7 @@ Grep::~Grep() { } -BLOCK_FUNCTIONS(Grep); +BLOCK_FUNCTIONS(Grep) Grep::PSPart::PSPart(Grep * sb) : BlockComponent(sb), diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp index 43044eeebcd..c7b472fc91a 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp @@ -114,4 +114,4 @@ Ndbcntr::~Ndbcntr() }//Ndbcntr::~Ndbcntr() -BLOCK_FUNCTIONS(Ndbcntr); +BLOCK_FUNCTIONS(Ndbcntr) diff --git a/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp b/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp index 21b0a2cb54f..9c943760e31 100644 --- a/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp +++ b/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp @@ -1010,7 +1010,7 @@ Ndbfs::execDUMP_STATE_ORD(Signal* signal) -BLOCK_FUNCTIONS(Ndbfs); +BLOCK_FUNCTIONS(Ndbfs) template class Vector<AsyncFile*>; template class Vector<OpenFiles::OpenFileItem>; diff --git a/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp b/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp index d3407e8d4e7..d093089acfc 100644 --- a/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp +++ b/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp @@ -196,5 +196,5 @@ VoidFs::execDUMP_STATE_ORD(Signal* signal) -BLOCK_FUNCTIONS(VoidFs); +BLOCK_FUNCTIONS(VoidFs) diff --git a/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp b/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp index b0f1088779c..d6960ce154e 100644 --- a/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp +++ b/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp @@ -100,4 +100,4 @@ Qmgr::~Qmgr() }//Qmgr::~Qmgr() -BLOCK_FUNCTIONS(Qmgr); +BLOCK_FUNCTIONS(Qmgr) diff --git a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp index a433d72744e..da8596076ec 100644 --- a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp +++ b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp @@ -2947,6 +2947,12 @@ void Qmgr::sendPrepFailReq(Signal* signal, Uint16 aNode) */ /** + * Should < 1/2 nodes die unconditionally. Affects only >= 3-way + * replication. + */ +static const bool g_ndb_arbit_one_half_rule = false; + +/** * Config signals are logically part of CM_INIT. */ void @@ -3157,7 +3163,8 @@ Qmgr::handleArbitCheck(Signal* signal) ndbrequire(cpresident == getOwnNodeId()); NodeBitmask ndbMask; computeArbitNdbMask(ndbMask); - if (2 * ndbMask.count() < cnoOfNodes) { + if (g_ndb_arbit_one_half_rule && + 2 * ndbMask.count() < cnoOfNodes) { jam(); arbitRec.code = ArbitCode::LoseNodes; } else { @@ -3181,6 +3188,11 @@ Qmgr::handleArbitCheck(Signal* signal) case CheckNodeGroups::Partitioning: jam(); arbitRec.code = ArbitCode::Partitioning; + if (g_ndb_arbit_one_half_rule && + 2 * ndbMask.count() > cnoOfNodes) { + jam(); + arbitRec.code = ArbitCode::WinNodes; + } break; default: ndbrequire(false); @@ -3190,8 +3202,12 @@ Qmgr::handleArbitCheck(Signal* signal) switch (arbitRec.code) { case ArbitCode::LoseNodes: jam(); + case ArbitCode::LoseGroups: + jam(); goto crashme; - case ArbitCode::WinGroups: + case ArbitCode::WinNodes: + jam(); + case ArbitCode::WinGroups: jam(); if (arbitRec.state == ARBIT_RUN) { jam(); @@ -3200,9 +3216,6 @@ Qmgr::handleArbitCheck(Signal* signal) arbitRec.state = ARBIT_INIT; arbitRec.newstate = true; break; - case ArbitCode::LoseGroups: - jam(); - goto crashme; case ArbitCode::Partitioning: if (arbitRec.state == ARBIT_RUN) { jam(); @@ -3762,8 +3775,7 @@ Qmgr::execARBIT_CHOOSEREF(Signal* signal) } /** - * Handle CRASH state. We must crash immediately. But it - * would be nice to wait until event reports have been sent. + * Handle CRASH state. We must crash immediately. * XXX tell other nodes in our party to crash too. */ void @@ -3773,12 +3785,11 @@ Qmgr::stateArbitCrash(Signal* signal) if (arbitRec.newstate) { jam(); CRASH_INSERTION((Uint32)910 + arbitRec.state); - arbitRec.setTimestamp(); arbitRec.code = 0; arbitRec.newstate = false; } -#if 0 +#ifdef ndb_arbit_crash_wait_for_event_report_to_get_out if (! (arbitRec.getTimediff() > getArbitTimeout())) return; #endif diff --git a/ndb/src/kernel/blocks/suma/Suma.cpp b/ndb/src/kernel/blocks/suma/Suma.cpp index f6d9a0ac35a..836fa28d9ad 100644 --- a/ndb/src/kernel/blocks/suma/Suma.cpp +++ b/ndb/src/kernel/blocks/suma/Suma.cpp @@ -3553,7 +3553,7 @@ Suma::Restart::Restart(Suma& s) : suma(s) { c_okToStart[i] = false; c_waitingToStart[i] = false; } -}; +} void Suma::Restart::resetNode(Uint32 sumaRef) diff --git a/ndb/src/kernel/blocks/suma/SumaInit.cpp b/ndb/src/kernel/blocks/suma/SumaInit.cpp index 255abd47c94..36217c313af 100644 --- a/ndb/src/kernel/blocks/suma/SumaInit.cpp +++ b/ndb/src/kernel/blocks/suma/SumaInit.cpp @@ -188,6 +188,6 @@ Suma::~Suma() { } -BLOCK_FUNCTIONS(Suma); -BLOCK_FUNCTIONS(SumaParticipant); +BLOCK_FUNCTIONS(Suma) +BLOCK_FUNCTIONS(SumaParticipant) diff --git a/ndb/src/kernel/blocks/trix/Trix.cpp b/ndb/src/kernel/blocks/trix/Trix.cpp index 80cf9f88c0d..75bc19b6a20 100644 --- a/ndb/src/kernel/blocks/trix/Trix.cpp +++ b/ndb/src/kernel/blocks/trix/Trix.cpp @@ -962,6 +962,6 @@ void Trix::checkParallelism(Signal* signal, SubscriptionRecord* subRec) } } -BLOCK_FUNCTIONS(Trix); +BLOCK_FUNCTIONS(Trix) template void append(DataBuffer<15>&,SegmentedSectionPtr,SectionSegmentPool&); diff --git a/ndb/src/kernel/main.cpp b/ndb/src/kernel/main.cpp index 2901320633c..44fe1725c9e 100644 --- a/ndb/src/kernel/main.cpp +++ b/ndb/src/kernel/main.cpp @@ -19,7 +19,6 @@ #include <ndb_version.h> #include "Configuration.hpp" -#include <LocalConfig.hpp> #include <TransporterRegistry.hpp> #include "vm/SimBlockList.hpp" @@ -69,18 +68,11 @@ int main(int argc, char** argv) return NRT_Default; } - LocalConfig local_config; - if (!local_config.init(theConfig->getConnectString(),0)){ - local_config.printError(); - local_config.printUsage(); - return NRT_Default; - } - { // Do configuration #ifndef NDB_WIN32 signal(SIGPIPE, SIG_IGN); #endif - theConfig->fetch_configuration(local_config); + theConfig->fetch_configuration(); } my_setwd(NdbConfig_get_path(0), MYF(0)); @@ -144,7 +136,7 @@ int main(int argc, char** argv) exit(0); } g_eventLogger.info("Ndb has terminated (pid %d) restarting", child); - theConfig->fetch_configuration(local_config); + theConfig->fetch_configuration(); } g_eventLogger.info("Angel pid: %d ndb pid: %d", getppid(), getpid()); diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index aecb5581d06..3de84bb0566 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -17,7 +17,6 @@ #include <ndb_global.h> #include <ndb_opts.h> -#include <LocalConfig.hpp> #include "Configuration.hpp" #include <ErrorHandlingMacros.hpp> #include "GlobalData.hpp" @@ -35,6 +34,7 @@ #include <kernel_types.h> #include <ndb_limits.h> +#include <ndbapi_limits.h> #include "pc.hpp" #include <LogLevel.hpp> #include <NdbSleep.h> @@ -108,7 +108,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), bool Configuration::init(int argc, char** argv) { - const char *load_default_groups[]= { "ndbd",0 }; + const char *load_default_groups[]= { "mysql_cluster","ndbd",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; @@ -189,7 +189,7 @@ Configuration::closeConfiguration(){ } void -Configuration::fetch_configuration(LocalConfig &local_config){ +Configuration::fetch_configuration(){ /** * Fetch configuration from management server */ @@ -199,8 +199,17 @@ Configuration::fetch_configuration(LocalConfig &local_config){ m_mgmd_port= 0; m_mgmd_host= 0; - m_config_retriever= new ConfigRetriever(local_config, NDB_VERSION, NODE_TYPE_DB); - if(m_config_retriever->do_connect() == -1){ + m_config_retriever= new ConfigRetriever(getConnectString(), + NDB_VERSION, NODE_TYPE_DB); + + if (m_config_retriever->hasError()) + { + ERROR_SET(fatal, ERR_INVALID_CONFIG, + "Could not connect initialize handle to management server", + m_config_retriever->getErrorString()); + } + + if(m_config_retriever->do_connect(12,5,1) == -1){ const char * s = m_config_retriever->getErrorString(); if(s == 0) s = "No error given!"; @@ -215,13 +224,7 @@ Configuration::fetch_configuration(LocalConfig &local_config){ ConfigRetriever &cr= *m_config_retriever; - if((globalData.ownId = cr.allocNodeId()) == 0){ - for(Uint32 i = 0; i<3; i++){ - NdbSleep_SecSleep(3); - if((globalData.ownId = cr.allocNodeId()) != 0) - break; - } - } + globalData.ownId = cr.allocNodeId(2 /*retry*/,3 /*delay*/); if(globalData.ownId == 0){ ERROR_SET(fatal, ERR_INVALID_CONFIG, @@ -452,6 +455,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ unsigned int noOfTables = 0; unsigned int noOfUniqueHashIndexes = 0; unsigned int noOfOrderedIndexes = 0; + unsigned int noOfTriggers = 0; unsigned int noOfReplicas = 0; unsigned int noOfDBNodes = 0; unsigned int noOfAPINodes = 0; @@ -476,6 +480,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ { CFG_DB_NO_TABLES, &noOfTables, false }, { CFG_DB_NO_ORDERED_INDEXES, &noOfOrderedIndexes, false }, { CFG_DB_NO_UNIQUE_HASH_INDEXES, &noOfUniqueHashIndexes, false }, + { CFG_DB_NO_TRIGGERS, &noOfTriggers, true }, { CFG_DB_NO_REPLICAS, &noOfReplicas, false }, { CFG_DB_NO_ATTRIBUTES, &noOfAttributes, false }, { CFG_DB_NO_OPS, &noOfOperations, false }, @@ -584,12 +589,42 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ ConfigValues::Iterator it2(*ownConfig, db.m_config); it2.set(CFG_DB_NO_TABLES, noOfTables); it2.set(CFG_DB_NO_ATTRIBUTES, noOfAttributes); + { + Uint32 neededNoOfTriggers = /* types: Insert/Update/Delete/Custom */ + 3 * noOfUniqueHashIndexes + /* for unique hash indexes, I/U/D */ + 3 * NDB_MAX_ACTIVE_EVENTS + /* for events in suma, I/U/D */ + 3 * noOfTables + /* for backup, I/U/D */ + noOfOrderedIndexes; /* for ordered indexes, C */ + if (noOfTriggers < neededNoOfTriggers) + { + noOfTriggers= neededNoOfTriggers; + it2.set(CFG_DB_NO_TRIGGERS, noOfTriggers); + } + } /** * Do size calculations */ ConfigValuesFactory cfg(ownConfig); + Uint32 noOfMetaTables= noOfTables + noOfOrderedIndexes + + noOfUniqueHashIndexes; + Uint32 noOfMetaTablesDict= noOfMetaTables; + if (noOfMetaTablesDict > MAX_TABLES) + noOfMetaTablesDict= MAX_TABLES; + + { + /** + * Dict Size Alt values + */ + cfg.put(CFG_DICT_ATTRIBUTE, + noOfAttributes); + + cfg.put(CFG_DICT_TABLE, + noOfMetaTablesDict); + } + + if (noOfLocalScanRecords == 0) { noOfLocalScanRecords = (noOfDBNodes * noOfScanRecords) + 1; } @@ -599,7 +634,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ Uint32 noOfTCScanRecords = noOfScanRecords; { - Uint32 noOfAccTables= noOfTables + noOfUniqueHashIndexes; + Uint32 noOfAccTables= noOfMetaTables/*noOfTables+noOfUniqueHashIndexes*/; /** * Acc Size Alt values */ @@ -641,19 +676,6 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ cfg.put(CFG_ACC_SCAN, noOfLocalScanRecords); } - Uint32 noOfMetaTables= noOfTables + noOfOrderedIndexes + - noOfUniqueHashIndexes; - { - /** - * Dict Size Alt values - */ - cfg.put(CFG_DICT_ATTRIBUTE, - noOfAttributes); - - cfg.put(CFG_DICT_TABLE, - noOfMetaTables); - } - { /** * Dih Size Alt values @@ -746,8 +768,8 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ noOfMetaTables); cfg.put(CFG_TUP_TABLE_DESC, - 4 * NO_OF_FRAG_PER_NODE * noOfAttributes* noOfReplicas + - 12 * NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas ); + 2 * 6 * NO_OF_FRAG_PER_NODE * noOfAttributes * noOfReplicas + + 2 * 10 * NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas ); cfg.put(CFG_TUP_STORED_PROC, noOfLocalScanRecords); @@ -758,9 +780,9 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ * Tux Size Alt values */ cfg.put(CFG_TUX_INDEX, - noOfOrderedIndexes); + noOfMetaTables /*noOfOrderedIndexes*/); - cfg.put(CFG_TUX_FRAGMENT, + cfg.put(CFG_TUX_FRAGMENT, 2 * NO_OF_FRAG_PER_NODE * noOfOrderedIndexes * noOfReplicas); cfg.put(CFG_TUX_ATTRIBUTE, diff --git a/ndb/src/kernel/vm/Configuration.hpp b/ndb/src/kernel/vm/Configuration.hpp index 34e70ca3121..acf0e163a84 100644 --- a/ndb/src/kernel/vm/Configuration.hpp +++ b/ndb/src/kernel/vm/Configuration.hpp @@ -21,7 +21,6 @@ #include <ndb_types.h> class ConfigRetriever; -struct LocalConfig; class Configuration { public: @@ -33,7 +32,7 @@ public: */ bool init(int argc, char** argv); - void fetch_configuration(LocalConfig &local_config); + void fetch_configuration(); void setupConfiguration(); void closeConfiguration(); diff --git a/ndb/src/mgmapi/LocalConfig.cpp b/ndb/src/mgmapi/LocalConfig.cpp index d0ff97cdedf..1dc805557ee 100644 --- a/ndb/src/mgmapi/LocalConfig.cpp +++ b/ndb/src/mgmapi/LocalConfig.cpp @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <LocalConfig.hpp> +#include "LocalConfig.hpp" #include <NdbEnv.h> #include <NdbConfig.h> #include <NdbAutoPtr.hpp> @@ -294,4 +294,27 @@ LocalConfig::readConnectString(const char * connectString, return return_value; } +char * +LocalConfig::makeConnectString(char *buf, int sz) +{ + int p= BaseString::snprintf(buf,sz,"nodeid=%d", _ownNodeId); + if (p < sz) + for (unsigned i = 0; i < ids.size(); i++) + { + if (ids[i].type != MgmId_TCP) + continue; + int new_p= p+BaseString::snprintf(buf+p,sz-p,",%s:%d", + ids[i].name.c_str(), ids[i].port); + if (new_p < sz) + p= new_p; + else + { + buf[p]= 0; + break; + } + } + buf[sz-1]=0; + return buf; +} + template class Vector<MgmtSrvrId>; diff --git a/ndb/include/mgmapi/LocalConfig.hpp b/ndb/src/mgmapi/LocalConfig.hpp index 9ceeffdba36..c415ec1be91 100644 --- a/ndb/include/mgmapi/LocalConfig.hpp +++ b/ndb/src/mgmapi/LocalConfig.hpp @@ -61,6 +61,7 @@ struct LocalConfig { bool parseHostName(const char *buf); bool parseFileName(const char *buf); bool parseString(const char *buf, BaseString &err); + char * makeConnectString(char *buf, int sz); }; #endif // LocalConfig_H diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 2a005a5dc1b..5a95c6e9ac1 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -20,6 +20,7 @@ #include <LocalConfig.hpp> #include <NdbAutoPtr.hpp> +#include <NdbSleep.h> #include <NdbTCP.h> #include "mgmapi.h" #include "mgmapi_debug.h" @@ -83,8 +84,7 @@ typedef Parser<ParserDummy> Parser_t; #define NDB_MGM_MAX_ERR_DESC_SIZE 256 struct ndb_mgm_handle { - char * hostname; - unsigned short port; + int cfg_i; int connected; int last_error; @@ -95,7 +95,7 @@ struct ndb_mgm_handle { NDB_SOCKET_TYPE socket; - char cfg_ptr[sizeof(LocalConfig)]; + LocalConfig cfg; #ifdef MGMAPI_LOG FILE* logfile; @@ -148,14 +148,16 @@ ndb_mgm_create_handle() h->connected = 0; h->last_error = 0; h->last_error_line = 0; - h->hostname = 0; h->socket = NDB_INVALID_SOCKET; h->read_timeout = 50000; h->write_timeout = 100; - - new (h->cfg_ptr) LocalConfig; + h->cfg_i = 0; strncpy(h->last_error_desc, "No error", NDB_MGM_MAX_ERR_DESC_SIZE); + + new (&(h->cfg)) LocalConfig; + h->cfg.init(0, 0); + #ifdef MGMAPI_LOG h->logfile = 0; #endif @@ -163,6 +165,23 @@ ndb_mgm_create_handle() return h; } +extern "C" +int +ndb_mgm_set_connectstring(NdbMgmHandle handle, const char * mgmsrv) +{ + new (&(handle->cfg)) LocalConfig; + if (!handle->cfg.init(mgmsrv, 0) || + handle->cfg.ids.size() == 0) + { + new (&(handle->cfg)) LocalConfig; + handle->cfg.init(0, 0); /* reset the LocalCongig */ + SET_ERROR(handle, NDB_MGM_ILLEGAL_CONNECT_STRING, ""); + return -1; + } + handle->cfg_i= 0; + return 0; +} + /** * Destroy a handle */ @@ -175,14 +194,13 @@ ndb_mgm_destroy_handle(NdbMgmHandle * handle) if((* handle)->connected){ ndb_mgm_disconnect(* handle); } - my_free((* handle)->hostname,MYF(MY_ALLOW_ZERO_PTR)); #ifdef MGMAPI_LOG if ((* handle)->logfile != 0){ fclose((* handle)->logfile); (* handle)->logfile = 0; } #endif - ((LocalConfig*)((*handle)->cfg_ptr))->~LocalConfig(); + (*handle)->cfg.~LocalConfig(); my_free((char*)* handle,MYF(MY_ALLOW_ZERO_PTR)); * handle = 0; } @@ -314,7 +332,8 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply, */ extern "C" int -ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv) +ndb_mgm_connect(NdbMgmHandle handle, int no_retries, + int retry_delay_in_seconds, int verbose) { SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_connect"); CHECK_HANDLE(handle, -1); @@ -331,36 +350,60 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv) /** * Do connect */ - LocalConfig *cfg= (LocalConfig*)(handle->cfg_ptr); - new (cfg) LocalConfig; - if (!cfg->init(mgmsrv, 0) || - cfg->ids.size() == 0) - { - SET_ERROR(handle, NDB_MGM_ILLEGAL_CONNECT_STRING, ""); - return -1; - } - + LocalConfig &cfg= handle->cfg; NDB_SOCKET_TYPE sockfd= NDB_INVALID_SOCKET; Uint32 i; - for (i = 0; i < cfg->ids.size(); i++) + while (sockfd == NDB_INVALID_SOCKET) { - if (cfg->ids[i].type != MgmId_TCP) - continue; - SocketClient s(cfg->ids[i].name.c_str(), cfg->ids[i].port); - sockfd = s.connect(); + // do all the mgmt servers + for (i = 0; i < cfg.ids.size(); i++) + { + if (cfg.ids[i].type != MgmId_TCP) + continue; + SocketClient s(cfg.ids[i].name.c_str(), cfg.ids[i].port); + sockfd = s.connect(); + if (sockfd != NDB_INVALID_SOCKET) + break; + } if (sockfd != NDB_INVALID_SOCKET) break; - } - if (sockfd == NDB_INVALID_SOCKET) - { - setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, - "Unable to connect using connectstring %s", mgmsrv); - return -1; + if (verbose > 0) { + char buf[1024]; + ndbout_c("Unable to connect with connect string: %s", + cfg.makeConnectString(buf,sizeof(buf))); + verbose= -1; + } + if (no_retries == 0) { + char buf[1024]; + setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, + "Unable to connect with connect string: %s", + cfg.makeConnectString(buf,sizeof(buf))); + if (verbose == -2) + ndbout << ", failed." << endl; + return -1; + } + if (verbose == -1) { + ndbout << "Retrying every " << retry_delay_in_seconds << " seconds"; + if (no_retries > 0) + ndbout << ". Attempts left:"; + else + ndbout << ", until connected.";; + ndbout << flush; + verbose= -2; + } + if (no_retries > 0) { + if (verbose == -2) { + ndbout << " " << no_retries; + ndbout << flush; + } + no_retries--; + } + NdbSleep_SecSleep(retry_delay_in_seconds); } + if (verbose == -2) + ndbout << endl; - my_free(handle->hostname,MYF(MY_ALLOW_ZERO_PTR)); - handle->hostname = my_strdup(cfg->ids[i].name.c_str(),MYF(MY_WME)); - handle->port = cfg->ids[i].port; + handle->cfg_i = i; handle->socket = sockfd; handle->connected = 1; @@ -531,7 +574,9 @@ cmp_state(const void *_a, const void *_b) a = (struct ndb_mgm_node_state *)_a; b = (struct ndb_mgm_node_state *)_b; - return a->node_id > b->node_id; + if (a->node_id > b->node_id) + return 1; + return -1; } extern "C" @@ -869,21 +914,67 @@ ndb_mgm_restart(NdbMgmHandle handle, int no_of_nodes, const int *node_list) return ndb_mgm_restart2(handle, no_of_nodes, node_list, 0, 0, 0); } +static const char *clusterlog_level_names[]= + { "enabled", "debug", "info", "warning", "error", "critical", "alert" }; + +struct ndb_mgm_clusterlog_levels +{ + const char* name; + enum ndb_mgm_clusterlog_level level; +} clusterlog_levels[] = { + { clusterlog_level_names[0], NDB_MGM_CLUSTERLOG_ON }, + { clusterlog_level_names[1], NDB_MGM_CLUSTERLOG_DEBUG }, + { clusterlog_level_names[2], NDB_MGM_CLUSTERLOG_INFO }, + { clusterlog_level_names[3], NDB_MGM_CLUSTERLOG_WARNING }, + { clusterlog_level_names[4], NDB_MGM_CLUSTERLOG_ERROR }, + { clusterlog_level_names[5], NDB_MGM_CLUSTERLOG_CRITICAL }, + { clusterlog_level_names[6], NDB_MGM_CLUSTERLOG_ALERT }, + { "all", NDB_MGM_CLUSTERLOG_ALL }, + { 0, NDB_MGM_ILLEGAL_CLUSTERLOG_LEVEL }, +}; + +extern "C" +ndb_mgm_clusterlog_level +ndb_mgm_match_clusterlog_level(const char * name) +{ + if(name == 0) + return NDB_MGM_ILLEGAL_CLUSTERLOG_LEVEL; + + for(int i = 0; clusterlog_levels[i].name !=0 ; i++) + if(strcasecmp(name, clusterlog_levels[i].name) == 0) + return clusterlog_levels[i].level; + + return NDB_MGM_ILLEGAL_CLUSTERLOG_LEVEL; +} + +extern "C" +const char * +ndb_mgm_get_clusterlog_level_string(enum ndb_mgm_clusterlog_level level) +{ + int i= (int)level; + if (i >= 0 && i < (int)NDB_MGM_CLUSTERLOG_ALL) + return clusterlog_level_names[i]; + for(i = (int)NDB_MGM_CLUSTERLOG_ALL; clusterlog_levels[i].name != 0; i++) + if(clusterlog_levels[i].level == level) + return clusterlog_levels[i].name; + return 0; +} + extern "C" unsigned int * ndb_mgm_get_logfilter(NdbMgmHandle handle) { SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_logfilter"); - static Uint32 enabled[7] = {0,0,0,0,0,0,0}; + static Uint32 enabled[(int)NDB_MGM_CLUSTERLOG_ALL] = {0,0,0,0,0,0,0}; const ParserRow<ParserDummy> getinfo_reply[] = { MGM_CMD("clusterlog", NULL, ""), - MGM_ARG("enabled", Int, Mandatory, ""), - MGM_ARG("debug", Int, Mandatory, ""), - MGM_ARG("info", Int, Mandatory, ""), - MGM_ARG("warning", Int, Mandatory, ""), - MGM_ARG("error", Int, Mandatory, ""), - MGM_ARG("critical", Int, Mandatory, ""), - MGM_ARG("alert", Int, Mandatory, ""), + MGM_ARG(clusterlog_level_names[0], Int, Mandatory, ""), + MGM_ARG(clusterlog_level_names[1], Int, Mandatory, ""), + MGM_ARG(clusterlog_level_names[2], Int, Mandatory, ""), + MGM_ARG(clusterlog_level_names[3], Int, Mandatory, ""), + MGM_ARG(clusterlog_level_names[4], Int, Mandatory, ""), + MGM_ARG(clusterlog_level_names[5], Int, Mandatory, ""), + MGM_ARG(clusterlog_level_names[6], Int, Mandatory, ""), }; CHECK_HANDLE(handle, NULL); CHECK_CONNECTED(handle, NULL); @@ -893,10 +984,8 @@ ndb_mgm_get_logfilter(NdbMgmHandle handle) reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args); CHECK_REPLY(reply, NULL); - const char *names[] = { "enabled", "debug", "info", "warning", "error", - "critical", "alert" }; - for(int i=0; i < 7; i++) { - reply->get(names[i], &enabled[i]); + for(int i=0; i < (int)NDB_MGM_CLUSTERLOG_ALL; i++) { + reply->get(clusterlog_level_names[i], &enabled[i]); } return enabled; } @@ -905,6 +994,7 @@ extern "C" int ndb_mgm_filter_clusterlog(NdbMgmHandle handle, enum ndb_mgm_clusterlog_level level, + int enable, struct ndb_mgm_reply* /*reply*/) { SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_filter_clusterlog"); @@ -919,6 +1009,7 @@ ndb_mgm_filter_clusterlog(NdbMgmHandle handle, Properties args; args.put("level", level); + args.put("enable", enable); const Properties *reply; reply = ndb_mgm_call(handle, filter_reply, "set logfilter", &args); @@ -926,11 +1017,14 @@ ndb_mgm_filter_clusterlog(NdbMgmHandle handle, BaseString result; reply->get("result", result); - if(strcmp(result.c_str(), "1") == 0) { + + if (strcmp(result.c_str(), "1") == 0) + retval = 1; + else if (strcmp(result.c_str(), "0") == 0) retval = 0; - } else { + else + { SET_ERROR(handle, EINVAL, result.c_str()); - retval = -1; } delete reply; return retval; @@ -1008,15 +1102,18 @@ ndb_mgm_set_loglevel_clusterlog(NdbMgmHandle handle, int nodeId, "set cluster loglevel", &args); CHECK_REPLY(reply, -1); + DBUG_ENTER("ndb_mgm_set_loglevel_clusterlog"); + DBUG_PRINT("enter",("node=%d, category=%d, level=%d", nodeId, cat, level)); + BaseString result; reply->get("result", result); if(strcmp(result.c_str(), "Ok") != 0) { SET_ERROR(handle, EINVAL, result.c_str()); delete reply; - return -1; + DBUG_RETURN(-1); } delete reply; - return 0; + DBUG_RETURN(0); } extern "C" @@ -1068,7 +1165,9 @@ ndb_mgm_listen_event(NdbMgmHandle handle, int filter[]) }; CHECK_HANDLE(handle, -1); - SocketClient s(handle->hostname, handle->port); + const char *hostname= ndb_mgm_get_connected_host(handle); + int port= ndb_mgm_get_connected_port(handle); + SocketClient s(hostname, port); const NDB_SOCKET_TYPE sockfd = s.connect(); if (sockfd == NDB_INVALID_SOCKET) { setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, @@ -1446,7 +1545,8 @@ ndb_mgm_start(NdbMgmHandle handle, int no_of_nodes, const int * node_list) *****************************************************************************/ extern "C" int -ndb_mgm_start_backup(NdbMgmHandle handle, unsigned int* _backup_id, +ndb_mgm_start_backup(NdbMgmHandle handle, int wait_completed, + unsigned int* _backup_id, struct ndb_mgm_reply* /*reply*/) { SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_start_backup"); @@ -1460,8 +1560,17 @@ ndb_mgm_start_backup(NdbMgmHandle handle, unsigned int* _backup_id, CHECK_CONNECTED(handle, -1); Properties args; + args.put("completed", wait_completed); const Properties *reply; - reply = ndb_mgm_call(handle, start_backup_reply, "start backup", &args); + { // start backup can take some time, set timeout high + Uint64 old_timeout= handle->read_timeout; + if (wait_completed == 2) + handle->read_timeout= 30*60*1000; // 30 minutes + else if (wait_completed == 1) + handle->read_timeout= 5*60*1000; // 5 minutes + reply = ndb_mgm_call(handle, start_backup_reply, "start backup", &args); + handle->read_timeout= old_timeout; + } CHECK_REPLY(reply, -1); BaseString result; @@ -1613,19 +1722,50 @@ ndb_mgm_destroy_configuration(struct ndb_mgm_configuration *cfg) extern "C" int -ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, unsigned *pnodeid, int nodetype) +ndb_mgm_get_configuration_nodeid(NdbMgmHandle handle) +{ + CHECK_HANDLE(handle, 0); + return handle->cfg._ownNodeId; +} + +extern "C" +int ndb_mgm_get_connected_port(NdbMgmHandle handle) { + return handle->cfg.ids[handle->cfg_i].port; +} + +extern "C" +const char *ndb_mgm_get_connected_host(NdbMgmHandle handle) +{ + return handle->cfg.ids[handle->cfg_i].name.c_str(); +} + +extern "C" +const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz) +{ + return handle->cfg.makeConnectString(buf,buf_sz); +} +extern "C" +int +ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype) +{ CHECK_HANDLE(handle, 0); CHECK_CONNECTED(handle, 0); + union { long l; char c[sizeof(long)]; } endian_check; + + endian_check.l = 1; + + int nodeid= handle->cfg._ownNodeId; Properties args; args.put("version", version); args.put("nodetype", nodetype); - args.put("nodeid", *pnodeid); + args.put("nodeid", nodeid); args.put("user", "mysqld"); args.put("password", "mysqld"); args.put("public key", "a public key"); + args.put("endian", (endian_check.c[sizeof(long)-1])?"big":"little"); const ParserRow<ParserDummy> reply[]= { MGM_CMD("get nodeid reply", NULL, ""), @@ -1638,26 +1778,29 @@ ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, unsigned *pnodei prop= ndb_mgm_call(handle, reply, "get nodeid", &args); CHECK_REPLY(prop, -1); - int res= -1; + nodeid= -1; do { const char * buf; if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ + const char *hostname= ndb_mgm_get_connected_host(handle); + unsigned port= ndb_mgm_get_connected_port(handle); BaseString err; err.assfmt("Could not alloc node id at %s port %d: %s", - handle->hostname, handle->port, buf); + hostname, port, buf); setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, err.c_str()); break; } - if(!prop->get("nodeid", pnodeid) != 0){ + Uint32 _nodeid; + if(!prop->get("nodeid", &_nodeid) != 0){ ndbout_c("ERROR Message: <nodeid Unspecified>\n"); break; } - res= 0; + nodeid= _nodeid; }while(0); delete prop; - return res; + return nodeid; } /***************************************************************************** @@ -1864,4 +2007,38 @@ ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **purged){ return res; } +extern "C" +int +ndb_mgm_check_connection(NdbMgmHandle handle){ + CHECK_HANDLE(handle, 0); + CHECK_CONNECTED(handle, 0); + SocketOutputStream out(handle->socket); + SocketInputStream in(handle->socket, handle->read_timeout); + char buf[32]; + + if (out.println("check connection")) + goto ndb_mgm_check_connection_error; + + if (out.println("")) + goto ndb_mgm_check_connection_error; + + in.gets(buf, sizeof(buf)); + if(strcmp("check connection reply\n", buf)) + goto ndb_mgm_check_connection_error; + + in.gets(buf, sizeof(buf)); + if(strcmp("result: Ok\n", buf)) + goto ndb_mgm_check_connection_error; + + in.gets(buf, sizeof(buf)); + if(strcmp("\n", buf)) + goto ndb_mgm_check_connection_error; + + return 0; + +ndb_mgm_check_connection_error: + ndb_mgm_disconnect(handle); + return -1; +} + template class Vector<const ParserRow<ParserDummy>*>; diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index a36263395ec..0c7fe642e54 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -44,7 +44,7 @@ public: * Constructor * @param mgmtSrvr: Management server to use when executing commands */ - CommandInterpreter(const char *); + CommandInterpreter(const char *, int verbose); ~CommandInterpreter(); /** @@ -54,10 +54,11 @@ public: * * @return true until quit/bye/exit has been typed */ - int execute(const char *_line, int _try_reconnect=-1); + int execute(const char *_line, int _try_reconnect=-1, int *error= 0); private: void printError(); + int execute_impl(const char *_line); /** * Analyse the command line, after the first token. @@ -94,8 +95,9 @@ private: */ void executeHelp(char* parameters); void executeShow(char* parameters); + void executeConnect(char* parameters); void executePurge(char* parameters); - void executeShutdown(char* parameters); + int executeShutdown(char* parameters); void executeRun(char* parameters); void executeInfo(char* parameters); void executeClusterLog(char* parameters); @@ -120,7 +122,7 @@ public: void executeStatus(int processId, const char* parameters, bool all); void executeEventReporting(int processId, const char* parameters, bool all); void executeDumpState(int processId, const char* parameters, bool all); - void executeStartBackup(char * parameters); + int executeStartBackup(char * parameters); void executeAbortBackup(char * parameters); void executeRep(char* parameters); @@ -152,14 +154,17 @@ private: const char * param); NdbMgmHandle m_mgmsrv; - bool connected; - const char *host; + NdbMgmHandle m_mgmsrv2; + bool m_connected; + int m_verbose; int try_reconnect; + int m_error; #ifdef HAVE_GLOBAL_REPLICATION NdbRepHandle m_repserver; const char *rep_host; bool rep_connected; #endif + struct NdbThread* m_event_thread; }; @@ -170,17 +175,17 @@ private: #include "ndb_mgmclient.hpp" #include "ndb_mgmclient.h" -Ndb_mgmclient::Ndb_mgmclient(const char *host) +Ndb_mgmclient::Ndb_mgmclient(const char *host,int verbose) { - m_cmd= new CommandInterpreter(host); + m_cmd= new CommandInterpreter(host,verbose); } Ndb_mgmclient::~Ndb_mgmclient() { delete m_cmd; } -int Ndb_mgmclient::execute(const char *_line, int _try_reconnect) +int Ndb_mgmclient::execute(const char *_line, int _try_reconnect, int *error) { - return m_cmd->execute(_line,_try_reconnect); + return m_cmd->execute(_line,_try_reconnect,error); } int Ndb_mgmclient::disconnect() @@ -226,7 +231,7 @@ extern "C" { #include <util/InputStream.hpp> #include <util/OutputStream.hpp> -int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect) +int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect, int *error) { if (argc <= 0) return 0; @@ -235,7 +240,7 @@ int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect) { _line.appfmt(" %s", argv[i]); } - return m_cmd->execute(_line.c_str(),_try_reconnect); + return m_cmd->execute(_line.c_str(),_try_reconnect, error); } /***************************************************************************** @@ -258,12 +263,13 @@ static const char* helpText = "SHOW CONFIG Print configuration\n" "SHOW PARAMETERS Print configuration parameters\n" #endif -"START BACKUP Start backup\n" +"START BACKUP [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n" +" Start backup (default WAIT COMPLETED)\n" "ABORT BACKUP <backup id> Abort backup\n" -"SHUTDOWN Shutdown all processes in cluster and quit\n" -"CLUSTERLOG ON Enable Cluster logging\n" -"CLUSTERLOG OFF Disable Cluster logging\n" -"CLUSTERLOG FILTER <severity> Toggle severity filter on/off\n" +"SHUTDOWN Shutdown all processes in cluster\n" +"CLUSTERLOG ON [<severity>] ... Enable Cluster logging\n" +"CLUSTERLOG OFF [<severity>] ... Disable Cluster logging\n" +"CLUSTERLOG TOGGLE [<severity>] ... Toggle severity filter on/off\n" "CLUSTERLOG INFO Print cluster log information\n" "<id> START Start DB node (started with -n)\n" "<id> RESTART [-n] [-i] Restart DB node\n" @@ -276,6 +282,7 @@ static const char* helpText = "REP CONNECT <host:port> Connect to REP server on host:port\n" #endif "PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n" +"CONNECT [<connectstring>] Connect to management server (reconnect if already connected)\n" "QUIT Quit management client\n" ; @@ -374,20 +381,28 @@ convert(const char* s, int& val) { /* * Constructor */ -CommandInterpreter::CommandInterpreter(const char *_host) +CommandInterpreter::CommandInterpreter(const char *_host,int verbose) + : m_verbose(verbose) { m_mgmsrv = ndb_mgm_create_handle(); if(m_mgmsrv == NULL) { ndbout_c("Cannot create handle to management server."); + exit(-1); + } + m_mgmsrv2 = ndb_mgm_create_handle(); + if(m_mgmsrv2 == NULL) { + ndbout_c("Cannot create handle to management server."); + exit(-1); + } + if (ndb_mgm_set_connectstring(m_mgmsrv, _host)) + { printError(); + exit(-1); } - connected = false; + m_connected= false; + m_event_thread= 0; try_reconnect = 0; - if (_host) - host= my_strdup(_host,MYF(MY_WME)); - else - host= 0; #ifdef HAVE_GLOBAL_REPLICATION rep_host = NULL; m_repserver = NULL; @@ -400,10 +415,9 @@ CommandInterpreter::CommandInterpreter(const char *_host) */ CommandInterpreter::~CommandInterpreter() { - connected = false; + disconnect(); ndb_mgm_destroy_handle(&m_mgmsrv); - my_free((char *)host,MYF(MY_ALLOW_ZERO_PTR)); - host = NULL; + ndb_mgm_destroy_handle(&m_mgmsrv2); } static bool @@ -425,6 +439,11 @@ emptyString(const char* s) void CommandInterpreter::printError() { + if (ndb_mgm_check_connection(m_mgmsrv)) + { + m_connected= false; + disconnect(); + } ndbout_c("* %5d: %s", ndb_mgm_get_latest_error(m_mgmsrv), ndb_mgm_get_latest_error_msg(m_mgmsrv)); @@ -434,34 +453,109 @@ CommandInterpreter::printError() //***************************************************************************** //***************************************************************************** -bool +static int do_event_thread; +static void* +event_thread_run(void* m) +{ + NdbMgmHandle handle= *(NdbMgmHandle*)m; + + my_thread_init(); + + int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 }; + int fd = ndb_mgm_listen_event(handle, filter); + if (fd > 0) + { + do_event_thread= 1; + char *tmp= 0; + char buf[1024]; + SocketInputStream in(fd,10); + do { + if (tmp == 0) NdbSleep_MilliSleep(10); + if((tmp = in.gets(buf, 1024))) + ndbout << tmp; + } while(do_event_thread); + } + else + { + do_event_thread= -1; + } + + my_thread_end(); + NdbThread_Exit(0); + return 0; +} + +bool CommandInterpreter::connect() { - if(!connected) { - int tries = try_reconnect; // tries == 0 => infinite - while(!connected) { - if(ndb_mgm_connect(m_mgmsrv, host) == -1) { - ndbout << "Cannot connect to management server (" << host << ")."; - tries--; - if (tries == 0) - break; - ndbout << "Retrying in 5 seconds." << endl; - NdbSleep_SecSleep(5); - } else - connected = true; + if(!m_connected) + { + if(!ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1)) + { + const char *host= ndb_mgm_get_connected_host(m_mgmsrv); + unsigned port= ndb_mgm_get_connected_port(m_mgmsrv); + if(!ndb_mgm_set_connectstring(m_mgmsrv2, + BaseString(host).appfmt(":%d",port).c_str()) + && + !ndb_mgm_connect(m_mgmsrv2, try_reconnect-1, 5, 1)) + { + assert(m_event_thread == 0); + assert(do_event_thread == 0); + do_event_thread= 0; + m_event_thread = NdbThread_Create(event_thread_run, + (void**)&m_mgmsrv2, + 32768, + "CommandInterpreted_event_thread", + NDB_THREAD_PRIO_LOW); + if (m_event_thread != 0) + { + int iter= 1000; // try for 30 seconds + while(do_event_thread == 0 && + iter-- > 0) + NdbSleep_MilliSleep(30); + } + if (m_event_thread == 0 || + do_event_thread == 0 || + do_event_thread == -1) + { + printf("Warning, event thread startup failed, degraded printouts as result\n"); + do_event_thread= 0; + } + } + else + { + printf("Warning, event connect failed, degraded printouts as result\n"); + } + m_connected= true; + if (m_verbose) + { + printf("Connected to Management Server at: %s:%d\n", + host, port); + } } } - return connected; + return m_connected; } bool CommandInterpreter::disconnect() { - if (ndb_mgm_disconnect(m_mgmsrv) == -1) { - ndbout_c("Could not disconnect from management server"); - printError(); + if (m_event_thread) { + void *res; + do_event_thread= 0; + NdbThread_WaitFor(m_event_thread, &res); + NdbThread_Destroy(&m_event_thread); + m_event_thread= 0; + ndb_mgm_disconnect(m_mgmsrv2); + } + if (m_connected) + { + if (ndb_mgm_disconnect(m_mgmsrv) == -1) { + ndbout_c("Could not disconnect from management server"); + printError(); + } + m_connected= false; } - connected = false; return true; } @@ -469,92 +563,136 @@ CommandInterpreter::disconnect() //***************************************************************************** int -CommandInterpreter::execute(const char *_line, int _try_reconnect) +CommandInterpreter::execute(const char *_line, int _try_reconnect, + int *error) { if (_try_reconnect >= 0) try_reconnect=_try_reconnect; + int result= execute_impl(_line); + if (error) + *error= m_error; + return result; +} + +static void +invalid_command(const char *cmd) +{ + ndbout << "Invalid command: " << cmd << endl; + ndbout << "Type HELP for help." << endl << endl; +} + +int +CommandInterpreter::execute_impl(const char *_line) +{ + DBUG_ENTER("CommandInterpreter::execute_impl"); + DBUG_PRINT("enter",("line=\"%s\"",_line)); + m_error= 0; + char * line; if(_line == NULL) { - // ndbout << endl; - return false; + DBUG_RETURN(false); } line = my_strdup(_line,MYF(MY_WME)); My_auto_ptr<char> ptr(line); - - if (emptyString(line)) { - return true; - } - - for (unsigned int i = 0; i < strlen(line); ++i) { - line[i] = toupper(line[i]); - } + int do_continue; + do { + do_continue= 0; + BaseString::trim(line," \t"); + if (line[0] == 0 || + line[0] == '#') + { + DBUG_RETURN(true); + } + // for mysql client compatability remove trailing ';' + { + unsigned last= strlen(line)-1; + if (line[last] == ';') + { + line[last]= 0; + do_continue= 1; + } + } + } while (do_continue); // if there is anything in the line proceed char* firstToken = strtok(line, " "); char* allAfterFirstToken = strtok(NULL, ""); - if (strcmp(firstToken, "HELP") == 0 || - strcmp(firstToken, "?") == 0) { + if (strcasecmp(firstToken, "HELP") == 0 || + strcasecmp(firstToken, "?") == 0) { executeHelp(allAfterFirstToken); - return true; + DBUG_RETURN(true); + } + else if (strcasecmp(firstToken, "CONNECT") == 0) { + executeConnect(allAfterFirstToken); + DBUG_RETURN(true); + } + else if (strcasecmp(firstToken, "SLEEP") == 0) { + if (allAfterFirstToken) + sleep(atoi(allAfterFirstToken)); + DBUG_RETURN(true); } - else if (strcmp(firstToken, "SHOW") == 0) { + else if((strcasecmp(firstToken, "QUIT") == 0 || + strcasecmp(firstToken, "EXIT") == 0 || + strcasecmp(firstToken, "BYE") == 0) && + allAfterFirstToken == NULL){ + DBUG_RETURN(false); + } + + if (!connect()) + DBUG_RETURN(true); + + if (strcasecmp(firstToken, "SHOW") == 0) { executeShow(allAfterFirstToken); - return true; + DBUG_RETURN(true); } - else if (strcmp(firstToken, "SHUTDOWN") == 0) { - executeShutdown(allAfterFirstToken); - return true; + else if (strcasecmp(firstToken, "SHUTDOWN") == 0) { + m_error= executeShutdown(allAfterFirstToken); + DBUG_RETURN(true); } - else if (strcmp(firstToken, "CLUSTERLOG") == 0){ + else if (strcasecmp(firstToken, "CLUSTERLOG") == 0){ executeClusterLog(allAfterFirstToken); - return true; + DBUG_RETURN(true); } - else if(strcmp(firstToken, "START") == 0 && + else if(strcasecmp(firstToken, "START") == 0 && allAfterFirstToken != NULL && - strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){ - executeStartBackup(allAfterFirstToken); - return true; + strncasecmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){ + m_error= executeStartBackup(allAfterFirstToken); + DBUG_RETURN(true); } - else if(strcmp(firstToken, "ABORT") == 0 && + else if(strcasecmp(firstToken, "ABORT") == 0 && allAfterFirstToken != NULL && - strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){ + strncasecmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){ executeAbortBackup(allAfterFirstToken); - return true; + DBUG_RETURN(true); } - else if (strcmp(firstToken, "PURGE") == 0) { + else if (strcasecmp(firstToken, "PURGE") == 0) { executePurge(allAfterFirstToken); - return true; + DBUG_RETURN(true); } #ifdef HAVE_GLOBAL_REPLICATION - else if(strcmp(firstToken, "REPLICATION") == 0 || - strcmp(firstToken, "REP") == 0) { + else if(strcasecmp(firstToken, "REPLICATION") == 0 || + strcasecmp(firstToken, "REP") == 0) { executeRep(allAfterFirstToken); - return true; + DBUG_RETURN(true); } #endif // HAVE_GLOBAL_REPLICATION - else if(strcmp(firstToken, "ENTER") == 0 && + else if(strcasecmp(firstToken, "ENTER") == 0 && allAfterFirstToken != NULL && - strncmp(allAfterFirstToken, "SINGLE USER MODE ", + strncasecmp(allAfterFirstToken, "SINGLE USER MODE ", sizeof("SINGLE USER MODE") - 1) == 0){ executeEnterSingleUser(allAfterFirstToken); - return true; + DBUG_RETURN(true); } - else if(strcmp(firstToken, "EXIT") == 0 && + else if(strcasecmp(firstToken, "EXIT") == 0 && allAfterFirstToken != NULL && - strncmp(allAfterFirstToken, "SINGLE USER MODE ", + strncasecmp(allAfterFirstToken, "SINGLE USER MODE ", sizeof("SINGLE USER MODE") - 1) == 0){ executeExitSingleUser(allAfterFirstToken); - return true; + DBUG_RETURN(true); } - else if (strcmp(firstToken, "ALL") == 0) { + else if (strcasecmp(firstToken, "ALL") == 0) { analyseAfterFirstToken(-1, allAfterFirstToken); - } - else if((strcmp(firstToken, "QUIT") == 0 || - strcmp(firstToken, "EXIT") == 0 || - strcmp(firstToken, "BYE") == 0) && - allAfterFirstToken == NULL){ - return false; } else { /** * First token should be a digit, node ID @@ -562,20 +700,19 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect) int nodeId; if (! convert(firstToken, nodeId)) { - ndbout << "Invalid command: " << line << endl; - ndbout << "Type HELP for help." << endl << endl; - return true; + invalid_command(_line); + DBUG_RETURN(true); } - if (nodeId < 0) { + if (nodeId <= 0) { ndbout << "Invalid node ID: " << firstToken << "." << endl; - return true; + DBUG_RETURN(true); } analyseAfterFirstToken(nodeId, allAfterFirstToken); } - return true; + DBUG_RETURN(true); } @@ -612,12 +749,8 @@ CommandInterpreter::analyseAfterFirstToken(int processId, char* allAfterFirstToken) { if (emptyString(allAfterFirstToken)) { - if (processId == -1) { - ndbout << "Expected a command after ALL." << endl; - } - else { - ndbout << "Expected a command after node ID." << endl; - } + ndbout << "Expected a command after " + << ((processId == -1) ? "ALL." : "node ID.") << endl; return; } @@ -628,7 +761,7 @@ CommandInterpreter::analyseAfterFirstToken(int processId, ExecuteFunction fun = 0; const char * command = 0; for(int i = 0; i<tmpSize; i++){ - if(strcmp(secondToken, commands[i].command) == 0){ + if(strcasecmp(secondToken, commands[i].command) == 0){ fun = commands[i].executeFunction; command = commands[i].command; break; @@ -636,19 +769,16 @@ CommandInterpreter::analyseAfterFirstToken(int processId, } if(fun == 0){ - ndbout << "Invalid command: " << secondToken << endl; - ndbout << "Type HELP for help." << endl << endl; + invalid_command(secondToken); return; } if(processId == -1){ executeForAll(command, fun, allAfterSecondToken); } else { - if(strcmp(command, "STATUS") != 0) - ndbout_c("Executing %s on node %d.", command, processId); (this->*fun)(processId, allAfterSecondToken, false); - ndbout << endl; } + ndbout << endl; } /** @@ -694,17 +824,16 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun, const char * allAfterSecondToken) { int nodeId = 0; - if(strcmp(cmd, "STOP") == 0) { + if(strcasecmp(cmd, "STOP") == 0) { ndbout_c("Executing STOP on all nodes."); (this->*fun)(nodeId, allAfterSecondToken, true); - } else if(strcmp(cmd, "RESTART") == 0) { + } else if(strcasecmp(cmd, "RESTART") == 0) { ndbout_c("Executing RESTART on all nodes."); ndbout_c("Starting shutdown. This may take a while. Please wait..."); (this->*fun)(nodeId, allAfterSecondToken, true); ndbout_c("Trying to start all nodes of system."); ndbout_c("Use ALL STATUS to see the system start-up phases."); } else { - connect(); struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(m_mgmsrv); if(cl == 0){ ndbout_c("Unable get status from management server"); @@ -712,12 +841,8 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun, return; } NdbAutoPtr<char> ap1((char*)cl); - while(get_next_nodeid(cl, &nodeId, NDB_MGM_NODE_TYPE_NDB)) { - if(strcmp(cmd, "STATUS") != 0) - ndbout_c("Executing %s on node %d.", cmd, nodeId); + while(get_next_nodeid(cl, &nodeId, NDB_MGM_NODE_TYPE_NDB)) (this->*fun)(nodeId, allAfterSecondToken, true); - ndbout << endl; - } // while } } @@ -741,7 +866,7 @@ CommandInterpreter::parseBlockSpecification(const char* allAfterLog, firstTokenAfterLog[i] = toupper(firstTokenAfterLog[i]); } - if (strcmp(firstTokenAfterLog, "BLOCK") != 0) { + if (strcasecmp(firstTokenAfterLog, "BLOCK") != 0) { ndbout << "Unexpected value: " << firstTokenAfterLog << ". Expected BLOCK." << endl; return false; @@ -754,7 +879,7 @@ CommandInterpreter::parseBlockSpecification(const char* allAfterLog, } char* secondTokenAfterLog = strtok(allAfterFirstToken, " "); - if (strcmp(secondTokenAfterLog, "=") != 0) { + if (strcasecmp(secondTokenAfterLog, "=") != 0) { ndbout << "Unexpected value: " << secondTokenAfterLog << ". Expected =." << endl; return false; @@ -762,7 +887,7 @@ CommandInterpreter::parseBlockSpecification(const char* allAfterLog, char* blockName = strtok(NULL, " "); bool all = false; - if (blockName != NULL && (strcmp(blockName, "ALL") == 0)) { + if (blockName != NULL && (strcasecmp(blockName, "ALL") == 0)) { all = true; } while (blockName != NULL) { @@ -813,20 +938,19 @@ CommandInterpreter::executeHelp(char* parameters) ndbout << "<level> = " << "0 - 15" << endl; ndbout << "<id> = " << "ALL | Any database node id" << endl; ndbout << endl; - } else if (strcmp(parameters, "SHOW") == 0) { + } else if (strcasecmp(parameters, "SHOW") == 0) { ndbout << helpTextShow; #ifdef HAVE_GLOBAL_REPLICATION - } else if (strcmp(parameters, "REPLICATION") == 0 || - strcmp(parameters, "REP") == 0) { + } else if (strcasecmp(parameters, "REPLICATION") == 0 || + strcasecmp(parameters, "REP") == 0) { ndbout << helpTextRep; #endif // HAVE_GLOBAL_REPLICATION #ifdef VM_TRACE // DEBUG ONLY - } else if (strcmp(parameters, "DEBUG") == 0) { + } else if (strcasecmp(parameters, "DEBUG") == 0) { ndbout << helpTextDebug; #endif } else { - ndbout << "Invalid argument: " << parameters << endl; - ndbout << "Type HELP for help." << endl << endl; + invalid_command(parameters); } } @@ -835,25 +959,23 @@ CommandInterpreter::executeHelp(char* parameters) * SHUTDOWN *****************************************************************************/ -void +int CommandInterpreter::executeShutdown(char* parameters) { - connect(); - ndb_mgm_cluster_state *state = ndb_mgm_get_status(m_mgmsrv); if(state == NULL) { ndbout_c("Could not get status"); printError(); - return; + return 1; } NdbAutoPtr<char> ap1((char*)state); int result = 0; result = ndb_mgm_stop(m_mgmsrv, 0, 0); if (result < 0) { - ndbout << "Shutdown failed." << endl; + ndbout << "Shutdown off NDB Cluster storage node(s) failed." << endl; printError(); - return; + return result; } ndbout << result << " NDB Cluster storage node(s) have shutdown." << endl; @@ -868,21 +990,24 @@ CommandInterpreter::executeShutdown(char* parameters) ndbout << "Unable to locate management server, " << "shutdown manually with <id> STOP" << endl; - return; + return 1; } } } - result = 0; result = ndb_mgm_stop(m_mgmsrv, 1, &mgm_id); if (result <= 0) { - ndbout << "Shutdown failed." << endl; + ndbout << "Shutdown of NDB Cluster management server failed." << endl; printError(); - return; + if (result == 0) + return 1; + return result; } + m_connected= false; + disconnect(); ndbout << "NDB Cluster management server shutdown." << endl; - exit(0); + return 0; } /***************************************************************************** @@ -931,7 +1056,7 @@ print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it, const char *hostname= node_state->connect_address; if (hostname == 0 || strlen(hostname) == 0 - || strcmp(hostname,"0.0.0.0") == 0) + || strcasecmp(hostname,"0.0.0.0") == 0) ndbout << " "; else ndbout << "\t@" << hostname; @@ -976,9 +1101,9 @@ CommandInterpreter::executePurge(char* parameters) break; char* firstToken = strtok(parameters, " "); char* nextToken = strtok(NULL, " \0"); - if (strcmp(firstToken,"STALE") == 0 && + if (strcasecmp(firstToken,"STALE") == 0 && nextToken && - strcmp(nextToken, "SESSIONS") == 0) { + strcasecmp(nextToken, "SESSIONS") == 0) { command_ok= 1; break; } @@ -991,7 +1116,6 @@ CommandInterpreter::executePurge(char* parameters) int i; char *str; - connect(); if (ndb_mgm_purge_stale_sessions(m_mgmsrv, &str)) { ndbout_c("Command failed"); @@ -1011,11 +1135,7 @@ void CommandInterpreter::executeShow(char* parameters) { int i; - connect(); if (emptyString(parameters)) { - ndbout << "Cluster Configuration" << endl - << "---------------------" << endl; - ndb_mgm_cluster_state *state = ndb_mgm_get_status(m_mgmsrv); if(state == NULL) { ndbout_c("Could not get status"); @@ -1075,22 +1195,24 @@ CommandInterpreter::executeShow(char* parameters) } } + ndbout << "Cluster Configuration" << endl + << "---------------------" << endl; print_nodes(state, it, "ndbd", ndb_nodes, NDB_MGM_NODE_TYPE_NDB, master_id); print_nodes(state, it, "ndb_mgmd", mgm_nodes, NDB_MGM_NODE_TYPE_MGM, 0); print_nodes(state, it, "mysqld", api_nodes, NDB_MGM_NODE_TYPE_API, 0); // ndbout << helpTextShow; return; - } else if (strcmp(parameters, "PROPERTIES") == 0 || - strcmp(parameters, "PROP") == 0) { + } else if (strcasecmp(parameters, "PROPERTIES") == 0 || + strcasecmp(parameters, "PROP") == 0) { ndbout << "SHOW PROPERTIES is not yet implemented." << endl; // ndbout << "_mgmtSrvr.getConfig()->print();" << endl; /* XXX */ - } else if (strcmp(parameters, "CONFIGURATION") == 0 || - strcmp(parameters, "CONFIG") == 0){ + } else if (strcasecmp(parameters, "CONFIGURATION") == 0 || + strcasecmp(parameters, "CONFIG") == 0){ ndbout << "SHOW CONFIGURATION is not yet implemented." << endl; //nbout << "_mgmtSrvr.getConfig()->printConfigFile();" << endl; /* XXX */ - } else if (strcmp(parameters, "PARAMETERS") == 0 || - strcmp(parameters, "PARAMS") == 0 || - strcmp(parameters, "PARAM") == 0) { + } else if (strcasecmp(parameters, "PARAMETERS") == 0 || + strcasecmp(parameters, "PARAMS") == 0 || + strcasecmp(parameters, "PARAM") == 0) { ndbout << "SHOW PARAMETERS is not yet implemented." << endl; // ndbout << "_mgmtSrvr.getConfig()->getConfigInfo()->print();" // << endl; /* XXX */ @@ -1099,151 +1221,150 @@ CommandInterpreter::executeShow(char* parameters) } } +void +CommandInterpreter::executeConnect(char* parameters) +{ + disconnect(); + if (!emptyString(parameters)) { + if (ndb_mgm_set_connectstring(m_mgmsrv, + BaseString(parameters).trim().c_str())) + { + printError(); + return; + } + } + connect(); +} //***************************************************************************** //***************************************************************************** void CommandInterpreter::executeClusterLog(char* parameters) { + DBUG_ENTER("CommandInterpreter::executeClusterLog"); int i; - connect(); - if (parameters != 0 && strlen(parameters) != 0) { - enum ndb_mgm_clusterlog_level severity = NDB_MGM_CLUSTERLOG_ALL; - int isOk = true; - char name[12]; - bool noArgs = false; - - char * tmpString = my_strdup(parameters,MYF(MY_WME)); - My_auto_ptr<char> ap1(tmpString); - char * tmpPtr = 0; - char * item = strtok_r(tmpString, " ", &tmpPtr); + if (emptyString(parameters)) + { + ndbout << "Missing argument." << endl; + DBUG_VOID_RETURN; + } + + enum ndb_mgm_clusterlog_level severity = NDB_MGM_CLUSTERLOG_ALL; - /******************** - * CLUSTERLOG FILTER - ********************/ - if (strcmp(item, "FILTER") == 0) { - - item = strtok_r(NULL, " ", &tmpPtr); - if (item == NULL) { - noArgs = true; - } - while (item != NULL) { - snprintf(name, sizeof(name), item); - - if (strcmp(item, "ALL") == 0) { - severity = NDB_MGM_CLUSTERLOG_ALL; - } else if (strcmp(item, "ALERT") == 0) { - severity = NDB_MGM_CLUSTERLOG_ALERT; - } else if (strcmp(item, "CRITICAL") == 0) { - severity = NDB_MGM_CLUSTERLOG_CRITICAL; - } else if (strcmp(item, "ERROR") == 0) { - severity = NDB_MGM_CLUSTERLOG_ERROR; - } else if (strcmp(item, "WARNING") == 0) { - severity = NDB_MGM_CLUSTERLOG_WARNING; - } else if (strcmp(item, "INFO") == 0) { - severity = NDB_MGM_CLUSTERLOG_INFO; - } else if (strcmp(item, "DEBUG") == 0) { - severity = NDB_MGM_CLUSTERLOG_DEBUG; - } else if (strcmp(item, "OFF") == 0) { - severity = NDB_MGM_CLUSTERLOG_OFF; - } else { - isOk = false; - } - - item = strtok_r(NULL, " ", &tmpPtr); - } // while(item != NULL){ - - if (noArgs) { - ndbout << "Missing argument(s)." << endl; - } else if (isOk) { - if(ndb_mgm_filter_clusterlog(m_mgmsrv, severity, NULL)) { - if(strcmp(name, "ALL") == 0 || strcmp(name, "all") == 0) { - ndbout << "All severities levels enabled." << endl; - } else if(strcmp(name, "OFF") == 0 || strcmp(name, "off") == 0) { - ndbout << "Cluster logging enabled." << endl; - } else { - ndbout << name << " events disabled." << endl; - } - } else { - if(strcmp(name, "ALL") == 0) { - ndbout << "All severities levels disabled." << endl; - } else if(strcmp(name, "OFF") == 0) { - ndbout << "Cluster logging disabled." << endl; - } else { - ndbout << name << " events enabled." << endl; - } - } - } else { - ndbout << "Invalid severity level." << endl; - } + char * tmpString = my_strdup(parameters,MYF(MY_WME)); + My_auto_ptr<char> ap1(tmpString); + char * tmpPtr = 0; + char * item = strtok_r(tmpString, " ", &tmpPtr); + int enable; - /******************** - * CLUSTERLOG INFO - ********************/ - } else if (strcmp(item, "INFO") == 0) { - Uint32 *enabled = ndb_mgm_get_logfilter(m_mgmsrv); - if(enabled == NULL) { - ndbout << "Couldn't get status" << endl; - printError(); - return; - } - const char* names[] = {"ENABLED", "DEBUG", "INFO", "WARNING", "ERROR", - "CRITICAL", "ALERT"}; - if(enabled[0]) - ndbout << "Cluster logging is disabled." << endl; + Uint32 *enabled = ndb_mgm_get_logfilter(m_mgmsrv); + if(enabled == NULL) { + ndbout << "Couldn't get status" << endl; + printError(); + DBUG_VOID_RETURN; + } - - for(i = 0; i<7;i++) - printf("enabled[%d] = %d\n", i, enabled[i]); - ndbout << "Severities enabled: "; - for(i = 1; i < 7; i++) { - if(enabled[i]) - ndbout << names[i] << " "; - } - ndbout << endl; - - /******************** - * CLUSTERLOG OFF - ********************/ - } else if (strcmp(item, "OFF") == 0) { - Uint32 *enabled = ndb_mgm_get_logfilter(m_mgmsrv); - if(enabled == NULL) { - ndbout << "Couldn't get status" << endl; - printError(); - return; - } - if(!enabled[0]) { - ndb_mgm_filter_clusterlog(m_mgmsrv, NDB_MGM_CLUSTERLOG_OFF, NULL); - ndbout << "Cluster logging is disabled." << endl; - } else { - ndbout << "Cluster logging is already disabled." << endl; - - } - - /******************** - * CLUSTERLOG ON - ********************/ - } else if (strcmp(item, "ON") == 0) { - Uint32 *enabled = ndb_mgm_get_logfilter(m_mgmsrv); - if(enabled == NULL) { - ndbout << "Could not get status" << endl; - printError(); - return; - } - if(enabled[0]) { - ndb_mgm_filter_clusterlog(m_mgmsrv, NDB_MGM_CLUSTERLOG_OFF, NULL); - ndbout << "Cluster logging is enabled." << endl; - } else { - ndbout << "Cluster logging is already enabled." << endl; - + /******************** + * CLUSTERLOG INFO + ********************/ + if (strcasecmp(item, "INFO") == 0) { + DBUG_PRINT("info",("INFO")); + if(enabled[0] == 0) + { + ndbout << "Cluster logging is disabled." << endl; + DBUG_VOID_RETURN; + } +#if 0 + for(i = 0; i<7;i++) + printf("enabled[%d] = %d\n", i, enabled[i]); +#endif + ndbout << "Severities enabled: "; + for(i = 1; i < (int)NDB_MGM_CLUSTERLOG_ALL; i++) { + const char *str= ndb_mgm_get_clusterlog_level_string((ndb_mgm_clusterlog_level)i); + if (str == 0) + { + DBUG_ASSERT(false); + continue; } - } else { - ndbout << "Invalid argument." << endl; + if(enabled[i]) + ndbout << BaseString(str).ndb_toupper() << " "; } - + ndbout << endl; + DBUG_VOID_RETURN; + + } + else if (strcasecmp(item, "FILTER") == 0 || + strcasecmp(item, "TOGGLE") == 0) + { + DBUG_PRINT("info",("TOGGLE")); + enable= -1; + } + else if (strcasecmp(item, "OFF") == 0) + { + DBUG_PRINT("info",("OFF")); + enable= 0; + } else if (strcasecmp(item, "ON") == 0) { + DBUG_PRINT("info",("ON")); + enable= 1; } else { - ndbout << "Missing argument." << endl; + ndbout << "Invalid argument." << endl; + DBUG_VOID_RETURN; + } + + int res_enable; + item = strtok_r(NULL, " ", &tmpPtr); + if (item == NULL) { + res_enable= ndb_mgm_filter_clusterlog(m_mgmsrv, + NDB_MGM_CLUSTERLOG_ON, enable, NULL); + if (res_enable < 0) + { + ndbout << "Couldn't set filter" << endl; + printError(); + DBUG_VOID_RETURN; + } + ndbout << "Cluster logging is " << (res_enable ? "enabled.":"disabled") << endl; + DBUG_VOID_RETURN; } + + do { + severity= NDB_MGM_ILLEGAL_CLUSTERLOG_LEVEL; + if (strcasecmp(item, "ALL") == 0) { + severity = NDB_MGM_CLUSTERLOG_ALL; + } else if (strcasecmp(item, "ALERT") == 0) { + severity = NDB_MGM_CLUSTERLOG_ALERT; + } else if (strcasecmp(item, "CRITICAL") == 0) { + severity = NDB_MGM_CLUSTERLOG_CRITICAL; + } else if (strcasecmp(item, "ERROR") == 0) { + severity = NDB_MGM_CLUSTERLOG_ERROR; + } else if (strcasecmp(item, "WARNING") == 0) { + severity = NDB_MGM_CLUSTERLOG_WARNING; + } else if (strcasecmp(item, "INFO") == 0) { + severity = NDB_MGM_CLUSTERLOG_INFO; + } else if (strcasecmp(item, "DEBUG") == 0) { + severity = NDB_MGM_CLUSTERLOG_DEBUG; + } else if (strcasecmp(item, "OFF") == 0 || + strcasecmp(item, "ON") == 0) { + if (enable < 0) // only makes sense with toggle + severity = NDB_MGM_CLUSTERLOG_ON; + } + if (severity == NDB_MGM_ILLEGAL_CLUSTERLOG_LEVEL) { + ndbout << "Invalid severity level: " << item << endl; + DBUG_VOID_RETURN; + } + + res_enable = ndb_mgm_filter_clusterlog(m_mgmsrv, severity, enable, NULL); + if (res_enable < 0) + { + ndbout << "Couldn't set filter" << endl; + printError(); + DBUG_VOID_RETURN; + } + ndbout << BaseString(item).ndb_toupper().c_str() << " " << (res_enable ? "enabled":"disabled") << endl; + + item = strtok_r(NULL, " ", &tmpPtr); + } while(item != NULL); + + DBUG_VOID_RETURN; } //***************************************************************************** @@ -1252,7 +1373,6 @@ CommandInterpreter::executeClusterLog(char* parameters) void CommandInterpreter::executeStop(int processId, const char *, bool all) { - connect(); int result = 0; if(all) { result = ndb_mgm_stop(m_mgmsrv, 0, 0); @@ -1274,7 +1394,6 @@ CommandInterpreter::executeStop(int processId, const char *, bool all) void CommandInterpreter::executeEnterSingleUser(char* parameters) { - connect(); strtok(parameters, " "); struct ndb_mgm_reply reply; char* id = strtok(NULL, " "); @@ -1301,7 +1420,6 @@ CommandInterpreter::executeEnterSingleUser(char* parameters) void CommandInterpreter::executeExitSingleUser(char* parameters) { - connect(); int result = ndb_mgm_exit_single_user(m_mgmsrv, 0); if (result != 0) { ndbout_c("Exiting single user mode failed."); @@ -1316,7 +1434,6 @@ void CommandInterpreter::executeStart(int processId, const char* parameters, bool all) { - connect(); int result; if(all) { result = ndb_mgm_start(m_mgmsrv, 0, 0); @@ -1340,7 +1457,6 @@ void CommandInterpreter::executeRestart(int processId, const char* parameters, bool all) { - connect(); int result; int nostart = 0; int initialstart = 0; @@ -1352,11 +1468,11 @@ CommandInterpreter::executeRestart(int processId, const char* parameters, char * tmpPtr = 0; char * item = strtok_r(tmpString, " ", &tmpPtr); while(item != NULL){ - if(strcmp(item, "-N") == 0) + if(strcasecmp(item, "-N") == 0) nostart = 1; - if(strcmp(item, "-I") == 0) + if(strcasecmp(item, "-I") == 0) initialstart = 1; - if(strcmp(item, "-A") == 0) + if(strcasecmp(item, "-A") == 0) abort = 1; item = strtok_r(NULL, " ", &tmpPtr); } @@ -1378,7 +1494,7 @@ CommandInterpreter::executeRestart(int processId, const char* parameters, if(all) ndbout << "NDB Cluster is being restarted." << endl; else - ndbout_c("Database node %d is being restarted.", processId); + ndbout_c("Node %d is being restarted.", processId); } } @@ -1386,11 +1502,10 @@ void CommandInterpreter::executeDumpState(int processId, const char* parameters, bool all) { - if(parameters == 0 || strlen(parameters) == 0){ + if(emptyString(parameters)){ ndbout << "Expected argument" << endl; return; } - connect(); Uint32 no = 0; int pars[25]; @@ -1426,11 +1541,10 @@ CommandInterpreter::executeStatus(int processId, const char* parameters, bool all) { if (! emptyString(parameters)) { - ndbout << "No parameters expected to this command." << endl; + ndbout_c("No parameters expected to this command."); return; } - connect(); ndb_mgm_node_status status; Uint32 startPhase, version; bool system; @@ -1458,7 +1572,7 @@ CommandInterpreter::executeStatus(int processId, ndbout << "Node " << processId << ": " << status_string(status); switch(status){ case NDB_MGM_NODE_STATUS_STARTING: - ndbout << " (Phase " << startPhase << ")" ; + ndbout << " (Phase " << startPhase << ")"; break; case NDB_MGM_NODE_STATUS_SHUTTING_DOWN: ndbout << " (Phase " << startPhase << ")"; @@ -1471,6 +1585,8 @@ CommandInterpreter::executeStatus(int processId, getMajor(version) , getMinor(version), getBuild(version)); + else + ndbout << endl; } @@ -1481,9 +1597,11 @@ void CommandInterpreter::executeLogLevel(int processId, const char* parameters, bool all) { - connect(); (void) all; - + if (emptyString(parameters)) { + ndbout << "Expected argument" << endl; + return; + } BaseString tmp(parameters); Vector<BaseString> spec; tmp.split(spec, "="); @@ -1509,6 +1627,8 @@ CommandInterpreter::executeLogLevel(int processId, const char* parameters, return; } + ndbout << "Executing LOGLEVEL on node " << processId << flush; + struct ndb_mgm_reply reply; int result; result = ndb_mgm_set_loglevel_node(m_mgmsrv, @@ -1518,11 +1638,10 @@ CommandInterpreter::executeLogLevel(int processId, const char* parameters, &reply); if (result < 0) { - ndbout_c("Executing LOGLEVEL on node %d failed.", processId); + ndbout_c(" failed."); printError(); } else { - ndbout << "Executing LOGLEVEL on node " << processId << " OK!" - << endl; + ndbout_c(" OK!"); } } @@ -1537,7 +1656,6 @@ void CommandInterpreter::executeError(int processId, return; } - connect(); // Copy parameters since strtok will modify it char* newpar = my_strdup(parameters,MYF(MY_WME)); My_auto_ptr<char> ap1(newpar); @@ -1589,7 +1707,7 @@ CommandInterpreter::executeTrace(int /*processId*/, int result = _mgmtSrvr.setTraceNo(processId, traceNo); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } #endif } @@ -1601,7 +1719,6 @@ void CommandInterpreter::executeLog(int processId, const char* parameters, bool all) { - connect(); struct ndb_mgm_reply reply; Vector<const char *> blocks; if (! parseBlockSpecification(parameters, blocks)) { @@ -1669,7 +1786,6 @@ CommandInterpreter::executeTestOn(int processId, ndbout << "No parameters expected to this command." << endl; return; } - connect(); struct ndb_mgm_reply reply; int result = ndb_mgm_start_signallog(m_mgmsrv, processId, &reply); if (result != 0) { @@ -1688,7 +1804,6 @@ CommandInterpreter::executeTestOff(int processId, ndbout << "No parameters expected to this command." << endl; return; } - connect(); struct ndb_mgm_reply reply; int result = ndb_mgm_stop_signallog(m_mgmsrv, processId, &reply); if (result != 0) { @@ -1752,7 +1867,7 @@ CommandInterpreter::executeSet(int /*processId*/, } } else { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; if (configBackupFileUpdated && configPrimaryFileUpdated) { ndbout << "The configuration files are however updated and " << "the value will be used next time the process is restarted." @@ -1787,7 +1902,7 @@ void CommandInterpreter::executeGetStat(int /*processId*/, MgmtSrvr::Statistics statistics; int result = _mgmtSrvr.getStatistics(processId, statistics); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; return; } #endif @@ -1806,8 +1921,10 @@ CommandInterpreter::executeEventReporting(int processId, const char* parameters, bool all) { - connect(); - + if (emptyString(parameters)) { + ndbout << "Expected argument" << endl; + return; + } BaseString tmp(parameters); Vector<BaseString> spec; tmp.split(spec, "="); @@ -1819,59 +1936,105 @@ CommandInterpreter::executeEventReporting(int processId, spec[0].trim().ndb_toupper(); int category = ndb_mgm_match_event_category(spec[0].c_str()); if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){ - category = atoi(spec[0].c_str()); - if(category < NDB_MGM_MIN_EVENT_CATEGORY || + if(!convert(spec[0].c_str(), category) || + category < NDB_MGM_MIN_EVENT_CATEGORY || category > NDB_MGM_MAX_EVENT_CATEGORY){ ndbout << "Unknown category: \"" << spec[0].c_str() << "\"" << endl; return; } } - - int level = atoi(spec[1].c_str()); - if(level < 0 || level > 15){ + + int level; + if (!convert(spec[1].c_str(),level)) + { ndbout << "Invalid level: " << spec[1].c_str() << endl; return; } - + + ndbout << "Executing CLUSTERLOG on node " << processId << flush; struct ndb_mgm_reply reply; int result; - result = ndb_mgm_set_loglevel_clusterlog(m_mgmsrv, - processId, // fast fix - pekka + processId, (ndb_mgm_event_category)category, level, &reply); if (result != 0) { - ndbout_c("Executing CLUSTERLOG on node %d failed", processId); + ndbout_c(" failed."); printError(); } else { - ndbout << "Executing CLUSTERLOG on node " << processId << " OK!" - << endl; + ndbout_c(" OK!"); } } /***************************************************************************** * Backup *****************************************************************************/ -void -CommandInterpreter::executeStartBackup(char* /*parameters*/) +int +CommandInterpreter::executeStartBackup(char* parameters) { - connect(); struct ndb_mgm_reply reply; unsigned int backupId; - +#if 0 int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 }; int fd = ndb_mgm_listen_event(m_mgmsrv, filter); - int result = ndb_mgm_start_backup(m_mgmsrv, &backupId, &reply); + if (fd < 0) + { + ndbout << "Initializing start of backup failed" << endl; + printError(); + return fd; + } +#endif + Vector<BaseString> args; + { + BaseString(parameters).split(args); + for (unsigned i= 0; i < args.size(); i++) + if (args[i].length() == 0) + args.erase(i--); + else + args[i].ndb_toupper(); + } + int sz= args.size(); + + int result; + if (sz == 2 && + args[1] == "NOWAIT") + { + result = ndb_mgm_start_backup(m_mgmsrv, 0, &backupId, &reply); + } + else if (sz == 1 || + (sz == 3 && + args[1] == "WAIT" && + args[2] == "COMPLETED")) + { + ndbout_c("Waiting for completed, this may take several minutes"); + result = ndb_mgm_start_backup(m_mgmsrv, 2, &backupId, &reply); + } + else if (sz == 3 && + args[1] == "WAIT" && + args[2] == "STARTED") + { + ndbout_c("Waiting for started, this may take several minutes"); + result = ndb_mgm_start_backup(m_mgmsrv, 1, &backupId, &reply); + } + else + { + invalid_command(parameters); + return -1; + } + if (result != 0) { ndbout << "Start of backup failed" << endl; printError(); +#if 0 close(fd); - return; +#endif + return result; } - +#if 0 + ndbout_c("Waiting for completed, this may take several minutes"); char *tmp; char buf[1024]; { @@ -1898,29 +2061,39 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/) ndbout << tmp; } } while(tmp && tmp[0] != 0); - + close(fd); +#endif + return 0; } void CommandInterpreter::executeAbortBackup(char* parameters) { - connect(); - strtok(parameters, " "); - struct ndb_mgm_reply reply; - char* id = strtok(NULL, "\0"); int bid = -1; - if(id == 0 || sscanf(id, "%d", &bid) != 1){ - ndbout << "Invalid arguments: expected <BackupId>" << endl; - return; + struct ndb_mgm_reply reply; + if (emptyString(parameters)) + goto executeAbortBackupError1; + + { + strtok(parameters, " "); + char* id = strtok(NULL, "\0"); + if(id == 0 || sscanf(id, "%d", &bid) != 1) + goto executeAbortBackupError1; } - int result = ndb_mgm_abort_backup(m_mgmsrv, bid, &reply); - if (result != 0) { - ndbout << "Abort of backup " << bid << " failed" << endl; - printError(); - } else { - ndbout << "Abort of backup " << bid << " ordered" << endl; + { + int result= ndb_mgm_abort_backup(m_mgmsrv, bid, &reply); + if (result != 0) { + ndbout << "Abort of backup " << bid << " failed" << endl; + printError(); + } else { + ndbout << "Abort of backup " << bid << " ordered" << endl; + } } + return; + executeAbortBackupError1: + ndbout << "Invalid arguments: expected <BackupId>" << endl; + return; } #ifdef HAVE_GLOBAL_REPLICATION @@ -1959,7 +2132,6 @@ CommandInterpreter::executeRep(char* parameters) return; } - connect(); char * line = my_strdup(parameters,MYF(MY_WME)); My_auto_ptr<char> ap1((char*)line); char * firstToken = strtok(line, " "); @@ -1968,7 +2140,7 @@ CommandInterpreter::executeRep(char* parameters) unsigned int repId; - if (!strcmp(firstToken, "CONNECT")) { + if (!strcasecmp(firstToken, "CONNECT")) { char * host = strtok(NULL, "\0"); for (unsigned int i = 0; i < strlen(host); ++i) { host[i] = tolower(host[i]); @@ -2003,30 +2175,30 @@ CommandInterpreter::executeRep(char* parameters) /******** * START ********/ - if (!strcmp(firstToken, "START")) { + if (!strcasecmp(firstToken, "START")) { unsigned int req; char *startType = strtok(NULL, "\0"); if (startType == NULL) { req = GrepReq::START; - } else if (!strcmp(startType, "SUBSCRIPTION")) { + } else if (!strcasecmp(startType, "SUBSCRIPTION")) { req = GrepReq::START_SUBSCR; - } else if (!strcmp(startType, "METALOG")) { + } else if (!strcasecmp(startType, "METALOG")) { req = GrepReq::START_METALOG; - } else if (!strcmp(startType, "METASCAN")) { + } else if (!strcasecmp(startType, "METASCAN")) { req = GrepReq::START_METASCAN; - } else if (!strcmp(startType, "DATALOG")) { + } else if (!strcasecmp(startType, "DATALOG")) { req = GrepReq::START_DATALOG; - } else if (!strcmp(startType, "DATASCAN")) { + } else if (!strcasecmp(startType, "DATASCAN")) { req = GrepReq::START_DATASCAN; - } else if (!strcmp(startType, "REQUESTOR")) { + } else if (!strcasecmp(startType, "REQUESTOR")) { req = GrepReq::START_REQUESTOR; - } else if (!strcmp(startType, "TRANSFER")) { + } else if (!strcasecmp(startType, "TRANSFER")) { req = GrepReq::START_TRANSFER; - } else if (!strcmp(startType, "APPLY")) { + } else if (!strcasecmp(startType, "APPLY")) { req = GrepReq::START_APPLY; - } else if (!strcmp(startType, "DELETE")) { + } else if (!strcasecmp(startType, "DELETE")) { req = GrepReq::START_DELETE; } else { ndbout_c("Illegal argument to command 'REPLICATION START'"); @@ -2046,7 +2218,7 @@ CommandInterpreter::executeRep(char* parameters) /******** * STOP ********/ - if (!strcmp(firstToken, "STOP")) { + if (!strcasecmp(firstToken, "STOP")) { unsigned int req; char *startType = strtok(NULL, " "); unsigned int epoch = 0; @@ -2056,7 +2228,7 @@ CommandInterpreter::executeRep(char* parameters) * Stop immediately */ req = GrepReq::STOP; - } else if (!strcmp(startType, "EPOCH")) { + } else if (!strcasecmp(startType, "EPOCH")) { char *strEpoch = strtok(NULL, "\0"); if(strEpoch == NULL) { ndbout_c("Epoch expected!"); @@ -2064,23 +2236,23 @@ CommandInterpreter::executeRep(char* parameters) } req = GrepReq::STOP; epoch=atoi(strEpoch); - } else if (!strcmp(startType, "SUBSCRIPTION")) { + } else if (!strcasecmp(startType, "SUBSCRIPTION")) { req = GrepReq::STOP_SUBSCR; - } else if (!strcmp(startType, "METALOG")) { + } else if (!strcasecmp(startType, "METALOG")) { req = GrepReq::STOP_METALOG; - } else if (!strcmp(startType, "METASCAN")) { + } else if (!strcasecmp(startType, "METASCAN")) { req = GrepReq::STOP_METASCAN; - } else if (!strcmp(startType, "DATALOG")) { + } else if (!strcasecmp(startType, "DATALOG")) { req = GrepReq::STOP_DATALOG; - } else if (!strcmp(startType, "DATASCAN")) { + } else if (!strcasecmp(startType, "DATASCAN")) { req = GrepReq::STOP_DATASCAN; - } else if (!strcmp(startType, "REQUESTOR")) { + } else if (!strcasecmp(startType, "REQUESTOR")) { req = GrepReq::STOP_REQUESTOR; - } else if (!strcmp(startType, "TRANSFER")) { + } else if (!strcasecmp(startType, "TRANSFER")) { req = GrepReq::STOP_TRANSFER; - } else if (!strcmp(startType, "APPLY")) { + } else if (!strcasecmp(startType, "APPLY")) { req = GrepReq::STOP_APPLY; - } else if (!strcmp(startType, "DELETE")) { + } else if (!strcasecmp(startType, "DELETE")) { req = GrepReq::STOP_DELETE; } else { ndbout_c("Illegal argument to command 'REPLICATION STOP'"); @@ -2099,7 +2271,7 @@ CommandInterpreter::executeRep(char* parameters) /********* * STATUS *********/ - if (!strcmp(firstToken, "STATUS")) { + if (!strcasecmp(firstToken, "STATUS")) { struct rep_state repstate; int result = ndb_rep_get_status(m_repserver, &repId, &reply, &repstate); @@ -2119,7 +2291,7 @@ CommandInterpreter::executeRep(char* parameters) /********* * QUERY (see repapi.h for querable counters) *********/ - if (!strcmp(firstToken, "QUERY")) { + if (!strcasecmp(firstToken, "QUERY")) { char *query = strtok(NULL, "\0"); int queryCounter=-1; if(query != NULL) { diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp index 401a9198f30..84e27790705 100644 --- a/ndb/src/mgmclient/main.cpp +++ b/ndb/src/mgmclient/main.cpp @@ -30,9 +30,10 @@ extern "C" int add_history(const char *command); /* From readline directory */ #include <NdbMain.h> #include <NdbHost.h> +#include <BaseString.hpp> +#include <NdbOut.hpp> #include <mgmapi.h> #include <ndb_version.h> -#include <LocalConfig.hpp> #include "ndb_mgmclient.hpp" @@ -55,17 +56,23 @@ handler(int sig){ } } - +static const char default_prompt[]= "ndb_mgm> "; static unsigned _try_reconnect; static char *opt_connect_str= 0; +static const char *prompt= default_prompt; +static char *opt_execute_str= 0; static struct my_option my_long_options[] = { NDB_STD_OPTS("ndb_mgm"), + { "execute", 'e', + "execute command and exit", + (gptr*) &opt_execute_str, (gptr*) &opt_execute_str, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, { "try-reconnect", 't', - "Specify number of retries for connecting to ndb_mgmd, default infinite", + "Specify number of tries for connecting to ndb_mgmd (0 = infinite)", (gptr*) &_try_reconnect, (gptr*) &_try_reconnect, 0, - GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + GET_UINT, REQUIRED_ARG, 3, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; static void short_usage_sub(void) @@ -115,13 +122,13 @@ read_and_execute(int _try_reconnect) } #ifdef HAVE_READLINE /* Get a line from the user. */ - line_read = readline ("ndb_mgm> "); + line_read = readline (prompt); /* If the line has any text in it, save it on the history. */ if (line_read && *line_read) add_history (line_read); #else static char linebuffer[254]; - fputs("ndb_mgm> ", stdout); + fputs(prompt, stdout); linebuffer[sizeof(linebuffer)-1]=0; line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin); if (line_read == linebuffer) { @@ -138,7 +145,7 @@ int main(int argc, char** argv){ NDB_INIT(argv[0]); const char *_host = 0; int _port = 0; - const char *load_default_groups[]= { "ndb_mgm",0 }; + const char *load_default_groups[]= { "mysql_cluster","ndb_mgm",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; @@ -154,15 +161,25 @@ int main(int argc, char** argv){ opt_connect_str= buf; } - ndbout << "-- NDB Cluster -- Management Client --" << endl; - printf("Connecting to Management Server: %s\n", opt_connect_str ? opt_connect_str : "default"); + if (!isatty(0) || opt_execute_str) + { + prompt= 0; + } signal(SIGPIPE, handler); - - com = new Ndb_mgmclient(opt_connect_str); - while(read_and_execute(_try_reconnect)); + com = new Ndb_mgmclient(opt_connect_str,1); + int ret= 0; + if (!opt_execute_str) + { + ndbout << "-- NDB Cluster -- Management Client --" << endl; + while(read_and_execute(_try_reconnect)); + } + else + { + com->execute(opt_execute_str,_try_reconnect, &ret); + } delete com; - return 0; + return ret; } diff --git a/ndb/src/mgmclient/ndb_mgmclient.hpp b/ndb/src/mgmclient/ndb_mgmclient.hpp index f6bcebc3896..bffdf69f920 100644 --- a/ndb/src/mgmclient/ndb_mgmclient.hpp +++ b/ndb/src/mgmclient/ndb_mgmclient.hpp @@ -21,10 +21,10 @@ class CommandInterpreter; class Ndb_mgmclient { public: - Ndb_mgmclient(const char*); + Ndb_mgmclient(const char*,int verbose=0); ~Ndb_mgmclient(); - int execute(const char *_line, int _try_reconnect=-1); - int execute(int argc, char** argv, int _try_reconnect=-1); + int execute(const char *_line, int _try_reconnect=-1, int *error= 0); + int execute(int argc, char** argv, int _try_reconnect=-1, int *error= 0); int disconnect(); private: CommandInterpreter *m_cmd; diff --git a/ndb/src/mgmsrv/CommandInterpreter.cpp b/ndb/src/mgmsrv/CommandInterpreter.cpp index c6ea9f662bb..526e7f5484a 100644 --- a/ndb/src/mgmsrv/CommandInterpreter.cpp +++ b/ndb/src/mgmsrv/CommandInterpreter.cpp @@ -113,6 +113,11 @@ private: void * m_ptr; }; +const char *CommandInterpreter::get_error_text(int err_no) +{ + return _mgmtSrvr.getErrorText(err_no, m_err_str, sizeof(m_err_str)); +} + //***************************************************************************** //***************************************************************************** int CommandInterpreter::readAndExecute() { @@ -152,10 +157,6 @@ int CommandInterpreter::readAndExecute() { executeShow(allAfterFirstToken); return true; } - else if (strcmp(firstToken, "CLUSTERLOG") == 0) { - executeClusterLog(allAfterFirstToken); - return true; - } else if(strcmp(firstToken, "START") == 0 && allAfterFirstToken != 0 && strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){ @@ -467,130 +468,6 @@ void CommandInterpreter::executeShow(char* parameters) { } } - -//***************************************************************************** -//***************************************************************************** -void CommandInterpreter::executeClusterLog(char* parameters) { - - if (parameters != 0 && strlen(parameters) != 0) { - int severity = 7; - int isOk = true; - char name[12]; - bool noArgs = false; - - char * tmpString = strdup(parameters); - char * tmpPtr = 0; - char * item = strtok_r(tmpString, " ", &tmpPtr); - - /******************** - * CLUSTERLOG FILTER - ********************/ - if (strcmp(item, "FILTER") == 0) { - - item = strtok_r(NULL, " ", &tmpPtr); - if (item == NULL) { - noArgs = true; - } - while (item != NULL) { - BaseString::snprintf(name, 12, item); - - if (strcmp(item, "ALL") == 0) { - severity = 7; - } else if (strcmp(item, "ALERT") == 0) { - severity = 6; - } else if (strcmp(item, "CRITICAL") == 0) { - severity = 5; - } else if (strcmp(item, "ERROR") == 0) { - severity = 4; - } else if (strcmp(item, "WARNING") == 0) { - severity = 3; - } else if (strcmp(item, "INFO") == 0) { - severity = 2; - } else if (strcmp(item, "DEBUG") == 0) { - severity = 1; - } else if (strcmp(item, "OFF") == 0) { - severity = 0; - } else { - isOk = false; - } - - item = strtok_r(NULL, " ", &tmpPtr); - } // while(item != NULL){ - free(tmpString); - - if (noArgs) { - ndbout << "Missing argument(s)." << endl; - } else if (isOk) { - if (_mgmtSrvr.setEventLogFilter(severity)) { - if(strcmp(name, "ALL") == 0 || strcmp(name, "all") == 0) { - ndbout << "All severities levels enabled." << endl; - } else if(strcmp(name, "OFF") == 0 || strcmp(name, "off") == 0) { - ndbout << "Cluster logging disabled." << endl; - } else { - ndbout << name << " events enabled." << endl; - } - } else { - if(strcmp(name, "ALL") == 0) { - ndbout << "All severities levels disabled." << endl; - } else if(strcmp(name, "OFF") == 0) { - ndbout << "Cluster logging enabled." << endl; - } else { - ndbout << name << " events disabled." << endl; - } - } - } else { - ndbout << "Invalid severity level." << endl; - } - - /******************** - * CLUSTERLOG INFO - ********************/ - } else if (strcmp(item, "INFO") == 0) { - const char* names[] = {"DEBUG", "INFO", "WARNING", "ERROR", - "CRITICAL", "ALERT"}; - if (_mgmtSrvr.isEventLogFilterEnabled(0)) { // OFF - ndbout << "Cluster logging is disabled." << endl; - } - - ndbout << "Severities enabled: "; - for (int i = 0; i < 6; i++) { - if (_mgmtSrvr.isEventLogFilterEnabled(i + 1)) { - ndbout << names[i] << " "; - } - } - ndbout << endl; - - /******************** - * CLUSTERLOG OFF - ********************/ - } else if (strcmp(item, "OFF") == 0) { - if (!_mgmtSrvr.isEventLogFilterEnabled(0)) { // ON - if (_mgmtSrvr.setEventLogFilter(0)); - ndbout << "Cluster logging is disabled." << endl; - } else { - ndbout << "Cluster logging is already disabled." << endl; - } - - /******************** - * CLUSTERLOG ON - ********************/ - } else if (strcmp(item, "ON") == 0) { - if (_mgmtSrvr.isEventLogFilterEnabled(0)) { // OFF - if (_mgmtSrvr.setEventLogFilter(0)); - ndbout << "Cluster logging is enabled." << endl; - } else { - ndbout << "Cluster logging is already enabled." << endl; - } - - } else { - ndbout << "Invalid argument." << endl; - } - - } else { - ndbout << "Missing argument." << endl; - } -} - void stopCallback(int nodeId, void * anyData, int errCode){ if(errCode == 0){ @@ -600,8 +477,9 @@ stopCallback(int nodeId, void * anyData, int errCode){ ndbout << "\nNode " << nodeId << " has shutdown" << endl; } else { MgmtSrvr * mgm = (MgmtSrvr *)anyData; + char err_str[1024]; ndbout << "Node " << nodeId << " has not shutdown: " - << mgm->getErrorText(errCode) << endl; + << mgm->getErrorText(errCode,err_str,sizeof(err_str)) << endl; } } @@ -653,7 +531,8 @@ versionCallback(int nodeId, int version, void * anyData, int errCode){ } else { MgmtSrvr * mgm = (MgmtSrvr *)anyData; - ndbout << mgm->getErrorText(errCode) << endl; + char err_str[1024]; + ndbout << mgm->getErrorText(errCode,err_str,sizeof(err_str)) << endl; } } @@ -671,7 +550,7 @@ void CommandInterpreter::executeStop(int processId, result = _mgmtSrvr.stopNode(processId, false, stopCallback, this); if(result != 0) - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } @@ -686,7 +565,7 @@ void CommandInterpreter::executeStart(int processId, const char* parameters, int result = _mgmtSrvr.start(processId); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } } @@ -719,7 +598,7 @@ CommandInterpreter::executeRestart(int processId, const char* parameters, stopCallback, this); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } } @@ -761,7 +640,7 @@ CommandInterpreter::executeDumpState(int processId, const char* parameters, free(tmpString); int result = _mgmtSrvr.dumpState(processId, pars, no); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } } @@ -782,7 +661,7 @@ void CommandInterpreter::executeStatus(int processId, &status, &version, &startPhase, &system, &dynamicId, &nodeGroup, &connectCount); if(result != 0){ - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; return; } @@ -876,7 +755,7 @@ void CommandInterpreter::executeLogLevel(int processId, int result = _mgmtSrvr.setNodeLogLevel(processId, logLevel); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } #endif } @@ -914,7 +793,7 @@ void CommandInterpreter::executeError(int processId, int result = _mgmtSrvr.insertError(processId, errorNo); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } free(newpar); } @@ -954,7 +833,7 @@ void CommandInterpreter::executeTrace(int processId, int result = _mgmtSrvr.setTraceNo(processId, traceNo); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } free(newpar); } @@ -975,7 +854,7 @@ void CommandInterpreter::executeLog(int processId, int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::InOut, blocks); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } } @@ -996,7 +875,7 @@ void CommandInterpreter::executeLogIn(int processId, int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::In, blocks); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } } @@ -1015,7 +894,7 @@ void CommandInterpreter::executeLogOut(int processId, int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Out, blocks); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } } @@ -1036,7 +915,7 @@ void CommandInterpreter::executeLogOff(int processId, int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Off, blocks); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } } @@ -1055,7 +934,7 @@ void CommandInterpreter::executeTestOn(int processId, int result = _mgmtSrvr.startSignalTracing(processId); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } } @@ -1074,7 +953,7 @@ void CommandInterpreter::executeTestOff(int processId, int result = _mgmtSrvr.stopSignalTracing(processId); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } } @@ -1127,7 +1006,7 @@ void CommandInterpreter::executeEventReporting(int processId, ndbout_c("processId %d", processId); int result = _mgmtSrvr.setEventReportingLevel(processId, logLevel); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } #endif } @@ -1137,7 +1016,7 @@ CommandInterpreter::executeStartBackup(char* parameters) { Uint32 backupId; int result = _mgmtSrvr.startBackup(backupId); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } else { // ndbout << "Start of backup ordered" << endl; } @@ -1154,7 +1033,7 @@ CommandInterpreter::executeAbortBackup(char* parameters) { } int result = _mgmtSrvr.abortBackup(bid); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } else { ndbout << "Abort of backup " << bid << " ordered" << endl; } @@ -1175,7 +1054,7 @@ CommandInterpreter::executeEnterSingleUser(char* parameters) { } int result = _mgmtSrvr.enterSingleUser(0, nodeId,0,0); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout << get_error_text(result) << endl; } else { ndbout << "Entering single user mode, granting access for node " << nodeId << " OK." << endl; diff --git a/ndb/src/mgmsrv/CommandInterpreter.hpp b/ndb/src/mgmsrv/CommandInterpreter.hpp index db23f76a5bd..74e5c2e95be 100644 --- a/ndb/src/mgmsrv/CommandInterpreter.hpp +++ b/ndb/src/mgmsrv/CommandInterpreter.hpp @@ -55,6 +55,9 @@ public: int readAndExecute(); private: + char m_err_str[1024]; + const char *get_error_text(int err_no); + /** * Read a string, and return a pointer to it. * @@ -122,7 +125,6 @@ private: void executeShow(char* parameters); void executeRun(char* parameters); void executeInfo(char* parameters); - void executeClusterLog(char* parameters); public: void executeStop(int processId, const char* parameters, bool all); diff --git a/ndb/src/mgmsrv/InitConfigFileParser.cpp b/ndb/src/mgmsrv/InitConfigFileParser.cpp index 01d5afae381..5cc5c3e9b32 100644 --- a/ndb/src/mgmsrv/InitConfigFileParser.cpp +++ b/ndb/src/mgmsrv/InitConfigFileParser.cpp @@ -214,48 +214,41 @@ InitConfigFileParser::parseConfig(FILE * file) { // Parse Name-Value Pair //**************************************************************************** -bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { - - char tmpLine[MAX_LINE_LENGTH]; - char fname[MAX_LINE_LENGTH], rest[MAX_LINE_LENGTH]; - char* t; - const char *separator_list[]= {":", "=", 0}; - const char *separator= 0; - +bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) +{ if (ctx.m_currentSection == NULL){ ctx.reportError("Value specified outside section"); return false; } - strncpy(tmpLine, line, MAX_LINE_LENGTH); - // ************************************* - // Check if a separator exists in line + // Split string at first occurrence of + // '=' or ':' // ************************************* - for(int i= 0; separator_list[i] != 0; i++) { - if(strchr(tmpLine, separator_list[i][0])) { - separator= separator_list[i]; - break; - } - } - if (separator == 0) { + Vector<BaseString> tmp_string_split; + if (BaseString(line).split(tmp_string_split, + BaseString("=:"), + 2) != 2) + { ctx.reportError("Parse error"); return false; } - // ******************************************* - // Get pointer to substring before separator - // ******************************************* - t = strtok(tmpLine, separator); - - // ***************************************** - // Count number of tokens before separator - // ***************************************** - if (sscanf(t, "%120s%120s", fname, rest) != 1) { - ctx.reportError("Multiple names before \'%c\'", separator[0]); - return false; + // ************************************* + // Remove leading and trailing chars + // ************************************* + { + for (int i = 0; i < 2; i++) + tmp_string_split[i].trim("\r\n \t"); } + + // ************************************* + // First in split is fname + // ************************************* + + const char *fname= tmp_string_split[0].c_str(); + if (!ctx.m_currentInfo->contains(fname)) { ctx.reportError("[%s] Unknown parameter: %s", ctx.fname, fname); return false; @@ -274,24 +267,11 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { } } - // ****************************************** - // Get pointer to substring after separator - // ****************************************** - t = strtok(NULL, "\0"); - if (t == NULL) { - ctx.reportError("No value for parameter"); - return false; - } - - // ****************************************** - // Remove prefix and postfix spaces and tabs - // ******************************************* - trim(t); - // *********************** // Store name-value pair // *********************** - return storeNameValuePair(ctx, fname, t); + + return storeNameValuePair(ctx, fname, tmp_string_split[1].c_str()); } diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 8306b4d92f1..713dff912bb 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -49,6 +49,8 @@ #include <NdbAutoPtr.hpp> +#include <ndberror.h> + #include <mgmapi.h> #include <mgmapi_configuration.hpp> #include <mgmapi_config_parameters.h> @@ -129,7 +131,7 @@ MgmtSrvr::signalRecvThreadRun() (this->*handler->function)(signal); } } -}; +} EventLogger g_EventLogger; @@ -152,7 +154,7 @@ MgmtSrvr::logLevelThreadRun() * Handle started nodes */ EventSubscribeReq req; - req = m_statisticsListner.m_clients[0].m_logLevel; + req = m_event_listner[0].m_logLevel; req.blockRef = _ownReference; SetLogLevelOrd ord; @@ -225,7 +227,8 @@ MgmtSrvr::startEventLog() clusterLog); } if(!g_EventLogger.addHandler(logdest)) { - ndbout << "Warning: could not add log destination \"" << logdest.c_str() << "\"" << endl; + ndbout << "Warning: could not add log destination \"" + << logdest.c_str() << "\"" << endl; } } @@ -243,18 +246,19 @@ public: }; bool -MgmtSrvr::setEventLogFilter(int severity) +MgmtSrvr::setEventLogFilter(int severity, int enable) { - bool enabled = true; Logger::LoggerLevel level = (Logger::LoggerLevel)severity; - if (g_EventLogger.isEnable(level)) { + if (enable > 0) { + g_EventLogger.enable(level); + } else if (enable == 0) { + g_EventLogger.disable(level); + } else if (g_EventLogger.isEnable(level)) { g_EventLogger.disable(level); - enabled = false; } else { g_EventLogger.enable(level); } - - return enabled; + return g_EventLogger.isEnable(level); } bool @@ -265,16 +269,6 @@ MgmtSrvr::isEventLogFilterEnabled(int severity) static ErrorItem errorTable[] = { - {200, "Backup undefined error"}, - {202, "Backup failed to allocate buffers (check configuration)"}, - {203, "Backup failed to setup fs buffers (check configuration)"}, - {204, "Backup failed to allocate tables (check configuration)"}, - {205, "Backup failed to insert file header (check configuration)"}, - {206, "Backup failed to insert table list (check configuration)"}, - {207, "Backup failed to allocate table memory (check configuration)"}, - {208, "Backup failed to allocate file record (check configuration)"}, - {209, "Backup failed to allocate attribute record (check configuration)"}, - {MgmtSrvr::NO_CONTACT_WITH_PROCESS, "No contact with the process (dead ?)."}, {MgmtSrvr::PROCESS_NOT_CONFIGURED, "The process is not configured."}, {MgmtSrvr::WRONG_PROCESS_TYPE, @@ -400,23 +394,29 @@ MgmtSrvr::getPort() const { } /* Constructor */ -MgmtSrvr::MgmtSrvr(NodeId nodeId, - SocketServer *socket_server, - const BaseString &configFilename, - LocalConfig &local_config, - Config * config): +int MgmtSrvr::init() +{ + if ( _ownNodeId > 0) + return 0; + return -1; +} + +MgmtSrvr::MgmtSrvr(SocketServer *socket_server, + const char *config_filename, + const char *connect_string) : _blockNumber(1), // Hard coded block number since it makes it easy to send // signals to other management servers. m_socket_server(socket_server), _ownReference(0), - m_local_config(local_config), theSignalIdleList(NULL), theWaitState(WAIT_SUBSCRIBE_CONF), - m_statisticsListner(this) + m_event_listner(this) { DBUG_ENTER("MgmtSrvr::MgmtSrvr"); + _ownNodeId= 0; + _config = NULL; _isStopThread = false; @@ -427,12 +427,48 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, theFacade = 0; m_newConfig = NULL; - m_configFilename = configFilename; + if (config_filename) + m_configFilename.assign(config_filename); + else + m_configFilename.assign("config.ini"); m_nextConfigGenerationNumber = 0; - _config = (config == 0 ? readConfig() : config); - + m_config_retriever= new ConfigRetriever(connect_string, + NDB_VERSION, NDB_MGM_NODE_TYPE_MGM); + // if connect_string explicitly given or + // no config filename is given then + // first try to allocate nodeid from another management server + if ((connect_string || config_filename == NULL) && + (m_config_retriever->do_connect(0,0,0) == 0)) + { + int tmp_nodeid= 0; + tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/); + if (tmp_nodeid == 0) + { + ndbout_c(m_config_retriever->getErrorString()); + exit(-1); + } + // read config from other managent server + _config= fetchConfig(); + if (_config == 0) + { + ndbout << m_config_retriever->getErrorString() << endl; + exit(-1); + } + _ownNodeId= tmp_nodeid; + } + + if (_ownNodeId == 0) + { + // read config locally + _config= readConfig(); + if (_config == 0) { + ndbout << "Unable to read config file" << endl; + exit(-1); + } + } + theMgmtWaitForResponseCondPtr = NdbCondition_Create(); m_configMutex = NdbMutex_Create(); @@ -444,9 +480,11 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, nodeTypes[i] = (enum ndb_mgm_node_type)-1; m_connect_address[i].s_addr= 0; } + { - ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator - (config->m_configValues, CFG_SECTION_NODE); + ndb_mgm_configuration_iterator + *iter = ndb_mgm_create_configuration_iterator(_config->m_configValues, + CFG_SECTION_NODE); for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)){ unsigned type, id; if(ndb_mgm_get_int_parameter(iter, CFG_TYPE_OF_SECTION, &type) != 0) @@ -479,8 +517,6 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, } _props = NULL; - _ownNodeId= 0; - NodeId tmp= nodeId; BaseString error_string; if ((m_node_id_mutex = NdbMutex_Create()) == 0) @@ -489,57 +525,41 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, exit(-1); } -#if 0 - char my_hostname[256]; - struct sockaddr_in tmp_addr; - SOCKET_SIZE_TYPE addrlen= sizeof(tmp_addr); - if (!g_no_nodeid_checks) { - if (gethostname(my_hostname, sizeof(my_hostname))) { - ndbout << "error: gethostname() - " << strerror(errno) << endl; - exit(-1); - } - if (Ndb_getInAddr(&(((sockaddr_in*)&tmp_addr)->sin_addr),my_hostname)) { - ndbout << "error: Ndb_getInAddr(" << my_hostname << ") - " - << strerror(errno) << endl; + if (_ownNodeId == 0) // we did not get node id from other server + { + NodeId tmp= m_config_retriever->get_configuration_nodeid(); + + if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, + 0, 0, error_string)){ + ndbout << "Unable to obtain requested nodeid: " + << error_string.c_str() << endl; exit(-1); } + _ownNodeId = tmp; } - if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, - (struct sockaddr *)&tmp_addr, - &addrlen, error_string)){ - ndbout << "Unable to obtain requested nodeid: " - << error_string.c_str() << endl; - exit(-1); - } -#else - if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, - 0, 0, error_string)){ - ndbout << "Unable to obtain requested nodeid: " - << error_string.c_str() << endl; - exit(-1); - } -#endif - _ownNodeId = tmp; { DBUG_PRINT("info", ("verifyConfig")); - ConfigRetriever cr(m_local_config, NDB_VERSION, NDB_MGM_NODE_TYPE_MGM); - if (!cr.verifyConfig(config->m_configValues, _ownNodeId)) { - ndbout << cr.getErrorString() << endl; + if (!m_config_retriever->verifyConfig(_config->m_configValues, + _ownNodeId)) + { + ndbout << m_config_retriever->getErrorString() << endl; exit(-1); } } + // Setup clusterlog as client[0] in m_event_listner { - MgmStatService::StatListener se; + Ndb_mgmd_event_service::Event_listener se; se.m_socket = NDB_INVALID_SOCKET; for(size_t t = 0; t<LogLevel::LOGLEVEL_CATEGORIES; t++){ se.m_logLevel.setLogLevel((LogLevel::EventCategory)t, 7); } se.m_logLevel.setLogLevel(LogLevel::llError, 15); + se.m_logLevel.setLogLevel(LogLevel::llConnection, 8); se.m_logLevel.setLogLevel(LogLevel::llBackup, 15); - m_statisticsListner.m_clients.push_back(se); - m_statisticsListner.m_logLevel = se.m_logLevel; + m_event_listner.m_clients.push_back(se); + m_event_listner.m_logLevel = se.m_logLevel; } DBUG_VOID_RETURN; @@ -658,6 +678,8 @@ MgmtSrvr::~MgmtSrvr() NdbThread_WaitFor(m_signalRecvThread, &res); NdbThread_Destroy(&m_signalRecvThread); } + if (m_config_retriever) + delete m_config_retriever; } //**************************************************************************** @@ -1831,18 +1853,21 @@ MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no) //**************************************************************************** //**************************************************************************** -const char* MgmtSrvr::getErrorText(int errorCode) +const char* MgmtSrvr::getErrorText(int errorCode, char *buf, int buf_sz) { - static char text[255]; for (int i = 0; i < noOfErrorCodes; ++i) { if (errorCode == errorTable[i]._errorCode) { - return errorTable[i]._errorText; + BaseString::snprintf(buf, buf_sz, errorTable[i]._errorText); + buf[buf_sz-1]= 0; + return buf; } } - - BaseString::snprintf(text, 255, "Unknown management server error code %d", errorCode); - return text; + + ndb_error_string(errorCode, buf, buf_sz); + buf[buf_sz-1]= 0; + + return buf; } void @@ -2049,21 +2074,18 @@ MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode) void MgmtSrvr::handleStatus(NodeId nodeId, bool alive) { + DBUG_ENTER("MgmtSrvr::handleStatus"); + Uint32 theData[25]; + theData[1] = nodeId; if (alive) { m_started_nodes.push_back(nodeId); - Uint32 theData[25]; theData[0] = EventReport::Connected; - theData[1] = nodeId; - eventReport(_ownNodeId, theData); } else { handleStopReply(nodeId, 0); - - Uint32 theData[25]; theData[0] = EventReport::Disconnected; - theData[1] = nodeId; - - eventReport(_ownNodeId, theData); } + eventReport(_ownNodeId, theData); + DBUG_VOID_RETURN; } //**************************************************************************** @@ -2084,8 +2106,11 @@ void MgmtSrvr::nodeStatusNotification(void* mgmSrv, Uint32 nodeId, bool alive, bool nfComplete) { + DBUG_ENTER("MgmtSrvr::nodeStatusNotification"); + DBUG_PRINT("enter",("nodeid= %d, alive= %d, nfComplete= %d", nodeId, alive, nfComplete)); if(!(!alive && nfComplete)) ((MgmtSrvr*)mgmSrv)->handleStatus(nodeId, alive); + DBUG_VOID_RETURN; } enum ndb_mgm_node_type @@ -2272,8 +2297,9 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, if (found_matching_type) if (found_free_node) error_string.appfmt("Connection done from wrong host ip %s.", - inet_ntoa(((struct sockaddr_in *) - (client_addr))->sin_addr)); + (client_addr)? + inet_ntoa(((struct sockaddr_in *) + (client_addr))->sin_addr):""); else error_string.appfmt("No free node id found for %s.", type_string.c_str()); @@ -2364,15 +2390,15 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData) EventReport::EventType type = eventReport->getEventType(); // Log event g_EventLogger.log(type, theData, nodeId, - &m_statisticsListner.m_clients[0].m_logLevel); - m_statisticsListner.log(type, theData, nodeId); + &m_event_listner[0].m_logLevel); + m_event_listner.log(type, theData, nodeId); } /*************************************************************************** * Backup ***************************************************************************/ int -MgmtSrvr::startBackup(Uint32& backupId, bool waitCompleted) +MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) { bool next; NodeId nodeId = 0; @@ -2394,11 +2420,16 @@ MgmtSrvr::startBackup(Uint32& backupId, bool waitCompleted) req->backupDataLen = 0; int result; - if (waitCompleted) { - result = sendRecSignal(nodeId, WAIT_BACKUP_COMPLETED, signal, true); + if (waitCompleted == 2) { + result = sendRecSignal(nodeId, WAIT_BACKUP_COMPLETED, + signal, true, 30*60*1000 /*30 secs*/); + } + else if (waitCompleted == 1) { + result = sendRecSignal(nodeId, WAIT_BACKUP_STARTED, + signal, true, 5*60*1000 /*5 mins*/); } else { - result = sendRecSignal(nodeId, WAIT_BACKUP_STARTED, signal, true); + result = sendRecSignal(nodeId, NO_WAIT, signal, true); } if (result == -1) { return SEND_OR_RECEIVE_FAILED; @@ -2477,18 +2508,31 @@ MgmtSrvr::abortBackup(Uint32 backupId) void MgmtSrvr::backupCallback(BackupEvent & event) { + DBUG_ENTER("MgmtSrvr::backupCallback"); m_lastBackupEvent = event; switch(event.Event){ case BackupEvent::BackupFailedToStart: + DBUG_PRINT("info",("BackupEvent::BackupFailedToStart")); + theWaitState = NO_WAIT; + break; case BackupEvent::BackupAborted: + DBUG_PRINT("info",("BackupEvent::BackupAborted")); + theWaitState = NO_WAIT; + break; case BackupEvent::BackupCompleted: + DBUG_PRINT("info",("BackupEvent::BackupCompleted")); theWaitState = NO_WAIT; break; case BackupEvent::BackupStarted: if(theWaitState == WAIT_BACKUP_STARTED) + { + DBUG_PRINT("info",("BackupEvent::BackupStarted NO_WAIT")); theWaitState = NO_WAIT; + } else { + DBUG_PRINT("info",("BackupEvent::BackupStarted")); + } } - return; + DBUG_VOID_RETURN; } @@ -2718,5 +2762,5 @@ template bool SignalQueue::waitFor<SigMatch>(Vector<SigMatch>&, SigMatch**, NdbA #endif template class MutexVector<unsigned short>; -template class MutexVector<MgmStatService::StatListener>; +template class MutexVector<Ndb_mgmd_event_service::Event_listener>; template class MutexVector<EventSubscribeReq>; diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index c70b6a0a90f..6378e763363 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -43,27 +43,34 @@ class Config; class SetLogLevelOrd; class SocketServer; -class MgmStatService : public EventLoggerBase +class Ndb_mgmd_event_service : public EventLoggerBase { friend class MgmtSrvr; public: - struct StatListener : public EventLoggerBase { + struct Event_listener : public EventLoggerBase { NDB_SOCKET_TYPE m_socket; }; private: class MgmtSrvr * m_mgmsrv; - MutexVector<StatListener> m_clients; + MutexVector<Event_listener> m_clients; public: - MgmStatService(class MgmtSrvr * m) : m_clients(5) { + Ndb_mgmd_event_service(class MgmtSrvr * m) : m_clients(5) { m_mgmsrv = m; } - void add_listener(const StatListener&); + void add_listener(const Event_listener&); + void update_max_log_level(const LogLevel&); + void update_log_level(const LogLevel&); void log(int eventType, const Uint32* theData, NodeId nodeId); - void stopSessions(); + void stop_sessions(); + + Event_listener& operator[](unsigned i) { return m_clients[i]; } + const Event_listener& operator[](unsigned i) const { return m_clients[i]; } + void lock() { m_clients.lock(); } + void unlock(){ m_clients.unlock(); } }; /** @@ -122,7 +129,7 @@ public: * @param serverity the log level/serverity. * @return true if the severity was enabled. */ - bool setEventLogFilter(int severity); + bool setEventLogFilter(int severity, int enable); /** * Returns true if the log level/severity is enabled. @@ -175,11 +182,10 @@ public: /* Constructor */ - MgmtSrvr(NodeId nodeId, /* Local nodeid */ - SocketServer *socket_server, - const BaseString &config_filename, /* Where to save config */ - LocalConfig &local_config, /* Ndb.cfg filename */ - Config * config); + MgmtSrvr(SocketServer *socket_server, + const char *config_filename, /* Where to save config */ + const char *connect_string); + int init(); NodeId getOwnNodeId() const {return _ownNodeId;}; /** @@ -358,7 +364,7 @@ public: /** * Backup functionallity */ - int startBackup(Uint32& backupId, bool waitCompleted = false); + int startBackup(Uint32& backupId, int waitCompleted= 2); int abortBackup(Uint32 backupId); int performBackup(Uint32* backupId); @@ -467,7 +473,7 @@ public: * @param errorCode: Error code to get a match error text for. * @return The error text. */ - const char* getErrorText(int errorCode); + const char* getErrorText(int errorCode, char *buf, int buf_sz); /** * Get configuration @@ -538,7 +544,6 @@ private: NdbMutex *m_configMutex; const Config * _config; Config * m_newConfig; - LocalConfig &m_local_config; BaseString m_configFilename; Uint32 m_nextConfigGenerationNumber; @@ -734,8 +739,8 @@ private: LogLevel m_nodeLogLevel[MAX_NODES]; enum ndb_mgm_node_type nodeTypes[MAX_NODES]; friend class MgmApiSession; - friend class MgmStatService; - MgmStatService m_statisticsListner; + friend class Ndb_mgmd_event_service; + Ndb_mgmd_event_service m_event_listner; /** * Handles the thread wich upon a 'Node is started' event will @@ -755,6 +760,9 @@ private: Config *_props; int send(class NdbApiSignal* signal, Uint32 node, Uint32 node_type); + + ConfigRetriever *m_config_retriever; + public: /** * This method does not exist diff --git a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp index 1d51061e909..6c4b4e9ae3c 100644 --- a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp +++ b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp @@ -272,30 +272,20 @@ MgmtSrvr::saveConfig(const Config *conf) { Config * MgmtSrvr::readConfig() { - Config *conf = NULL; - if(m_configFilename.length() != 0) { - /* Use config file */ - InitConfigFileParser parser; - conf = parser.parseConfig(m_configFilename.c_str()); - - if(conf == NULL) { - /* Try to get configuration from other MGM server */ - return fetchConfig(); - } - } + Config *conf; + InitConfigFileParser parser; + conf = parser.parseConfig(m_configFilename.c_str()); return conf; } Config * MgmtSrvr::fetchConfig() { - ConfigRetriever cr(m_local_config, NDB_VERSION, NODE_TYPE_MGM); - struct ndb_mgm_configuration * tmp = cr.getConfig(); + struct ndb_mgm_configuration * tmp = m_config_retriever->getConfig(); if(tmp != 0){ Config * conf = new Config(); conf->m_configValues = tmp; return conf; } - return 0; } diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index a4b5254dfee..8ba8c2fe87e 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -132,6 +132,7 @@ ParserRow<MgmApiSession> commands[] = { MGM_ARG("user", String, Mandatory, "Password"), MGM_ARG("password", String, Mandatory, "Password"), MGM_ARG("public key", String, Mandatory, "Public key"), + MGM_ARG("endian", String, Optional, "Endianness"), MGM_CMD("get version", &MgmApiSession::getVersion, ""), @@ -175,6 +176,7 @@ ParserRow<MgmApiSession> commands[] = { MGM_ARG("args", String, Mandatory, "Args(space separated int's)"), MGM_CMD("start backup", &MgmApiSession::startBackup, ""), + MGM_ARG("completed", Int, Optional ,"Wait until completed"), MGM_CMD("abort backup", &MgmApiSession::abortBackup, ""), MGM_ARG("id", Int, Mandatory, "Backup id"), @@ -207,16 +209,17 @@ ParserRow<MgmApiSession> commands[] = { MGM_CMD("set loglevel", &MgmApiSession::setLogLevel, ""), MGM_ARG("node", Int, Mandatory, "Node"), - MGM_ARG("category", String, Mandatory, "Event category"), + MGM_ARG("category", Int, Mandatory, "Event category"), MGM_ARG("level", Int, Mandatory, "Log level (0-15)"), MGM_CMD("set cluster loglevel", &MgmApiSession::setClusterLogLevel, ""), MGM_ARG("node", Int, Mandatory, "Node"), - MGM_ARG("category", String, Mandatory, "Event category"), + MGM_ARG("category", Int, Mandatory, "Event category"), MGM_ARG("level", Int, Mandatory, "Log level (0-15)"), MGM_CMD("set logfilter", &MgmApiSession::setLogFilter, ""), MGM_ARG("level", Int, Mandatory, "Severety level"), + MGM_ARG("enable", Int, Mandatory, "1=disable, 0=enable, -1=toggle"), MGM_CMD("config lock", &MgmApiSession::configLock, ""), @@ -244,6 +247,8 @@ ParserRow<MgmApiSession> commands[] = { MGM_CMD("purge stale sessions", &MgmApiSession::purge_stale_sessions, ""), + MGM_CMD("check connection", &MgmApiSession::check_connection, ""), + MGM_END() }; @@ -384,6 +389,8 @@ MgmApiSession::get_nodeid(Parser_t::Context &, const char * user; const char * password; const char * public_key; + const char * endian= NULL; + union { long l; char c[sizeof(long)]; } endian_check; args.get("version", &version); args.get("nodetype", &nodetype); @@ -392,7 +399,17 @@ MgmApiSession::get_nodeid(Parser_t::Context &, args.get("user", &user); args.get("password", &password); args.get("public key", &public_key); - + args.get("endian", &endian); + + endian_check.l = 1; + if(endian + && strcmp(endian,(endian_check.c[sizeof(long)-1])?"big":"little")!=0) { + m_output->println(cmd); + m_output->println("result: Node does not have the same endianness as the management server."); + m_output->println(""); + return; + } + bool compatible; switch (nodetype) { case NODE_TYPE_MGM: @@ -579,7 +596,7 @@ MgmApiSession::insertError(Parser<MgmApiSession>::Context &, m_output->println("insert error reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println(""); @@ -597,7 +614,7 @@ MgmApiSession::setTrace(Parser<MgmApiSession>::Context &, m_output->println("set trace reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println(""); @@ -613,85 +630,30 @@ MgmApiSession::getVersion(Parser<MgmApiSession>::Context &, m_output->println("string: %s", NDB_VERSION_STRING); m_output->println(""); } -#if 0 - -/***************************************************************************** - * BACKUP - *****************************************************************************/ - -int completed; -MgmtSrvr::BackupEvent globalEvent; - -static void -completedCallback(const MgmtSrvr::BackupEvent & event){ - - ndbout << "WaitCallback" << endl; - // Save event in the latestEvent var - - switch(event.Event){ - case MgmtSrvr::BackupEvent::BackupCompleted: - case MgmtSrvr::BackupEvent::BackupFailedToStart: - globalEvent = event; - completed = 1; - break; - } -} void MgmApiSession::startBackup(Parser<MgmApiSession>::Context &, - Properties const &) { + Properties const &args) { + DBUG_ENTER("MgmApiSession::startBackup"); unsigned backupId; + Uint32 completed= 2; int result; - MgmtSrvr::BackupCallback prevCallback; - prevCallback = m_mgmsrv.setCallback(completedCallback); - completed = 0; - result = m_mgmsrv.startBackup(backupId); - if (result == 0){ + args.get("completed", &completed); - // Wait for the callback to call our condition - // waitFor(); - while (completed == 0) - NdbSleep_SecSleep(0); - - if (globalEvent.Event == MgmtSrvr::BackupEvent::BackupFailedToStart) - result = globalEvent.FailedToStart.ErrorCode; - else - backupId = globalEvent.Completed.BackupId; - } - - // restore old callback - m_mgmsrv.setCallback(prevCallback); + result = m_mgmsrv.startBackup(backupId, completed); m_output->println("start backup reply"); if(result != 0) - m_output->println("result: %s(%d)", m_mgmsrv.getErrorText(result), result); - else{ - m_output->println("result: Ok"); - m_output->println("id: %d", backupId); + { + m_output->println("result: %s", get_error_text(result)); } - m_output->println(""); - -} -#endif - -void -MgmApiSession::startBackup(Parser<MgmApiSession>::Context &, - Properties const &) { - unsigned backupId; - int result; - - result = m_mgmsrv.startBackup(backupId, true); - - m_output->println("start backup reply"); - if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); else{ m_output->println("result: Ok"); m_output->println("id: %d", backupId); } m_output->println(""); - + DBUG_VOID_RETURN; } void @@ -705,7 +667,7 @@ MgmApiSession::abortBackup(Parser<MgmApiSession>::Context &, m_output->println("abort backup reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println(""); @@ -727,7 +689,7 @@ MgmApiSession::repCommand(Parser<MgmApiSession>::Context &, m_output->println("global replication reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else{ m_output->println("result: Ok"); m_output->println("id: %d", repReqId); @@ -749,7 +711,7 @@ MgmApiSession::dumpState(Parser<MgmApiSession>::Context &, int result = m_mgmsrv.dumpState(node, args_str.c_str()); m_output->println("dump state reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println(""); @@ -765,43 +727,62 @@ MgmApiSession::bye(Parser<MgmApiSession>::Context &, void MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &, Properties const &args) { - Uint32 node, level, category; + const char *reply= "set cluster loglevel reply"; + Uint32 node, level, cat; BaseString errorString; SetLogLevelOrd logLevel; int result; + DBUG_ENTER("MgmApiSession::setClusterLogLevel"); args.get("node", &node); - args.get("category", &category); + args.get("category", &cat); args.get("level", &level); + DBUG_PRINT("enter",("node=%d, category=%d, level=%d", node, cat, level)); + /* XXX should use constants for this value */ if(level > 15) { - m_output->println("set cluster loglevel reply"); - m_output->println("result: Invalid loglevel"); + m_output->println(reply); + m_output->println("result: Invalid loglevel %d", level); m_output->println(""); - return; + DBUG_VOID_RETURN; } - EventSubscribeReq req; - req.blockRef = 0; - req.noOfEntries = 1; - req.theData[0] = (category << 16) | level; - m_mgmsrv.m_log_level_requests.push_back(req); - - m_output->println("set cluster loglevel reply"); + LogLevel::EventCategory category= + (LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL); + + m_mgmsrv.m_event_listner.lock(); + if (m_mgmsrv.m_event_listner[0].m_logLevel.setLogLevel(category,level)) + { + m_output->println(reply); + m_output->println("result: Invalid category %d", category); + m_output->println(""); + m_mgmsrv.m_event_listner.unlock(); + DBUG_VOID_RETURN; + } + m_mgmsrv.m_event_listner.unlock(); + + { + LogLevel ll; + ll.setLogLevel(category,level); + m_mgmsrv.m_event_listner.update_max_log_level(ll); + } + + m_output->println(reply); m_output->println("result: Ok"); m_output->println(""); + DBUG_VOID_RETURN; } void MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &, Properties const &args) { - Uint32 node = 0, level = 0, category; + Uint32 node = 0, level = 0, cat; BaseString errorString; SetLogLevelOrd logLevel; int result; logLevel.clear(); args.get("node", &node); - args.get("category", &category); + args.get("category", &cat); args.get("level", &level); /* XXX should use constants for this value */ @@ -812,12 +793,15 @@ MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &, return; } - EventSubscribeReq req; - req.blockRef = node; - req.noOfEntries = 1; - req.theData[0] = (category << 16) | level; - m_mgmsrv.m_log_level_requests.push_back(req); - + LogLevel::EventCategory category= + (LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL); + + { + LogLevel ll; + ll.setLogLevel(category,level); + m_mgmsrv.m_event_listner.update_max_log_level(ll); + } + m_output->println("set loglevel reply"); m_output->println("result: Ok"); m_output->println(""); @@ -834,7 +818,7 @@ MgmApiSession::stopSignalLog(Parser<MgmApiSession>::Context &, m_output->println("stop signallog"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println(""); @@ -874,7 +858,7 @@ MgmApiSession::restart(Parser<MgmApiSession>::Context &, m_output->println("restart reply"); if(result != 0){ - m_output->println("result: %d-%s", result, m_mgmsrv.getErrorText(result)); + m_output->println("result: %d-%s", result, get_error_text(result)); } else m_output->println("result: Ok"); m_output->println("restarted: %d", restarted); @@ -898,7 +882,7 @@ MgmApiSession::restartAll(Parser<MgmApiSession>::Context &, m_output->println("restart reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println("restarted: %d", count); @@ -1029,7 +1013,7 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &, m_output->println("stop reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println("stopped: %d", stopped); @@ -1051,7 +1035,7 @@ MgmApiSession::stopAll(Parser<MgmApiSession>::Context &, m_output->println("stop reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println("stopped: %d", stopped); @@ -1067,7 +1051,7 @@ MgmApiSession::enterSingleUser(Parser<MgmApiSession>::Context &, int result = m_mgmsrv.enterSingleUser(&stopped, nodeId); m_output->println("enter single user reply"); if(result != 0) { - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); } else { m_output->println("result: Ok"); @@ -1082,7 +1066,7 @@ MgmApiSession::exitSingleUser(Parser<MgmApiSession>::Context &, int result = m_mgmsrv.exitSingleUser(&stopped, false); m_output->println("exit single user reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println(""); @@ -1100,7 +1084,7 @@ MgmApiSession::startSignalLog(Parser<MgmApiSession>::Context &, m_output->println("start signallog reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println(""); @@ -1145,7 +1129,7 @@ MgmApiSession::logSignals(Parser<MgmApiSession>::Context &, m_output->println("log signals reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println(""); @@ -1162,7 +1146,7 @@ MgmApiSession::start(Parser<MgmApiSession>::Context &, m_output->println("start reply"); if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); + m_output->println("result: %s", get_error_text(result)); else m_output->println("result: Ok"); m_output->println(""); @@ -1188,10 +1172,12 @@ void MgmApiSession::setLogFilter(Parser_t::Context &ctx, const class Properties &args) { Uint32 level; + Uint32 enable; args.get("level", &level); + args.get("enable", &enable); - int result = m_mgmsrv.setEventLogFilter(level); + int result = m_mgmsrv.setEventLogFilter(level, enable); m_output->println("set logfilter reply"); m_output->println("result: %d", result); @@ -1245,21 +1231,17 @@ operator<<(NdbOut& out, const LogLevel & ll) } void -MgmStatService::log(int eventType, const Uint32* theData, NodeId nodeId){ +Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId){ - Uint32 threshold = 0; - LogLevel::EventCategory cat= LogLevel::llInvalid; + Uint32 threshold; + LogLevel::EventCategory cat; + Logger::LoggerLevel severity; int i; + DBUG_ENTER("Ndb_mgmd_event_service::log"); + DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId)); - for(i = 0; (unsigned)i<EventLogger::matrixSize; i++){ - if(EventLogger::matrix[i].eventType == eventType){ - cat = EventLogger::matrix[i].eventCategory; - threshold = EventLogger::matrix[i].threshold; - break; - } - } - if (cat == LogLevel::llInvalid) - return; + if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity)) + DBUG_VOID_RETURN; char m_text[256]; EventLogger::getText(m_text, sizeof(m_text), eventType, theData, nodeId); @@ -1289,23 +1271,22 @@ MgmStatService::log(int eventType, const Uint32* theData, NodeId nodeId){ tmp.set_max(m_clients[i].m_logLevel); } m_clients.unlock(); - - if(!(tmp == m_logLevel)){ - m_logLevel = tmp; - EventSubscribeReq req; - req = tmp; - req.blockRef = 0; - m_mgmsrv->m_log_level_requests.push_back(req); - } + update_log_level(tmp); } + DBUG_VOID_RETURN; } void -MgmStatService::add_listener(const StatListener& client){ - m_clients.push_back(client); - LogLevel tmp = m_logLevel; - tmp.set_max(client.m_logLevel); - +Ndb_mgmd_event_service::update_max_log_level(const LogLevel &log_level) +{ + LogLevel tmp= m_logLevel; + tmp.set_max(log_level); + update_log_level(tmp); +} + +void +Ndb_mgmd_event_service::update_log_level(const LogLevel &tmp) +{ if(!(tmp == m_logLevel)){ m_logLevel = tmp; EventSubscribeReq req; @@ -1316,13 +1297,21 @@ MgmStatService::add_listener(const StatListener& client){ } void -MgmStatService::stopSessions(){ +Ndb_mgmd_event_service::add_listener(const Event_listener& client){ + m_clients.push_back(client); + update_max_log_level(client.m_logLevel); +} + +void +Ndb_mgmd_event_service::stop_sessions(){ + m_clients.lock(); for(int i = m_clients.size() - 1; i >= 0; i--){ if(m_clients[i].m_socket != NDB_INVALID_SOCKET){ NDB_CLOSE_SOCKET(m_clients[i].m_socket); m_clients.erase(i); } } + m_clients.unlock(); } void @@ -1356,7 +1345,7 @@ MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx, int result = 0; BaseString msg; - MgmStatService::StatListener le; + Ndb_mgmd_event_service::Event_listener le; le.m_socket = m_socket; Vector<BaseString> list; @@ -1401,7 +1390,7 @@ MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx, goto done; } - m_mgmsrv.m_statisticsListner.add_listener(le); + m_mgmsrv.m_event_listner.add_listener(le); m_stop = true; m_socket = NDB_INVALID_SOCKET; @@ -1454,6 +1443,15 @@ MgmApiSession::purge_stale_sessions(Parser_t::Context &ctx, m_output->println(""); } +void +MgmApiSession::check_connection(Parser_t::Context &ctx, + const class Properties &args) +{ + m_output->println("check connection reply"); + m_output->println("result: Ok"); + m_output->println(""); +} + template class MutexVector<int>; template class Vector<ParserRow<MgmApiSession> const*>; template class Vector<unsigned short>; diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp index 14abab2a486..8627343b1cf 100644 --- a/ndb/src/mgmsrv/Services.hpp +++ b/ndb/src/mgmsrv/Services.hpp @@ -39,10 +39,13 @@ private: OutputStream *m_output; Parser_t *m_parser; MgmtSrvr::Allocated_resources *m_allocated_resources; + char m_err_str[1024]; void getConfig_common(Parser_t::Context &ctx, const class Properties &args, bool compat = false); + const char *get_error_text(int err_no) + { return m_mgmsrv.getErrorText(err_no, m_err_str, sizeof(m_err_str)); } public: MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock); @@ -88,6 +91,7 @@ public: void listen_event(Parser_t::Context &ctx, const class Properties &args); void purge_stale_sessions(Parser_t::Context &ctx, const class Properties &args); + void check_connection(Parser_t::Context &ctx, const class Properties &args); void repCommand(Parser_t::Context &ctx, const class Properties &args); }; diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index 1c3b838ef5f..992e827ceaa 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -62,7 +62,6 @@ struct MgmGlobals { int non_interactive; int interactive; const char * config_filename; - const char * local_config_filename; /** Stuff found in environment or in local config */ NodeId localNodeId; @@ -70,9 +69,6 @@ struct MgmGlobals { char * interface_name; int port; - /** The configuration of the cluster */ - Config * cluster_config; - /** The Mgmt Server */ MgmtSrvr * mgmObject; @@ -86,9 +82,6 @@ static MgmGlobals glob; /****************************************************************************** * Function prototypes ******************************************************************************/ -static bool readLocalConfig(); -static bool readGlobalConfig(); - /** * Global variables */ @@ -110,10 +103,14 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, { "version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, - { "connect-string", 1023, + { "ndb-connectstring", 1023, "Set connect string for connecting to ndb_mgmd. " - "<constr>=\"host=<hostname:port>[;nodeid=<id>]\". " - "Overides specifying entries in NDB_CONNECTSTRING and config file", + "Syntax: \"[nodeid=<id>;][host=]<hostname>[:<port>]\". " + "Overides specifying entries in NDB_CONNECTSTRING and Ndb.cfg", + (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + { "connect-string", 1023, + "same as --ndb-connectstring.", (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, { "config-file", 'f', "Specify cluster configuration file", @@ -122,9 +119,6 @@ static struct my_option my_long_options[] = { "daemon", 'd', "Run ndb_mgmd in daemon mode (default)", (gptr*) &glob.daemon, (gptr*) &glob.daemon, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 }, - { "l", 'l', "Specify configuration file connect string (default Ndb.cfg if available)", - (gptr*) &glob.local_config_filename, (gptr*) &glob.local_config_filename, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, { "interactive", 256, "Run interactive. Not supported but provided for testing purposes", (gptr*) &glob.interactive, (gptr*) &glob.interactive, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, @@ -194,9 +188,8 @@ int main(int argc, char** argv) #endif global_mgmt_server_check = 1; - glob.config_filename= "config.ini"; - const char *load_default_groups[]= { "ndb_mgmd",0 }; + const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; @@ -212,29 +205,16 @@ int main(int argc, char** argv) MgmApiService * mapi = new MgmApiService(); - /**************************** - * Read configuration files * - ****************************/ - LocalConfig local_config; - if(!local_config.init(opt_connect_str,glob.local_config_filename)){ - local_config.printError(); - goto error_end; - } - glob.localNodeId = local_config._ownNodeId; + glob.mgmObject = new MgmtSrvr(glob.socketServer, + glob.config_filename, + opt_connect_str); - if (!readGlobalConfig()) + if (glob.mgmObject->init()) goto error_end; - glob.mgmObject = new MgmtSrvr(glob.localNodeId, glob.socketServer, - BaseString(glob.config_filename), - local_config, - glob.cluster_config); - my_setwd(NdbConfig_get_path(0), MYF(0)); - glob.cluster_config = 0; glob.localNodeId= glob.mgmObject->getOwnNodeId(); - if (glob.localNodeId == 0) { goto error_end; } @@ -347,9 +327,7 @@ MgmGlobals::MgmGlobals(){ // Default values port = 0; config_filename = NULL; - local_config_filename = NULL; interface_name = 0; - cluster_config = 0; daemon = 1; non_interactive = 0; interactive = 0; @@ -362,27 +340,6 @@ MgmGlobals::~MgmGlobals(){ delete socketServer; if (mgmObject) delete mgmObject; - if (cluster_config) - delete cluster_config; if (interface_name) free(interface_name); } - -/** - * @fn readGlobalConfig - * @param glob : Global variables - * @return true if success, false otherwise. - */ -static bool -readGlobalConfig() { - if(glob.config_filename == NULL) - return false; - - /* Use config file */ - InitConfigFileParser parser; - glob.cluster_config = parser.parseConfig(glob.config_filename); - if(glob.cluster_config == 0){ - return false; - } - return true; -} diff --git a/ndb/src/ndbapi/DictCache.cpp b/ndb/src/ndbapi/DictCache.cpp index 12300ce216f..afdb37aa53f 100644 --- a/ndb/src/ndbapi/DictCache.cpp +++ b/ndb/src/ndbapi/DictCache.cpp @@ -24,10 +24,12 @@ Ndb_local_table_info * Ndb_local_table_info::create(NdbTableImpl *table_impl, Uint32 sz) { - void *data= malloc(sizeof(NdbTableImpl)+sz-1); + if (sz % 8 != 0) // round to Uint64 + sz += 8 - sz % 8; + void *data= malloc(sizeof(NdbTableImpl)+sz-8); if (data == 0) return 0; - memset(data,0,sizeof(NdbTableImpl)+sz-1); + memset(data,0,sizeof(NdbTableImpl)+sz-8); new (data) Ndb_local_table_info(table_impl); return (Ndb_local_table_info *) data; } diff --git a/ndb/src/ndbapi/DictCache.hpp b/ndb/src/ndbapi/DictCache.hpp index 0dc853306fa..a517acee56b 100644 --- a/ndb/src/ndbapi/DictCache.hpp +++ b/ndb/src/ndbapi/DictCache.hpp @@ -32,7 +32,7 @@ public: static Ndb_local_table_info *create(NdbTableImpl *table_impl, Uint32 sz=0); static void destroy(Ndb_local_table_info *); NdbTableImpl *m_table_impl; - char m_local_data[1]; + Uint64 m_local_data[1]; private: Ndb_local_table_info(NdbTableImpl *table_impl); ~Ndb_local_table_info(); diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index bd642ef3fd7..0836dc46fed 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -55,6 +55,7 @@ NdbConnection::NdbConnection( Ndb* aNdb ) : theFirstExecOpInList(NULL), theLastExecOpInList(NULL), theCompletedFirstOp(NULL), + theCompletedLastOp(NULL), theNoOfOpSent(0), theNoOfOpCompleted(0), theNoOfOpFetched(0), @@ -124,6 +125,7 @@ NdbConnection::init() theLastExecOpInList = NULL; theCompletedFirstOp = NULL; + theCompletedLastOp = NULL; theGlobalCheckpointId = 0; theCommitStatus = Started; @@ -256,6 +258,8 @@ NdbConnection::handleExecuteCompletion() if (tLastExecOp != NULL) { tLastExecOp->next(theCompletedFirstOp); theCompletedFirstOp = tFirstExecOp; + if (theCompletedLastOp == NULL) + theCompletedLastOp = tLastExecOp; theFirstExecOpInList = NULL; theLastExecOpInList = NULL; }//if @@ -292,6 +296,8 @@ NdbConnection::execute(ExecType aTypeOfExec, ExecType tExecType; NdbOperation* tPrepOp; + NdbOperation* tCompletedFirstOp = NULL; + NdbOperation* tCompletedLastOp = NULL; int ret = 0; do { @@ -314,6 +320,7 @@ NdbConnection::execute(ExecType aTypeOfExec, } tPrepOp = tPrepOp->next(); } + // save rest of prepared ops if batch NdbOperation* tRestOp= 0; NdbOperation* tLastOp= 0; @@ -323,6 +330,7 @@ NdbConnection::execute(ExecType aTypeOfExec, tLastOp = theLastOpInList; theLastOpInList = tPrepOp; } + if (tExecType == Commit) { NdbOperation* tOp = theCompletedFirstOp; while (tOp != NULL) { @@ -338,6 +346,19 @@ NdbConnection::execute(ExecType aTypeOfExec, } } + // completed ops are in unspecified order + if (theCompletedFirstOp != NULL) { + if (tCompletedFirstOp == NULL) { + tCompletedFirstOp = theCompletedFirstOp; + tCompletedLastOp = theCompletedLastOp; + } else { + tCompletedLastOp->next(theCompletedFirstOp); + tCompletedLastOp = theCompletedLastOp; + } + theCompletedFirstOp = NULL; + theCompletedLastOp = NULL; + } + if (executeNoBlobs(tExecType, abortOption, forceSend) == -1) ret = -1; #ifndef VM_TRACE @@ -362,6 +383,7 @@ NdbConnection::execute(ExecType aTypeOfExec, tOp = tOp->next(); } } + // add saved prepared ops if batch if (tPrepOp != NULL && tRestOp != NULL) { if (theFirstOpInList == NULL) @@ -373,6 +395,18 @@ NdbConnection::execute(ExecType aTypeOfExec, assert(theFirstOpInList == NULL || tExecType == NoCommit); } while (theFirstOpInList != NULL || tExecType != aTypeOfExec); + if (tCompletedFirstOp != NULL) { + tCompletedLastOp->next(theCompletedFirstOp); + theCompletedFirstOp = tCompletedFirstOp; + if (theCompletedLastOp == NULL) + theCompletedLastOp = tCompletedLastOp; + } +#if ndb_api_count_completed_ops_after_blob_execute + { NdbOperation* tOp; unsigned n = 0; + for (tOp = theCompletedFirstOp; tOp != NULL; tOp = tOp->next()) n++; + ndbout << "completed ops: " << n << endl; + } +#endif DBUG_RETURN(ret); } @@ -894,6 +928,7 @@ NdbConnection::releaseOperations() releaseOps(theFirstExecOpInList); theCompletedFirstOp = NULL; + theCompletedLastOp = NULL; theFirstOpInList = NULL; theFirstExecOpInList = NULL; theLastOpInList = NULL; @@ -909,6 +944,7 @@ NdbConnection::releaseCompletedOperations() { releaseOps(theCompletedFirstOp); theCompletedFirstOp = NULL; + theCompletedLastOp = NULL; }//NdbConnection::releaseOperations() /****************************************************************************** diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp index 09d15c7f962..f88bbc907a6 100644 --- a/ndb/src/ndbapi/NdbDictionary.cpp +++ b/ndb/src/ndbapi/NdbDictionary.cpp @@ -773,14 +773,6 @@ NdbDictionary::Dictionary::removeCachedTable(const char * name){ m_impl.removeCachedObject(* t); } -NdbDictionary::Table -NdbDictionary::Dictionary::getTableForAlteration(const char * name){ - const NdbDictionary::Table * oldTable = getTable(name); - return (oldTable) ? - NdbDictionary::Table(*oldTable) - : NdbDictionary::Table(); -} - int NdbDictionary::Dictionary::createIndex(const Index & ind) { diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 304d1b904d4..5319e678441 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -1411,15 +1411,14 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl) const char * originalInternalName = internalName.c_str(); BaseString externalName = impl.m_externalName; const char * originalExternalName = externalName.c_str(); - NdbTableImpl * oldTab = getTable(originalExternalName); - - if(!oldTab){ + + DBUG_ENTER("NdbDictionaryImpl::alterTable"); + if(!get_local_table_info(originalInternalName, false)){ m_error.code = 709; - return -1; + DBUG_RETURN(-1); } // Alter the table int ret = m_receiver.alterTable(m_ndb, impl); - if(ret == 0){ // Remove cached information and let it be refreshed at next access if (m_localHash.get(originalInternalName) != NULL) { @@ -1433,7 +1432,7 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl) m_globalHash->unlock(); } } - return ret; + DBUG_RETURN(ret); } int @@ -1448,15 +1447,16 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, NdbTableImpl & impl, bool alter) { + DBUG_ENTER("NdbDictInterface::createOrAlterTable"); unsigned i; if((unsigned)impl.getNoOfPrimaryKeys() > NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY){ m_error.code = 4317; - return -1; + DBUG_RETURN(-1); } unsigned sz = impl.m_columns.size(); if (sz > NDB_MAX_ATTRIBUTES_IN_TABLE){ m_error.code = 4318; - return -1; + DBUG_RETURN(-1); } impl.copyNewProperties(); @@ -1491,7 +1491,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, // Check max length of frm data if (impl.m_frm.length() > MAX_FRM_DATA_SIZE){ m_error.code = 1229; - return -1; + DBUG_RETURN(-1); } tmpTab.FrmLen = impl.m_frm.length(); memcpy(tmpTab.FrmData, impl.m_frm.get_data(), impl.m_frm.length()); @@ -1543,12 +1543,12 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, // charset is defined exactly for char types if (col->getCharType() != (col->m_cs != NULL)) { m_error.code = 703; - return -1; + DBUG_RETURN(-1); } // primary key type check if (col->m_pk && ! NdbSqlUtil::usable_in_pk(col->m_type, col->m_cs)) { m_error.code = 743; - return -1; + DBUG_RETURN(-1); } // charset in upper half of precision if (col->getCharType()) { @@ -1571,7 +1571,13 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, NdbApiSignal tSignal(m_reference); tSignal.theReceiversBlockNumber = DBDICT; - if (alter) { + + LinearSectionPtr ptr[3]; + ptr[0].p = (Uint32*)m_buffer.get_data(); + ptr[0].sz = m_buffer.length() / 4; + int ret; + if (alter) + { AlterTableReq * const req = CAST_PTR(AlterTableReq, tSignal.getDataPtrSend()); @@ -1582,8 +1588,10 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, req->tableVersion = impl.m_version;; tSignal.theVerId_signalNumber = GSN_ALTER_TABLE_REQ; tSignal.theLength = AlterTableReq::SignalLength; + ret= alterTable(&tSignal, ptr); } - else { + else + { CreateTableReq * const req = CAST_PTR(CreateTableReq, tSignal.getDataPtrSend()); @@ -1591,28 +1599,24 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, req->senderData = 0; tSignal.theVerId_signalNumber = GSN_CREATE_TABLE_REQ; tSignal.theLength = CreateTableReq::SignalLength; - } - - LinearSectionPtr ptr[3]; - ptr[0].p = (Uint32*)m_buffer.get_data(); - ptr[0].sz = m_buffer.length() / 4; - - int ret = (alter) ? - alterTable(&tSignal, ptr) - : createTable(&tSignal, ptr); - - if (!alter && haveAutoIncrement) { - if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(), - autoIncrementValue)) { - if (ndb.theError.code == 0) { - m_error.code = 4336; - ndb.theError = m_error; - } else - m_error= ndb.theError; - ret = -1; // errorcode set in initialize_autoincrement + ret= createTable(&tSignal, ptr); + + if (ret) + return ret; + + if (haveAutoIncrement) { + if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(), + autoIncrementValue)) { + if (ndb.theError.code == 0) { + m_error.code = 4336; + ndb.theError = m_error; + } else + m_error= ndb.theError; + ret = -1; // errorcode set in initialize_autoincrement + } } } - return ret; + DBUG_RETURN(ret); } int @@ -1671,17 +1675,17 @@ NdbDictInterface::alterTable(NdbApiSignal* signal, LinearSectionPtr ptr[3]) int errCodes[noErrCodes] = {AlterTableRef::NotMaster, AlterTableRef::Busy}; - int r = dictSignal(signal,ptr,1, - 1/*use masternode id*/, - 100,WAIT_ALTER_TAB_REQ, - WAITFOR_RESPONSE_TIMEOUT, - errCodes, noErrCodes); - if(m_error.code == AlterTableRef::InvalidTableVersion) { - // Clear caches and try again - return INCOMPATIBLE_VERSION; - } - - return r; + int r = dictSignal(signal,ptr,1, + 1/*use masternode id*/, + 100,WAIT_ALTER_TAB_REQ, + WAITFOR_RESPONSE_TIMEOUT, + errCodes, noErrCodes); + if(m_error.code == AlterTableRef::InvalidTableVersion) { + // Clear caches and try again + return INCOMPATIBLE_VERSION; + } + + return r; } void diff --git a/ndb/src/ndbapi/NdbEventOperation.cpp b/ndb/src/ndbapi/NdbEventOperation.cpp index 506a6c8d86d..d209293f8b0 100644 --- a/ndb/src/ndbapi/NdbEventOperation.cpp +++ b/ndb/src/ndbapi/NdbEventOperation.cpp @@ -121,5 +121,5 @@ NdbEventOperation::wait(void *p, int aMillisecondNumber) } NdbEventOperation::NdbEventOperation(NdbEventOperationImpl& impl) - : m_impl(impl) {}; + : m_impl(impl) {} diff --git a/ndb/src/ndbapi/NdbResultSet.cpp b/ndb/src/ndbapi/NdbResultSet.cpp index f270584d227..d9d71464026 100644 --- a/ndb/src/ndbapi/NdbResultSet.cpp +++ b/ndb/src/ndbapi/NdbResultSet.cpp @@ -44,10 +44,10 @@ void NdbResultSet::init() { } -int NdbResultSet::nextResult(bool fetchAllowed) +int NdbResultSet::nextResult(bool fetchAllowed, bool forceSend) { int res; - if ((res = m_operation->nextResult(fetchAllowed)) == 0) { + if ((res = m_operation->nextResult(fetchAllowed, forceSend)) == 0) { // handle blobs NdbBlob* tBlob = m_operation->theBlobList; while (tBlob != 0) { @@ -67,9 +67,9 @@ int NdbResultSet::nextResult(bool fetchAllowed) return res; } -void NdbResultSet::close() +void NdbResultSet::close(bool forceSend) { - m_operation->closeScan(); + m_operation->closeScan(forceSend); } NdbOperation* @@ -98,6 +98,6 @@ NdbResultSet::deleteTuple(NdbConnection * takeOverTrans){ } int -NdbResultSet::restart(){ - return m_operation->restart(); +NdbResultSet::restart(bool forceSend){ + return m_operation->restart(forceSend); } diff --git a/ndb/src/ndbapi/NdbScanFilter.cpp b/ndb/src/ndbapi/NdbScanFilter.cpp index 38b1c70c047..0c851427ba5 100644 --- a/ndb/src/ndbapi/NdbScanFilter.cpp +++ b/ndb/src/ndbapi/NdbScanFilter.cpp @@ -397,7 +397,7 @@ NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, (m_operation->* branch)(4, 5, m_current.m_ownLabel); return 0; -}; +} int NdbScanFilter::eq(int AttrId, Uint32 value){ @@ -478,7 +478,7 @@ NdbScanFilterImpl::cond_col(Interpreter::UnaryCondition op, Uint32 AttrId){ Branch1 branch = table2[op].m_branches[m_current.m_group]; (m_operation->* branch)(AttrId, m_current.m_ownLabel); return 0; -}; +} int NdbScanFilter::isnull(int AttrId){ diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 6eb5167e385..88208409c08 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -453,10 +453,12 @@ NdbScanOperation::executeCursor(int nodeId){ return -1; } -int NdbScanOperation::nextResult(bool fetchAllowed) + +int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend) { if(m_ordered) - return ((NdbIndexScanOperation*)this)->next_result_ordered(fetchAllowed); + return ((NdbIndexScanOperation*)this)->next_result_ordered(fetchAllowed, + forceSend); /** * Check current receiver @@ -496,7 +498,8 @@ int NdbScanOperation::nextResult(bool fetchAllowed) return -1; Uint32 seq = theNdbCon->theNodeSequence; - if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false) == 0){ + if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false, + forceSend) == 0){ idx = m_current_api_receiver; last = m_api_receivers_count; @@ -587,9 +590,9 @@ int NdbScanOperation::nextResult(bool fetchAllowed) } int -NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){ - if(cnt > 0) - { +NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag, + bool forceSend){ + if(cnt > 0){ NdbApiSignal tSignal(theNdb->theMyRef); tSignal.setSignal(GSN_SCAN_NEXTREQ); @@ -636,6 +639,8 @@ NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){ } } + if (!ret) checkForceSend(forceSend); + m_sent_receivers_count = last + sent; m_api_receivers_count -= cnt; m_current_api_receiver = 0; @@ -645,6 +650,15 @@ NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){ return 0; } +void NdbScanOperation::checkForceSend(bool forceSend) +{ + if (forceSend) { + TransporterFacade::instance()->forceSend(theNdb->theNdbBlockNumber); + } else { + TransporterFacade::instance()->checkForceSend(theNdb->theNdbBlockNumber); + }//if +} + int NdbScanOperation::prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId) { @@ -660,7 +674,7 @@ NdbScanOperation::doSend(int ProcessorId) return 0; } -void NdbScanOperation::closeScan() +void NdbScanOperation::closeScan(bool forceSend) { if(m_transConnection){ if(DEBUG_NEXT_RESULT) @@ -675,7 +689,7 @@ void NdbScanOperation::closeScan() TransporterFacade* tp = TransporterFacade::instance(); Guard guard(tp->theMutexPtr); - close_impl(tp); + close_impl(tp, forceSend); } while(0); @@ -1310,7 +1324,8 @@ NdbIndexScanOperation::compare(Uint32 skip, Uint32 cols, } int -NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){ +NdbIndexScanOperation::next_result_ordered(bool fetchAllowed, + bool forceSend){ Uint32 u_idx = 0, u_last = 0; Uint32 s_idx = m_current_api_receiver; // first sorted @@ -1338,7 +1353,8 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){ return -1; Uint32 seq = theNdbCon->theNodeSequence; Uint32 nodeId = theNdbCon->theDBnode; - if(seq == tp->getNodeSequence(nodeId) && !send_next_scan_ordered(s_idx)){ + if(seq == tp->getNodeSequence(nodeId) && + !send_next_scan_ordered(s_idx, forceSend)){ Uint32 tmp = m_sent_receivers_count; s_idx = m_current_api_receiver; while(m_sent_receivers_count > 0 && !theError.code){ @@ -1432,7 +1448,7 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){ } int -NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx){ +NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx, bool forceSend){ if(idx == theParallelism) return 0; @@ -1469,11 +1485,13 @@ NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx){ Uint32 nodeId = theNdbCon->theDBnode; TransporterFacade * tp = TransporterFacade::instance(); tSignal.setLength(4+1); - return tp->sendSignal(&tSignal, nodeId); + int ret= tp->sendSignal(&tSignal, nodeId); + if (!ret) checkForceSend(forceSend); + return ret; } int -NdbScanOperation::close_impl(TransporterFacade* tp){ +NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){ Uint32 seq = theNdbCon->theNodeSequence; Uint32 nodeId = theNdbCon->theDBnode; @@ -1547,7 +1565,7 @@ NdbScanOperation::close_impl(TransporterFacade* tp){ } // Send close scan - if(send_next_scan(api+conf, true) == -1) + if(send_next_scan(api+conf, true, forceSend) == -1) { theNdbCon->theReleaseOnClose = true; return -1; @@ -1596,7 +1614,7 @@ NdbScanOperation::reset_receivers(Uint32 parallell, Uint32 ordered){ } int -NdbScanOperation::restart() +NdbScanOperation::restart(bool forceSend) { TransporterFacade* tp = TransporterFacade::instance(); @@ -1605,7 +1623,7 @@ NdbScanOperation::restart() { int res; - if((res= close_impl(tp))) + if((res= close_impl(tp, forceSend))) { return res; } @@ -1624,13 +1642,13 @@ NdbScanOperation::restart() } int -NdbIndexScanOperation::reset_bounds(){ +NdbIndexScanOperation::reset_bounds(bool forceSend){ int res; { TransporterFacade* tp = TransporterFacade::instance(); Guard guard(tp->theMutexPtr); - res= close_impl(tp); + res= close_impl(tp, forceSend); } if(!res) diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp index 698bbcde4c6..48e62c36a5f 100644 --- a/ndb/src/ndbapi/Ndbinit.cpp +++ b/ndb/src/ndbapi/Ndbinit.cpp @@ -58,7 +58,7 @@ Ndb::Ndb( const char* aDataBase , const char* aSchema) { theNoOfNdbObjects++; if (global_ndb_cluster_connection == 0) { global_ndb_cluster_connection= new Ndb_cluster_connection(ndbConnectString); - global_ndb_cluster_connection->connect(); + global_ndb_cluster_connection->connect(12,5,1); } setup(global_ndb_cluster_connection, aDataBase, aSchema); DBUG_VOID_RETURN; diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp index dfb090c8416..031ee6315e8 100644 --- a/ndb/src/ndbapi/TransporterFacade.cpp +++ b/ndb/src/ndbapi/TransporterFacade.cpp @@ -626,6 +626,9 @@ TransporterFacade::ReportNodeFailureComplete(NodeId tNodeId) * After the restart the node is up again and the Ndb object * might not have noticed the failure. */ + + DBUG_ENTER("TransporterFacade::ReportNodeFailureComplete"); + DBUG_PRINT("enter",("nodeid= %d", tNodeId)); Uint32 sz = m_threads.m_statusNext.size(); for (Uint32 i = 0; i < sz ; i ++) { if (m_threads.getInUse(i)){ @@ -634,6 +637,7 @@ TransporterFacade::ReportNodeFailureComplete(NodeId tNodeId) (*RegPC) (obj, tNodeId, false, true); } } + DBUG_VOID_RETURN; } void diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index 4c42fe1aeef..f436ee56ede 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -40,12 +40,8 @@ Ndb_cluster_connection::Ndb_cluster_connection(const char *connect_string) DBUG_ENTER("Ndb_cluster_connection"); DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%x", this)); m_facade= TransporterFacade::theFacadeInstance= new TransporterFacade(); - if (connect_string) - m_connect_string= my_strdup(connect_string,MYF(MY_WME)); - else - m_connect_string= 0; + m_config_retriever= 0; - m_local_config= 0; m_connect_thread= 0; m_connect_callback= 0; @@ -59,9 +55,39 @@ Ndb_cluster_connection::Ndb_cluster_connection(const char *connect_string) ndb_print_state_mutex= NdbMutex_Create(); } #endif + m_config_retriever= + new ConfigRetriever(connect_string, NDB_VERSION, NODE_TYPE_API); + if (m_config_retriever->hasError()) + { + printf("Could not connect initialize handle to management server: %s", + m_config_retriever->getErrorString()); + delete m_config_retriever; + m_config_retriever= 0; + } DBUG_VOID_RETURN; } +int Ndb_cluster_connection::get_connected_port() const +{ + if (m_config_retriever) + return m_config_retriever->get_mgmd_port(); + return -1; +} + +const char *Ndb_cluster_connection::get_connected_host() const +{ + if (m_config_retriever) + return m_config_retriever->get_mgmd_host(); + return 0; +} + +const char *Ndb_cluster_connection::get_connectstring(char *buf, int buf_sz) const +{ + if (m_config_retriever) + return m_config_retriever->get_connectstring(buf,buf_sz); + return 0; +} + extern "C" pthread_handler_decl(run_ndb_cluster_connection_connect_thread, me) { my_thread_init(); @@ -78,7 +104,7 @@ void Ndb_cluster_connection::connect_thread() int r; do { NdbSleep_SecSleep(1); - if ((r = connect(1)) == 0) + if ((r = connect(0,0,0)) == 0) break; if (r == -1) { printf("Ndb_cluster_connection::connect_thread error\n"); @@ -99,7 +125,7 @@ int Ndb_cluster_connection::start_connect_thread(int (*connect_callback)(void)) int r; DBUG_ENTER("Ndb_cluster_connection::start_connect_thread"); m_connect_callback= connect_callback; - if ((r = connect(1)) == 1) + if ((r = connect(0,0,0)) == 1) { DBUG_PRINT("info",("starting thread")); m_connect_thread= @@ -118,45 +144,17 @@ int Ndb_cluster_connection::start_connect_thread(int (*connect_callback)(void)) DBUG_RETURN(0); } -int Ndb_cluster_connection::connect(int reconnect) +int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds, int verbose) { DBUG_ENTER("Ndb_cluster_connection::connect"); const char* error = 0; do { if (m_config_retriever == 0) - { - if (m_local_config == 0) { - m_local_config= new LocalConfig(); - if (!m_local_config->init(m_connect_string,0)) { - ndbout_c("Configuration error: Unable to retrieve local config"); - m_local_config->printError(); - m_local_config->printUsage(); - DBUG_RETURN(-1); - } - } - m_config_retriever= - new ConfigRetriever(*m_local_config, NDB_VERSION, NODE_TYPE_API); - } - else - if (reconnect == 0) - DBUG_RETURN(0); - if (reconnect) - { - int r= m_config_retriever->do_connect(1); - if (r == 1) - DBUG_RETURN(1); // mgmt server not up yet - if (r == -1) - break; - } - else - if(m_config_retriever->do_connect() == -1) - break; - - Uint32 nodeId = m_config_retriever->allocNodeId(); - for(Uint32 i = 0; nodeId == 0 && i<5; i++){ - NdbSleep_SecSleep(3); - nodeId = m_config_retriever->allocNodeId(); - } + DBUG_RETURN(-1); + if (m_config_retriever->do_connect(no_retries,retry_delay_in_seconds,verbose)) + DBUG_RETURN(1); // mgmt server not up yet + + Uint32 nodeId = m_config_retriever->allocNodeId(4/*retries*/,3/*delay*/); if(nodeId == 0) break; ndb_mgm_configuration * props = m_config_retriever->getConfig(); @@ -197,11 +195,8 @@ Ndb_cluster_connection::~Ndb_cluster_connection() abort(); TransporterFacade::theFacadeInstance= 0; } - my_free(m_connect_string,MYF(MY_ALLOW_ZERO_PTR)); if (m_config_retriever) delete m_config_retriever; - if (m_local_config) - delete m_local_config; DBUG_VOID_RETURN; } diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index 0b1fdcbd0af..d4ad9cd6f1c 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -36,6 +36,7 @@ typedef struct ErrorBundle { #define NE ndberror_cl_none #define AE ndberror_cl_application +#define CE ndberror_cl_configuration #define ND ndberror_cl_no_data_found #define CV ndberror_cl_constraint_violation #define SE ndberror_cl_schema_error @@ -54,8 +55,32 @@ typedef struct ErrorBundle { #define NI ndberror_cl_function_not_implemented #define UE ndberror_cl_unknown_error_code +static const char REDO_BUFFER_MSG[]= +"REDO log buffers overloaded, consult online manual (increase RedoBuffer, and|or decrease TimeBetweenLocalCheckpoints, and|or increase NoOfFragmentLogFiles)"; + static const char* empty_string = ""; +/* + * Error code ranges are reserved for respective block + * + * 200 - TC + * 300 - DIH + * 400 - LQH + * 600 - ACC + * 700 - DICT + * 800 - TUP + * 1200 - LQH + * 1300 - BACKUP + * 4000 - API + * 4100 - "" + * 4200 - "" + * 4300 - "" + * 4400 - "" + * 4500 - "" + * 4600 - "" + * 5000 - Management server + */ + static const ErrorBundle ErrorCodes[] = { @@ -138,9 +163,8 @@ ErrorBundle ErrorCodes[] = { { 805, TR, "Out of attrinfo records in tuple manager" }, { 830, TR, "Out of add fragment operation records" }, { 873, TR, "Out of attrinfo records for scan in tuple manager" }, - { 1217, TR, "1217" }, - { 1219, TR, "Out of operation records in local data manager (increase MaxNoOfLocalOperations)" }, - { 1220, TR, "1220" }, + { 1217, TR, "Out of operation records in local data manager (increase MaxNoOfLocalOperations)" }, + { 1220, TR, REDO_BUFFER_MSG }, { 1222, TR, "Out of transaction markers in LQH" }, { 4021, TR, "Out of Send Buffer space in NDB API" }, { 4022, TR, "Out of Send Buffer space in NDB API" }, @@ -166,14 +190,13 @@ ErrorBundle ErrorCodes[] = { { 297, TO, "Time-out in NDB, probably caused by deadlock" }, /* Scan trans timeout, temporary!! */ { 237, TO, "Transaction had timed out when trying to commit it" }, - /** * OverloadError */ - { 410, OL, "Out of log file space temporarily" }, + { 410, OL, REDO_BUFFER_MSG }, { 677, OL, "Index UNDO buffers overloaded (increase UndoIndexBuffer)" }, { 891, OL, "Data UNDO buffers overloaded (increase UndoDataBuffer)" }, - { 1221, OL, "REDO log buffers overloaded (increase RedoBuffer)" }, + { 1221, OL, REDO_BUFFER_MSG }, { 4006, OL, "Connect failure - out of connection objects (increase MaxNoOfConcurrentTransactions)" }, @@ -241,11 +264,12 @@ ErrorBundle ErrorCodes[] = { { 877, AE, "877" }, { 878, AE, "878" }, { 879, AE, "879" }, + { 880, AE, "Tried to read too much - too many getValue calls" }, { 884, AE, "Stack overflow in interpreter" }, { 885, AE, "Stack underflow in interpreter" }, { 886, AE, "More than 65535 instructions executed in interpreter" }, + { 897, AE, "Update attempt of primary key via ndbcluster internal api (if this occurs via the MySQL server it is a bug, please report)" }, { 4256, AE, "Must call Ndb::init() before this function" }, - { 880, AE, "Tried to read too much - too many getValue calls" }, { 4257, AE, "Tried to read too much - too many getValue calls" }, /** @@ -303,6 +327,36 @@ ErrorBundle ErrorCodes[] = { { 4003, NI, "Function not implemented yet" }, /** + * Backup error codes + */ + + { 1300, IE, "Undefined error" }, + { 1301, IE, "Backup issued to not master (reissue command to master)" }, + { 1302, IE, "Out of backup record" }, + { 1303, IS, "Out of resources" }, + { 1304, IE, "Sequence failure" }, + { 1305, IE, "Backup definition not implemented" }, + { 1306, AE, "Backup not supported in diskless mode (change Diskless)" }, + + { 1321, IE, "Backup aborted by application" }, + { 1322, IE, "Backup already completed" }, + { 1323, IE, "1323" }, + { 1324, IE, "Backup log buffer full" }, + { 1325, IE, "File or scan error" }, + { 1326, IE, "Backup abortet due to node failure" }, + { 1327, IE, "1327" }, + + { 1340, IE, "Backup undefined error" }, + { 1342, AE, "Backup failed to allocate buffers (check configuration)" }, + { 1343, AE, "Backup failed to setup fs buffers (check configuration)" }, + { 1344, AE, "Backup failed to allocate tables (check configuration)" }, + { 1345, AE, "Backup failed to insert file header (check configuration)" }, + { 1346, AE, "Backup failed to insert table list (check configuration)" }, + { 1347, AE, "Backup failed to allocate table memory (check configuration)" }, + { 1348, AE, "Backup failed to allocate file record (check configuration)" }, + { 1349, AE, "Backup failed to allocate attribute record (check configuration)" }, + + /** * Still uncategorized */ { 720, AE, "Attribute name reused in table definition" }, @@ -426,7 +480,8 @@ ErrorBundle ErrorCodes[] = { { 4267, IE, "Corrupted blob value" }, { 4268, IE, "Error in blob head update forced rollback of transaction" }, { 4268, IE, "Unknown blob error" }, - { 4269, IE, "No connection to ndb management server" } + { 4269, IE, "No connection to ndb management server" }, + { 4335, AE, "Only one autoincrement column allowed per table. Having a table without primary key uses an autoincremented hidden key, i.e. a table without a primary key can not have an autoincremented column" } }; static @@ -465,6 +520,7 @@ const ErrorStatusClassification StatusClassificationMapping[] = { { ST_S, NE, "No error"}, { ST_P, AE, "Application error"}, + { ST_P, CE, "Configuration or application error"}, { ST_P, ND, "No data found"}, { ST_P, CV, "Constraint violation"}, { ST_P, SE, "Schema error"}, diff --git a/ndb/test/include/NdbRestarter.hpp b/ndb/test/include/NdbRestarter.hpp index 114726f6a2b..19a88b4f8ad 100644 --- a/ndb/test/include/NdbRestarter.hpp +++ b/ndb/test/include/NdbRestarter.hpp @@ -87,8 +87,6 @@ protected: bool connected; BaseString addr; - BaseString host; - int port; NdbMgmHandle handle; ndb_mgm_configuration * m_config; protected: diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp index efa0811aa39..4b532856709 100644 --- a/ndb/test/ndbapi/testBlobs.cpp +++ b/ndb/test/ndbapi/testBlobs.cpp @@ -22,6 +22,7 @@ #include <NdbMain.h> #include <NdbOut.hpp> #include <NdbTest.hpp> +#include <NdbTick.h> struct Bcol { bool m_nullable; @@ -59,6 +60,9 @@ struct Opt { bool m_oneblob; Bcol m_blob1; Bcol m_blob2; + // perf + const char* m_tnameperf; + unsigned m_rowsperf; // bugs int m_bug; int (*m_bugtest)(); @@ -84,6 +88,9 @@ struct Opt { m_oneblob(false), m_blob1(false, 7, 1137, 10), m_blob2(true, 99, 55, 1), + // perf + m_tnameperf("TBLOB2"), + m_rowsperf(10000), // bugs m_bug(0), m_bugtest(0) { @@ -107,6 +114,7 @@ printusage() << " -loop N loop N times 0=forever [" << d.m_loop << "]" << endl << " -parts N max parts in blob value [" << d.m_parts << "]" << endl << " -rows N number of rows [" << d.m_rows << "]" << endl + << " -rowsperf N rows for performace test [" << d.m_rowsperf << "]" << endl << " -seed N random seed 0=loop number [" << d.m_seed << "]" << endl << " -skip xxx skip given tests (see list) [no tests]" << endl << " -test xxx only given tests (see list) [all tests]" << endl @@ -118,6 +126,7 @@ printusage() << " i hash index ops" << endl << " s table scans" << endl << " r ordered index scans" << endl + << " p performance test" << endl << "additional flags for test/skip" << endl << " u update existing blob value" << endl << " n normal insert and update" << endl @@ -1381,6 +1390,292 @@ testmain() return 0; } +// separate performance test + +struct Tmr { // stolen from testOIBasic + Tmr() { + clr(); + } + void clr() { + m_on = m_ms = m_cnt = m_time[0] = m_text[0] = 0; + } + void on() { + assert(m_on == 0); + m_on = NdbTick_CurrentMillisecond(); + } + void off(unsigned cnt = 0) { + NDB_TICKS off = NdbTick_CurrentMillisecond(); + assert(m_on != 0 && off >= m_on); + m_ms += off - m_on; + m_cnt += cnt; + m_on = 0; + } + const char* time() { + if (m_cnt == 0) + sprintf(m_time, "%u ms", m_ms); + else + sprintf(m_time, "%u ms per %u ( %u ms per 1000 )", m_ms, m_cnt, (1000 * m_ms) / m_cnt); + return m_time; + } + const char* pct (const Tmr& t1) { + if (0 < t1.m_ms) + sprintf(m_text, "%u pct", (100 * m_ms) / t1.m_ms); + else + sprintf(m_text, "[cannot measure]"); + return m_text; + } + const char* over(const Tmr& t1) { + if (0 < t1.m_ms) { + if (t1.m_ms <= m_ms) + sprintf(m_text, "%u pct", (100 * (m_ms - t1.m_ms)) / t1.m_ms); + else + sprintf(m_text, "-%u pct", (100 * (t1.m_ms - m_ms)) / t1.m_ms); + } else + sprintf(m_text, "[cannot measure]"); + return m_text; + } + NDB_TICKS m_on; + unsigned m_ms; + unsigned m_cnt; + char m_time[100]; + char m_text[100]; +}; + +static int +testperf() +{ + if (! testcase('p')) + return 0; + DBG("=== perf test ==="); + g_ndb = new Ndb("TEST_DB"); + CHK(g_ndb->init() == 0); + CHK(g_ndb->waitUntilReady() == 0); + g_dic = g_ndb->getDictionary(); + NdbDictionary::Table tab(g_opt.m_tnameperf); + if (g_dic->getTable(tab.getName()) != 0) + CHK(g_dic->dropTable(tab) == 0); + // col A - pk + { NdbDictionary::Column col("A"); + col.setType(NdbDictionary::Column::Unsigned); + col.setPrimaryKey(true); + tab.addColumn(col); + } + // col B - char 20 + { NdbDictionary::Column col("B"); + col.setType(NdbDictionary::Column::Char); + col.setLength(20); + col.setNullable(true); + tab.addColumn(col); + } + // col C - text + { NdbDictionary::Column col("C"); + col.setType(NdbDictionary::Column::Text); + col.setInlineSize(20); + col.setPartSize(512); + col.setStripeSize(1); + col.setNullable(true); + tab.addColumn(col); + } + // create + CHK(g_dic->createTable(tab) == 0); + Uint32 cA = 0, cB = 1, cC = 2; + // timers + Tmr t1; + Tmr t2; + // insert char (one trans) + { + DBG("--- insert char ---"); + t1.on(); + CHK((g_con = g_ndb->startTransaction()) != 0); + for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { + CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); + CHK(g_opr->insertTuple() == 0); + CHK(g_opr->equal(cA, (char*)&k) == 0); + CHK(g_opr->setValue(cB, "b") == 0); + CHK(g_con->execute(NoCommit) == 0); + } + t1.off(g_opt.m_rowsperf); + CHK(g_con->execute(Rollback) == 0); + DBG(t1.time()); + g_opr = 0; + g_con = 0; + } + // insert text (one trans) + { + DBG("--- insert text ---"); + t2.on(); + CHK((g_con = g_ndb->startTransaction()) != 0); + for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { + CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); + CHK(g_opr->insertTuple() == 0); + CHK(g_opr->equal(cA, (char*)&k) == 0); + CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0); + CHK((g_bh1->setValue("c", 1) == 0)); + CHK(g_con->execute(NoCommit) == 0); + } + t2.off(g_opt.m_rowsperf); + CHK(g_con->execute(Rollback) == 0); + DBG(t2.time()); + g_bh1 = 0; + g_opr = 0; + g_con = 0; + } + // insert overhead + DBG("insert overhead: " << t2.over(t1)); + t1.clr(); + t2.clr(); + // insert + { + DBG("--- insert for read test ---"); + unsigned n = 0; + CHK((g_con = g_ndb->startTransaction()) != 0); + for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { + CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); + CHK(g_opr->insertTuple() == 0); + CHK(g_opr->equal(cA, (char*)&k) == 0); + CHK(g_opr->setValue(cB, "b") == 0); + CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0); + CHK((g_bh1->setValue("c", 1) == 0)); + if (++n == g_opt.m_batch) { + CHK(g_con->execute(Commit) == 0); + g_ndb->closeTransaction(g_con); + CHK((g_con = g_ndb->startTransaction()) != 0); + n = 0; + } + } + if (n != 0) { + CHK(g_con->execute(Commit) == 0); + n = 0; + } + g_bh1 = 0; + g_opr = 0; + g_con = 0; + } + // pk read char (one trans) + { + DBG("--- pk read char ---"); + CHK((g_con = g_ndb->startTransaction()) != 0); + Uint32 a; + char b[20]; + t1.on(); + for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { + CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); + CHK(g_opr->readTuple() == 0); + CHK(g_opr->equal(cA, (char*)&k) == 0); + CHK(g_opr->getValue(cA, (char*)&a) != 0); + CHK(g_opr->getValue(cB, b) != 0); + a = (Uint32)-1; + b[0] = 0; + CHK(g_con->execute(NoCommit) == 0); + CHK(a == k && strcmp(b, "b") == 0); + } + CHK(g_con->execute(Commit) == 0); + t1.off(g_opt.m_rowsperf); + DBG(t1.time()); + g_opr = 0; + g_con = 0; + } + // pk read text (one trans) + { + DBG("--- pk read text ---"); + CHK((g_con = g_ndb->startTransaction()) != 0); + Uint32 a; + char c[20]; + t2.on(); + for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { + CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); + CHK(g_opr->readTuple() == 0); + CHK(g_opr->equal(cA, (char*)&k) == 0); + CHK(g_opr->getValue(cA, (char*)&a) != 0); + CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0); + a = (Uint32)-1; + c[0] = 0; + CHK(g_con->execute(NoCommit) == 0); + Uint32 m = 20; + CHK(g_bh1->readData(c, m) == 0); + CHK(a == k && m == 1 && strcmp(c, "c") == 0); + } + CHK(g_con->execute(Commit) == 0); + t2.off(g_opt.m_rowsperf); + DBG(t2.time()); + g_opr = 0; + g_con = 0; + } + // pk read overhead + DBG("pk read overhead: " << t2.over(t1)); + t1.clr(); + t2.clr(); + // scan read char + { + DBG("--- scan read char ---"); + NdbResultSet* rs; + Uint32 a; + char b[20]; + CHK((g_con = g_ndb->startTransaction()) != 0); + CHK((g_ops = g_con->getNdbScanOperation(tab.getName())) != 0); + CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Read)) != 0); + CHK(g_ops->getValue(cA, (char*)&a) != 0); + CHK(g_ops->getValue(cB, b) != 0); + CHK(g_con->execute(NoCommit) == 0); + unsigned n = 0; + t1.on(); + while (1) { + a = (Uint32)-1; + b[0] = 0; + int ret; + CHK((ret = rs->nextResult(true)) == 0 || ret == 1); + if (ret == 1) + break; + CHK(a < g_opt.m_rowsperf && strcmp(b, "b") == 0); + n++; + } + CHK(n == g_opt.m_rowsperf); + t1.off(g_opt.m_rowsperf); + DBG(t1.time()); + g_ops = 0; + g_con = 0; + } + // scan read text + { + DBG("--- read text ---"); + NdbResultSet* rs; + Uint32 a; + char c[20]; + CHK((g_con = g_ndb->startTransaction()) != 0); + CHK((g_ops = g_con->getNdbScanOperation(tab.getName())) != 0); + CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Read)) != 0); + CHK(g_ops->getValue(cA, (char*)&a) != 0); + CHK((g_bh1 = g_ops->getBlobHandle(cC)) != 0); + CHK(g_con->execute(NoCommit) == 0); + unsigned n = 0; + t2.on(); + while (1) { + a = (Uint32)-1; + c[0] = 0; + int ret; + CHK((ret = rs->nextResult(true)) == 0 || ret == 1); + if (ret == 1) + break; + Uint32 m = 20; + CHK(g_bh1->readData(c, m) == 0); + CHK(a < g_opt.m_rowsperf && m == 1 && strcmp(c, "c") == 0); + n++; + } + CHK(n == g_opt.m_rowsperf); + t2.off(g_opt.m_rowsperf); + DBG(t2.time()); + g_bh1 = 0; + g_ops = 0; + g_con = 0; + } + // scan read overhead + DBG("scan read overhead: " << t2.over(t1)); + t1.clr(); + t2.clr(); + delete g_ndb; + return 0; +} + // bug tests static int @@ -1498,6 +1793,12 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) continue; } } + if (strcmp(arg, "-rowsperf") == 0) { + if (++argv, --argc > 0) { + g_opt.m_rowsperf = atoi(argv[0]); + continue; + } + } if (strcmp(arg, "-seed") == 0) { if (++argv, --argc > 0) { g_opt.m_seed = atoi(argv[0]); @@ -1558,7 +1859,7 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) strcat(b, "r"); g_opt.m_skip = strdup(b); } - if (testmain() == -1) { + if (testmain() == -1 || testperf() == -1) { ndbout << "line " << __LINE__ << " FAIL loop=" << g_loop << endl; return NDBT_ProgramExit(NDBT_FAILED); } diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index 712ab2e4d25..5f88342705a 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1211,7 +1211,7 @@ runTableRename(NDBT_Context* ctx, NDBT_Step* step){ const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); if (oldTable) { - NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str()); + NdbDictionary::Table newTable = *oldTable; newTable.setName(pTabNewName.c_str()); CHECK2(dict->alterTable(newTable) == 0, "TableRename failed"); @@ -1280,7 +1280,7 @@ runTableRenameNF(NDBT_Context* ctx, NDBT_Step* step){ const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); if (oldTable) { - NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str()); + NdbDictionary::Table newTable = *oldTable; newTable.setName(pTabNewName.c_str()); CHECK2(dict->alterTable(newTable) == 0, "TableRename failed"); @@ -1377,7 +1377,7 @@ runTableRenameSR(NDBT_Context* ctx, NDBT_Step* step){ const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); if (oldTable) { - NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str()); + NdbDictionary::Table newTable = *oldTable; newTable.setName(pTabNewName.c_str()); CHECK2(dict->alterTable(newTable) == 0, "TableRename failed"); @@ -1480,8 +1480,10 @@ runTestDictionaryPerf(NDBT_Context* ctx, NDBT_Step* step){ } int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){ + static int acclst[] = { 3001 }; static int tuplst[] = { 4007, 4008, 4009, 4010, 4011, 4012 }; static int tuxlst[] = { 12001, 12002, 12003, 12004, 12005, 12006 }; + static unsigned acccnt = sizeof(acclst)/sizeof(acclst[0]); static unsigned tupcnt = sizeof(tuplst)/sizeof(tuplst[0]); static unsigned tuxcnt = sizeof(tuxlst)/sizeof(tuxlst[0]); @@ -1509,6 +1511,19 @@ int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){ (void)pDic->dropTable(tab.getName()); for (int l = 0; l < loops; l++) { + for (unsigned i0 = 0; i0 < acccnt; i0++) { + unsigned j = (l == 0 ? i0 : myRandom48(acccnt)); + int errval = acclst[j]; + g_info << "insert error node=" << nodeId << " value=" << errval << endl; + CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0, + "failed to set error insert"); + CHECK2(pDic->createTable(tab) != 0, + "failed to fail after error insert " << errval); + CHECK2(pDic->createTable(tab) == 0, + pDic->getNdbError()); + CHECK2(pDic->dropTable(tab.getName()) == 0, + pDic->getNdbError()); + } for (unsigned i1 = 0; i1 < tupcnt; i1++) { unsigned j = (l == 0 ? i1 : myRandom48(tupcnt)); int errval = tuplst[j]; @@ -1638,7 +1653,7 @@ TESTCASE("DictionaryPerf", INITIALIZER(runTestDictionaryPerf); } TESTCASE("FailAddFragment", - "Fail add fragment or attribute in TUP or TUX\n"){ + "Fail add fragment or attribute in ACC or TUP or TUX\n"){ INITIALIZER(runFailAddFragment); } NDBT_TESTSUITE_END(testDict); @@ -1650,5 +1665,3 @@ int main(int argc, const char** argv){ myRandom48Init(NdbTick_CurrentMillisecond()); return testDict.execute(argc, argv); } - - diff --git a/ndb/test/run-test/main.cpp b/ndb/test/run-test/main.cpp index e5f73bc6a5c..ac7710d9546 100644 --- a/ndb/test/run-test/main.cpp +++ b/ndb/test/run-test/main.cpp @@ -538,15 +538,19 @@ connect_ndb_mgm(atrt_process & proc){ } BaseString tmp = proc.m_hostname; tmp.appfmt(":%d", proc.m_ndb_mgm_port); - time_t start = time(0); - const time_t max_connect_time = 30; - do { - if(ndb_mgm_connect(handle, tmp.c_str()) != -1){ - proc.m_ndb_mgm_handle = handle; - return true; - } - sleep(1); - } while(time(0) < (start + max_connect_time)); + + if (ndb_mgm_set_connectstring(handle,tmp.c_str())) + { + g_logger.critical("Unable to create parse connectstring"); + return false; + } + + if(ndb_mgm_connect(handle, 30, 1, 0) != -1) + { + proc.m_ndb_mgm_handle = handle; + return true; + } + g_logger.critical("Unable to connect to ndb mgm %s", tmp.c_str()); return false; } diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp index 1ce48d495a5..5e22468692e 100644 --- a/ndb/test/src/NdbBackup.cpp +++ b/ndb/test/src/NdbBackup.cpp @@ -46,7 +46,8 @@ NdbBackup::start(unsigned int & _backup_id){ ndb_mgm_reply reply; reply.return_code = 0; - if (ndb_mgm_start_backup(handle, + if (ndb_mgm_start_backup(handle, + 2, // wait until completed &_backup_id, &reply) == -1) { g_err << "Could not start backup " << endl; @@ -69,28 +70,19 @@ NdbBackup::getBackupDataDirForNode(int _node_id){ /** * Fetch configuration from management server */ - LocalConfig lc; - if (!lc.init(0,0)) { - abort(); - } - ConfigRetriever cr(lc, 0, NODE_TYPE_API); - ndb_mgm_configuration * p = 0; + ndb_mgm_configuration *p; + if (connect()) + return NULL; - BaseString tmp; tmp.assfmt("%s:%d", host.c_str(), port); - NdbMgmHandle handle = ndb_mgm_create_handle(); - if(handle == 0 || ndb_mgm_connect(handle, tmp.c_str()) != 0 || - (p = ndb_mgm_get_configuration(handle, 0)) == 0){ - - const char * s = 0; - if(p == 0 && handle != 0){ - s = ndb_mgm_get_latest_error_msg(handle); - if(s == 0) - s = "No error given!"; + if ((p = ndb_mgm_get_configuration(handle, 0)) == 0) + { + const char * s= ndb_mgm_get_latest_error_msg(handle); + if(s == 0) + s = "No error given!"; - ndbout << "Could not fetch configuration" << endl; - ndbout << s << endl; - return NULL; - } + ndbout << "Could not fetch configuration" << endl; + ndbout << s << endl; + return NULL; } /** @@ -155,13 +147,14 @@ NdbBackup::execRestore(bool _restore_data, ndbout << "scp res: " << res << endl; - BaseString::snprintf(buf, 255, "%sndb_restore -c \"host=%s\" -n %d -b %d %s %s .", + BaseString::snprintf(buf, 255, "%sndb_restore -c \"%s:%d\" -n %d -b %d %s %s .", #if 1 "", #else "valgrind --leak-check=yes -v " #endif - addr.c_str(), + ndb_mgm_get_connected_host(handle), + ndb_mgm_get_connected_port(handle), _node_id, _backup_id, _restore_data?"-r":"", diff --git a/ndb/test/src/NdbRestarter.cpp b/ndb/test/src/NdbRestarter.cpp index 14976b561e8..91c0963feae 100644 --- a/ndb/test/src/NdbRestarter.cpp +++ b/ndb/test/src/NdbRestarter.cpp @@ -18,7 +18,6 @@ #include <NdbOut.hpp> #include <NdbSleep.h> #include <NdbTick.h> -#include <LocalConfig.hpp> #include <mgmapi_debug.h> #include <NDBT_Output.hpp> #include <random.h> @@ -33,42 +32,11 @@ NdbRestarter::NdbRestarter(const char* _addr): connected(false), - port(-1), handle(NULL), m_config(0) { if (_addr == NULL){ - LocalConfig lcfg; - if(!lcfg.init()){ - lcfg.printError(); - lcfg.printUsage(); - g_err << "NdbRestarter - Error parsing local config file" << endl; - return; - } - - if (lcfg.ids.size() == 0){ - g_err << "NdbRestarter - No management servers configured in local config file" << endl; - return; - } - - for (int i = 0; i<lcfg.ids.size(); i++){ - MgmtSrvrId * m = &lcfg.ids[i]; - - switch(m->type){ - case MgmId_TCP: - char buf[255]; - BaseString::snprintf(buf, 255, "%s:%d", m->name.c_str(), m->port); - addr.assign(buf); - host.assign(m->name.c_str()); - port = m->port; - return; - break; - case MgmId_File: - break; - default: - break; - } - } + addr.assign(""); } else { addr.assign(_addr); } @@ -391,13 +359,22 @@ NdbRestarter::isConnected(){ int NdbRestarter::connect(){ + disconnect(); handle = ndb_mgm_create_handle(); if (handle == NULL){ g_err << "handle == NULL" << endl; return -1; } g_info << "Connecting to mgmsrv at " << addr.c_str() << endl; - if (ndb_mgm_connect(handle, addr.c_str()) == -1) { + if (ndb_mgm_set_connectstring(handle,addr.c_str())) + { + MGMERR(handle); + g_err << "Connection to " << addr.c_str() << " failed" << endl; + return -1; + } + + if (ndb_mgm_connect(handle, 0, 0, 0) == -1) + { MGMERR(handle); g_err << "Connection to " << addr.c_str() << " failed" << endl; return -1; diff --git a/ndb/tools/Makefile.am b/ndb/tools/Makefile.am index 8d78a3dcad9..c350fb0a141 100644 --- a/ndb/tools/Makefile.am +++ b/ndb/tools/Makefile.am @@ -26,7 +26,7 @@ ndb_select_all_SOURCES = select_all.cpp \ ../test/src/NDBT_ResultRow.cpp \ $(tools_common_sources) ndb_select_count_SOURCES = select_count.cpp $(tools_common_sources) -ndb_restore_SOURCES = restore/main.cpp \ +ndb_restore_SOURCES = restore/restore_main.cpp \ restore/consumer.cpp \ restore/consumer_restore.cpp \ restore/consumer_printer.cpp \ diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp index a4fd73a5128..046ac8005d2 100644 --- a/ndb/tools/delete_all.cpp +++ b/ndb/tools/delete_all.cpp @@ -67,7 +67,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int main(int argc, char** argv){ NDB_INIT(argv[0]); - const char *load_default_groups[]= { "ndb_tools",0 }; + const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) diff --git a/ndb/tools/desc.cpp b/ndb/tools/desc.cpp index 8f7a2031ef0..c5e9efdfa8a 100644 --- a/ndb/tools/desc.cpp +++ b/ndb/tools/desc.cpp @@ -67,7 +67,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int main(int argc, char** argv){ NDB_INIT(argv[0]); - const char *load_default_groups[]= { "ndb_tools",0 }; + const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) diff --git a/ndb/tools/drop_index.cpp b/ndb/tools/drop_index.cpp index 1d4b454682f..6600811e0c4 100644 --- a/ndb/tools/drop_index.cpp +++ b/ndb/tools/drop_index.cpp @@ -64,7 +64,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int main(int argc, char** argv){ NDB_INIT(argv[0]); - const char *load_default_groups[]= { "ndb_tools",0 }; + const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) diff --git a/ndb/tools/drop_tab.cpp b/ndb/tools/drop_tab.cpp index 3362c7de47b..0661a8c599b 100644 --- a/ndb/tools/drop_tab.cpp +++ b/ndb/tools/drop_tab.cpp @@ -64,7 +64,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int main(int argc, char** argv){ NDB_INIT(argv[0]); - const char *load_default_groups[]= { "ndb_tools",0 }; + const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) diff --git a/ndb/tools/listTables.cpp b/ndb/tools/listTables.cpp index 05e864a35c4..ccb6967e2dc 100644 --- a/ndb/tools/listTables.cpp +++ b/ndb/tools/listTables.cpp @@ -220,7 +220,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int main(int argc, char** argv){ NDB_INIT(argv[0]); const char* _tabname; - const char *load_default_groups[]= { "ndb_tools",0 }; + const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) @@ -228,10 +228,11 @@ int main(int argc, char** argv){ _tabname = argv[0]; ndb_cluster_connection = new Ndb_cluster_connection(opt_connect_str); + if (ndb_cluster_connection->connect(12,5,1)) + fatal("unable to connect"); ndb = new Ndb(ndb_cluster_connection, _dbname); if (ndb->init() != 0) fatal("init"); - ndb_cluster_connection->connect(); if (ndb->waitUntilReady(30) < 0) fatal("waitUntilReady"); dic = ndb->getDictionary(); diff --git a/ndb/tools/restore/Restore.cpp b/ndb/tools/restore/Restore.cpp index 277cdc72532..fa616ee8fee 100644 --- a/ndb/tools/restore/Restore.cpp +++ b/ndb/tools/restore/Restore.cpp @@ -260,16 +260,16 @@ TupleS & TupleS::operator=(const TupleS& tuple) memcpy(allAttrData, tuple.allAttrData, getNoOfAttributes()*sizeof(AttributeData)); return *this; -}; +} int TupleS::getNoOfAttributes() const { if (m_currentTable == 0) return 0; return m_currentTable->getNoOfAttributes(); -}; +} TableS * TupleS::getTable() const { return m_currentTable; -}; +} const AttributeDesc * TupleS::getDesc(int i) const { return m_currentTable->allAttributesDesc[i]; @@ -277,7 +277,7 @@ const AttributeDesc * TupleS::getDesc(int i) const { AttributeData * TupleS::getData(int i) const{ return &(allAttrData[i]); -}; +} bool TupleS::prepareRecord(TableS & tab){ diff --git a/ndb/tools/restore/main.cpp b/ndb/tools/restore/restore_main.cpp index 575cd9b3b2f..ece2b2605b4 100644 --- a/ndb/tools/restore/main.cpp +++ b/ndb/tools/restore/restore_main.cpp @@ -74,7 +74,7 @@ static struct my_option my_long_options[] = "No of parallel transactions during restore of data." "(parallelism can be 1 to 1024)", (gptr*) &ga_nParallelism, (gptr*) &ga_nParallelism, 0, - GET_INT, REQUIRED_ARG, 128, 0, 0, 0, 0, 0 }, + GET_INT, REQUIRED_ARG, 128, 1, 1024, 0, 1, 0 }, { "print", 256, "Print data and log to stdout", (gptr*) &_print, (gptr*) &_print, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, @@ -120,6 +120,20 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'V': print_version(); exit(0); + case 'n': + if (ga_nodeId == 0) + { + printf("Error in --nodeid,-n setting, see --help\n"); + exit(1); + } + break; + case 'b': + if (ga_backupId == 0) + { + printf("Error in --backupid,-b setting, see --help\n"); + exit(1); + } + break; case '?': usage(); exit(0); @@ -129,13 +143,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), bool readArguments(int *pargc, char*** pargv) { - const char *load_default_groups[]= { "ndb_tools","ndb_restore",0 }; + const char *load_default_groups[]= { "mysql_cluster","ndb_restore",0 }; load_defaults("my",load_default_groups,pargc,pargv); - if (handle_options(pargc, pargv, my_long_options, get_one_option) || - ga_nodeId == 0 || - ga_backupId == 0 || - ga_nParallelism < 1 || - ga_nParallelism >1024) { + if (handle_options(pargc, pargv, my_long_options, get_one_option)) + { exit(1); } @@ -350,7 +361,8 @@ main(int argc, char** argv) if (res < 0) { - err << "Restore: An error occured while restoring data. Exiting... res=" << res << endl; + err << "Restore: An error occured while restoring data. Exiting... " + << "res=" << res << endl; return -1; } @@ -376,7 +388,8 @@ main(int argc, char** argv) } if (res < 0) { - err << "Restore: An restoring the data log. Exiting... res=" << res << endl; + err << "Restore: An restoring the data log. Exiting... res=" + << res << endl; return -1; } logIter.validateFooter(); //not implemented diff --git a/ndb/tools/select_all.cpp b/ndb/tools/select_all.cpp index a670a2ed49a..5efeed485a4 100644 --- a/ndb/tools/select_all.cpp +++ b/ndb/tools/select_all.cpp @@ -105,7 +105,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int main(int argc, char** argv){ NDB_INIT(argv[0]); - const char *load_default_groups[]= { "ndb_tools",0 }; + const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); const char* _tabname; int ho_error; diff --git a/ndb/tools/select_count.cpp b/ndb/tools/select_count.cpp index 6ee49ddbff0..c3491f842d8 100644 --- a/ndb/tools/select_count.cpp +++ b/ndb/tools/select_count.cpp @@ -83,7 +83,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int main(int argc, char** argv){ NDB_INIT(argv[0]); - const char *load_default_groups[]= { "ndb_tools",0 }; + const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp index e24164ea807..5973b046f8f 100644 --- a/ndb/tools/waiter.cpp +++ b/ndb/tools/waiter.cpp @@ -23,7 +23,6 @@ #include <NdbOut.hpp> #include <NdbSleep.h> #include <kernel/ndb_limits.h> -#include <LocalConfig.hpp> #include <NDBT.hpp> @@ -75,7 +74,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int main(int argc, char** argv){ NDB_INIT(argv[0]); - const char *load_default_groups[]= { "ndb_tools",0 }; + const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); const char* _hostName = NULL; int ho_error; @@ -85,39 +84,8 @@ int main(int argc, char** argv){ char buf[255]; _hostName = argv[0]; - if (_hostName == NULL){ - LocalConfig lcfg; - if(!lcfg.init(opt_connect_str, 0)) - { - lcfg.printError(); - lcfg.printUsage(); - g_err << "Error parsing local config file" << endl; - return NDBT_ProgramExit(NDBT_FAILED); - } - - for (unsigned i = 0; i<lcfg.ids.size();i++) - { - MgmtSrvrId * m = &lcfg.ids[i]; - - switch(m->type){ - case MgmId_TCP: - snprintf(buf, 255, "%s:%d", m->name.c_str(), m->port); - _hostName = buf; - break; - case MgmId_File: - break; - default: - break; - } - if (_hostName != NULL) - break; - } - if (_hostName == NULL) - { - g_err << "No management servers configured in local config file" << endl; - return NDBT_ProgramExit(NDBT_FAILED); - } - } + if (_hostName == 0) + _hostName= opt_connect_str; if (_no_contact) { if (waitClusterStatus(_hostName, NDB_MGM_NODE_STATUS_NO_CONTACT, _timeout) != 0) @@ -210,13 +178,19 @@ waitClusterStatus(const char* _addr, int _nodes[MAX_NDB_NODES]; int _num_nodes = 0; - handle = ndb_mgm_create_handle(); + handle = ndb_mgm_create_handle(); if (handle == NULL){ g_err << "handle == NULL" << endl; return -1; } g_info << "Connecting to mgmsrv at " << _addr << endl; - if (ndb_mgm_connect(handle, _addr) == -1) { + if (ndb_mgm_set_connectstring(handle, _addr)) + { + MGMERR(handle); + g_err << "Connectstring " << _addr << " invalid" << endl; + return -1; + } + if (ndb_mgm_connect(handle,0,0,1)) { MGMERR(handle); g_err << "Connection to " << _addr << " failed" << endl; return -1; |