diff options
Diffstat (limited to 'ndb/src/mgmsrv/MgmtSrvr.hpp')
-rw-r--r-- | ndb/src/mgmsrv/MgmtSrvr.hpp | 780 |
1 files changed, 780 insertions, 0 deletions
diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp new file mode 100644 index 00000000000..4fdf3c99d43 --- /dev/null +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -0,0 +1,780 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef MgmtSrvr_H +#define MgmtSrvr_H + +#include <kernel_types.h> +#include "Config.hpp" +#include <NdbCondition.h> +#include <NdbConstant.hpp> +#include <mgmapi.h> + + +#include <Vector.hpp> +#include <NodeBitmask.hpp> +#include <signaldata/ManagementServer.hpp> +#include "SignalQueue.hpp" + +#include "NodeLogLevelList.hpp" + +/** + * @desc Block number for Management server. + * @todo This should probably be somewhere else. I don't know where atm. + */ +#define MGMSRV 1 + +class ConfigInfoServer; +class NdbApiSignal; +class Config; +class SetLogLevelOrd; +class SocketServer; + +/** + * @class MgmtSrvr + * @brief Main class for the management server. + * + * It has one interface to be used by a local client. + * With the methods it's possible to send different kind of commands to + * DB processes, as log level, set trace number etc. + * + * A MgmtSrvr creates a ConfigInfoServer which serves request on TCP sockets. + * The requests come typical from DB and API processes which want + * to fetch its configuration parameters. The MgmtSrvr knows about the + * configuration by reading a configuration file. + * + * The MgmtSrvr class corresponds in some ways to the Ndb class in API. + * It creates a TransporterFacade, receives signals and defines signals + * to send and receive. + */ +class MgmtSrvr { + +public: + class StatisticsListner { + public: + virtual void println_statistics(const BaseString &s) = 0; + }; + + /** + * Set a reference to the socket server. + */ + void setStatisticsListner(StatisticsListner* listner); + + /** + * Start/initate the event log. + */ + void startEventLog(); + + /** + * Stop the event log. + */ + void stopEventLog(); + + /** + * Enable/disable eventlog log levels/severities. + * + * @param serverity the log level/serverity. + * @return true if the severity was enabled. + */ + bool setEventLogFilter(int severity); + + /** + * Returns true if the log level/severity is enabled. + * + * @param severity the severity level. + */ + bool isEventLogFilterEnabled(int severity); + + STATIC_CONST( NO_CONTACT_WITH_PROCESS = 5000 ); + STATIC_CONST( PROCESS_NOT_CONFIGURED = 5001 ); + STATIC_CONST( WRONG_PROCESS_TYPE = 5002 ); + STATIC_CONST( COULD_NOT_ALLOCATE_MEMORY = 5003 ); + STATIC_CONST( SEND_OR_RECEIVE_FAILED = 5005 ); + STATIC_CONST( INVALID_LEVEL = 5006 ); + STATIC_CONST( INVALID_ERROR_NUMBER = 5007 ); + STATIC_CONST( INVALID_TRACE_NUMBER = 5008 ); + STATIC_CONST( NOT_IMPLEMENTED = 5009 ); + STATIC_CONST( INVALID_BLOCK_NAME = 5010 ); + + STATIC_CONST( CONFIG_PARAM_NOT_EXIST = 5011 ); + STATIC_CONST( CONFIG_PARAM_NOT_UPDATEABLE = 5012 ); + STATIC_CONST( VALUE_WRONG_FORMAT_INT_EXPECTED = 5013 ); + STATIC_CONST( VALUE_TOO_LOW = 5014 ); + STATIC_CONST( VALUE_TOO_HIGH = 5015 ); + STATIC_CONST( VALUE_WRONG_FORMAT_BOOL_EXPECTED = 5016 ); + + STATIC_CONST( CONFIG_FILE_OPEN_WRITE_ERROR = 5017 ); + STATIC_CONST( CONFIG_FILE_OPEN_READ_ERROR = 5018 ); + STATIC_CONST( CONFIG_FILE_WRITE_ERROR = 5019 ); + STATIC_CONST( CONFIG_FILE_READ_ERROR = 5020 ); + STATIC_CONST( CONFIG_FILE_CLOSE_ERROR = 5021 ); + + STATIC_CONST( CONFIG_CHANGE_REFUSED_BY_RECEIVER = 5022 ); + STATIC_CONST( COULD_NOT_SYNC_CONFIG_CHANGE_AGAINST_PHYSICAL_MEDIUM = 5023 ); + STATIC_CONST( CONFIG_FILE_CHECKSUM_ERROR = 5024 ); + STATIC_CONST( NOT_POSSIBLE_TO_SEND_CONFIG_UPDATE_TO_PROCESS_TYPE = 5025 ); + + STATIC_CONST( NODE_SHUTDOWN_IN_PROGESS = 5026 ); + STATIC_CONST( SYSTEM_SHUTDOWN_IN_PROGRESS = 5027 ); + STATIC_CONST( NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH = 5028 ); + STATIC_CONST( NO_CONTACT_WITH_CLUSTER = 6666 ); + STATIC_CONST( OPERATION_IN_PROGRESS = 6667 ); + + STATIC_CONST( NO_CONTACT_WITH_DB_NODES = 5030 ); + /** + * This class holds all statistical variables fetched with + * the getStatistics methods. + */ + class Statistics { // TODO, Real statistic data to be added + public: + int _test1; + }; + + /** + * This enum specifies the different signal loggig modes possible to set + * with the setSignalLoggingMode method. + */ + enum LogMode {In, Out, InOut, Off}; + + /* Constructor */ + MgmtSrvr(NodeId nodeId, /* Local nodeid */ + const BaseString &config_filename, /* Where to save config */ + const BaseString &ndb_config_filename); /* Ndb.cfg filename */ + + /** + * Read (initial) config file, create TransporterFacade, + * define signals, create ConfigInfoServer. + * @return true if succeeded, otherwise false + */ + bool check_start(); // may be run before start to check that some things are ok + bool start(); + + ~MgmtSrvr(); + + int status(int processId, + ndb_mgm_node_status * status, + Uint32 * version, + Uint32 * phase, + bool * systemShutdown, + Uint32 * dynamicId, + Uint32 * nodeGroup); + + // All the functions below may return any of this error codes: + // NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE, + // COULD_NOT_ALLOCATE_MEMORY, SEND_OR_RECEIVE_FAILED + + + typedef void (* StopCallback)(int nodeId, void * anyData, int errorCode); + + typedef void (* VersionCallback)(int nodeId, int version, + void * anyData, int errorCode); + + + typedef void (* EnterSingleCallback)(int nodeId, void * anyData, + int errorCode); + typedef void (* ExitSingleCallback)(int nodeId, void * anyData, + int errorCode); + + /** + * Lock configuration + */ + int lockConf(); + + /** + * Unlock configuration, and commit it if commit is true + */ + int unlockConf(bool commit); + + /** + * Commit new configuration + */ + int commitConfig(); + + /** + * Rollback configuration + */ + int rollbackConfig(); + + /** + * Save a configuration to permanent storage + */ + int saveConfig(const Config *); + + /** + * Save the running configuration + */ + int saveConfig() { + return saveConfig(_config); + }; + + /** + * Read configuration from file, or from another MGM server + */ + Config *readConfig(); + + /** + * Fetch configuration from another MGM server + */ + Config *fetchConfig(); + + /** + * Stop a node + * + * @param processId: Id of the DB process to stop + * @return 0 if succeeded, otherwise: as stated above, plus: + */ + int stopNode(int nodeId, bool abort = false, StopCallback = 0, void *any= 0); + + /** + * Stop the system + */ + int stop(int * cnt = 0, bool abort = false, StopCallback = 0, void *any = 0); + + /** + * print version info about a node + * + * @param processId: Id of the DB process to stop + * @return 0 if succeeded, otherwise: as stated above, plus: + */ + int versionNode(int nodeId, bool abort = false, + VersionCallback = 0, void *any= 0); + + /** + * print version info about all node in the system + */ + int version(int * cnt = 0, bool abort = false, + VersionCallback = 0, void *any = 0); + + /** + * Maintenance on the system + */ + int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0, + EnterSingleCallback = 0, void *any = 0); + + + /** + * Resume from maintenance on the system + */ + int exitSingleUser(int * cnt = 0, bool abort = false, + ExitSingleCallback = 0, void *any = 0); + + /** + * Start DB process. + * @param processId: Id of the DB process to start + * @return 0 if succeeded, otherwise: as stated above, plus: + */ + int start(int processId); + + /** + * Restart a node + * @param processId: Id of the DB process to start + */ + int restartNode(int processId, bool nostart, bool initialStart, + bool abort = false, + StopCallback = 0, void * anyData = 0); + + /** + * Restart the system + */ + int restart(bool nostart, bool initialStart, + bool abort = false, + int * stopCount = 0, StopCallback = 0, void * anyData = 0); + + int setEventReportingLevel(int processId, + const class SetLogLevelOrd & logLevel, + bool isResend = false); + + int startStatisticEventReporting(int level = 5); + + + struct BackupEvent { + enum Event { + BackupStarted = 1, + BackupFailedToStart = 2, + BackupCompleted = 3, + BackupAborted = 4 + } Event; + + union { + struct { + Uint32 BackupId; + NdbNodeBitmask Nodes; + } Started ; + struct { + Uint32 ErrorCode; + } FailedToStart ; + struct { + Uint32 BackupId; + Uint32 NoOfBytes; + Uint32 NoOfRecords; + Uint32 NoOfLogBytes; + Uint32 NoOfLogRecords; + NdbNodeBitmask Nodes; + Uint32 startGCP; + Uint32 stopGCP; + } Completed ; + struct { + Uint32 BackupId; + Uint32 Reason; + Uint32 ErrorCode; + } Aborted ; + }; + }; + + /** + * Backup functionallity + */ + typedef void (* BackupCallback)(const BackupEvent& Event); + BackupCallback setCallback(BackupCallback); + int startBackup(Uint32& backupId, bool waitCompleted = false); + int abortBackup(Uint32 backupId); + int performBackup(Uint32* backupId); + + /** + * Global Replication + */ + int repCommand(Uint32* repReqId, Uint32 request, bool waitCompleted = false); + + //************************************************************************** + // Description: Set event report level for a DB process + // Parameters: + // processId: Id of the DB process + // level: Event report level + // isResend: Flag to indicate for resending log levels during node restart + // Returns: 0 if succeeded, otherwise: as stated above, plus: + // INVALID_LEVEL + //************************************************************************** + + /** + * Sets the Node's log level, i.e., its local event reporting. + * + * @param processId the DB node id. + * @param logLevel the log level. + * @param isResend Flag to indicate for resending log levels + * during node restart + + * @return 0 if successful or NO_CONTACT_WITH_PROCESS, + * SEND_OR_RECEIVE_FAILED, + * COULD_NOT_ALLOCATE_MEMORY + */ + int setNodeLogLevel(int processId, + const class SetLogLevelOrd & logLevel, + bool isResend = false); + + + /** + * Insert an error in a DB process. + * @param processId: Id of the DB process + * @param errorNo: The error number. > 0. + * @return 0 if succeeded, otherwise: as stated above, plus: + * INVALID_ERROR_NUMBER + */ + int insertError(int processId, int errorNo); + + + + int setTraceNo(int processId, int traceNo); + //************************************************************************** + // Description: Set trace number in a DB process. + // Parameters: + // processId: Id of the DB process + // trace: Trace number + // Returns: 0 if succeeded, otherwise: as stated above, plus: + // INVALID_TRACE_NUMBER + //************************************************************************** + + + int setSignalLoggingMode(int processId, LogMode mode, + const Vector<BaseString> &blocks); + + int setSignalLoggingMode(int processId, LogMode mode, + BaseString &block) { + Vector<BaseString> v; + v.push_back(block); + return setSignalLoggingMode(processId, mode, v); + } + //************************************************************************** + // Description: Set signal logging mode for blocks in a DB process. + // Parameters: + // processId: Id of the DB process + // mode: The log mode + // blocks: Which blocks to be affected (container of strings) + // Returns: 0 if succeeded, otherwise: as stated above, plus: + // INVALID_BLOCK_NAME + //************************************************************************** + + + int startSignalTracing(int processId); + //************************************************************************** + // Description: Start signal tracing for a DB process. + // Parameters: + // processId: Id of the DB process + // Returns: 0 if succeeded, otherwise: as stated above. + //************************************************************************** + + + int stopSignalTracing(int processId); + //************************************************************************** + // Description: Stop signal tracing for a DB process. + // Parameters: + // processId: Id of the DB process + // Returns: 0 if succeeded, otherwise: as stated above. + //************************************************************************** + + /** + * Dump State + */ + int dumpState(int processId, const Uint32 args[], Uint32 argNo); + int dumpState(int processId, const char* args); + + /** + * Get next node id (node id gt that _nodeId) + * of specified type and save it in _nodeId + * + * @return false if none found + */ + bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ; + + /** + * + */ + enum ndb_mgm_node_type getNodeType(NodeId) const; + + /** + * Get error text + * + * @param errorCode: Error code to get a match error text for. + * @return The error text. + */ + const char* getErrorText(int errorCode); + + /** + * Get configuration + */ + const Config * getConfig() const; + + /** + * Change configuration paramter + */ + bool changeConfig(const BaseString §ion, + const BaseString ¶m, + const BaseString &value); + + /** + * Returns the node count for the specified node type. + * + * @param type The node type. + * @return The number of nodes of the specified type. + */ + int getNodeCount(enum ndb_mgm_node_type type) const; + + /** + * Returns the nodeId of the management master + */ + NodeId getPrimaryNode() const; + + /** + * Returns the statistics port number. + * @return statistic port number. + */ + int getStatPort() const; + + + //************************************************************************** +private: + //************************************************************************** + + int setEventReportingLevelImpl(int processId, + const class SetLogLevelOrd & logLevel, + bool isResend = false); + + + /** + * Check if it is possible to send a signal to a (DB) process + * + * @param processId: Id of the process to send to + * @return 0 OK, 1 process dead, 2 API or MGMT process, 3 not configured + */ + int okToSendTo(NodeId nodeId, bool unCond = false); + + /** + * Get block number for a block + * + * @param blockName: Block to get number for + * @return -1 if block not found, otherwise block number + */ + int getBlockNumber(const BaseString &blockName); + + //************************************************************************** + + int _blockNumber; + NodeId _ownNodeId; + BlockReference _ownReference; + NdbMutex *m_configMutex; + const Config * _config; + Config * m_newConfig; + BaseString m_configFilename; + BaseString m_localNdbConfigFilename; + Uint32 m_nextConfigGenerationNumber; + + int _setVarReqResult; // The result of the SET_VAR_REQ response + Statistics _statistics; // handleSTATISTICS_CONF store the result here, + // and getStatistics reads it. + + + + //************************************************************************** + // Specific signal handling methods + //************************************************************************** + + static void defineSignals(int blockNumber); + //************************************************************************** + // Description: Define all signals to be sent or received for a block + // Parameters: + // blockNumber: The block number send/receive + // Returns: - + //************************************************************************** + + void handleReceivedSignal(NdbApiSignal* signal); + //************************************************************************** + // Description: This method is called from "another" thread when a signal + // is received. If expect the received signal and succeed to handle it + // we signal with a condition variable to the waiting + // thread (receiveOptimisedResponse) that the signal has arrived. + // Parameters: + // signal: The recieved signal + // Returns: - + //************************************************************************** + + void handleStatus(NodeId nodeId, bool alive); + //************************************************************************** + // Description: Handle the death of a process + // Parameters: + // processId: Id of the dead process. + // Returns: - + //************************************************************************** + + int handleSTATISTICS_CONF(NdbApiSignal* signal); + //************************************************************************** + // Description: Handle reception of signal STATISTICS_CONF + // Parameters: + // signal: The recieved signal + // Returns: TODO, to be defined + //************************************************************************** + + void handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal); + void handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal); + + //************************************************************************** + // Specific signal handling data + //************************************************************************** + + + //************************************************************************** + //************************************************************************** + // General signal handling methods + // This functions are more or less copied from the Ndb class. + + + /** + * WaitSignalType defines states where each state define a set of signals + * we accept to receive. + * The state is set after we have sent a signal. + * When a signal arrives we first check current state (handleReceivedSignal) + * to verify that we expect the arrived signal. + * It's only then we are in state accepting the arrived signal + * we handle the signal. + */ + enum WaitSignalType { + NO_WAIT, // We don't expect to receive any signal + WAIT_STATISTICS, // Accept STATISTICS_CONF + WAIT_SET_VAR, // Accept SET_VAR_CONF and SET_VAR_REF + WAIT_SUBSCRIBE_CONF, // Accept event subscription confirmation + WAIT_STOP, + WAIT_BACKUP_STARTED, + WAIT_BACKUP_COMPLETED, + WAIT_VERSION + }; + + /** + * Get an unused signal + * @return A signal if succeeded, NULL otherwise + */ + NdbApiSignal* getSignal(); + + /** + * Add a signal to the list of unused signals + * @param signal: The signal to add + */ + void releaseSignal(NdbApiSignal* signal); + + /** + * Remove a signal from the list of unused signals and delete + * the memory for it. + */ + void freeSignal(); + + /** + * Send a signal + * @param processId: Id of the receiver process + * @param waitState: State denoting a set of signals we accept to receive + * @param signal: The signal to send + * @return 0 if succeeded, -1 otherwise + */ + int sendSignal(Uint16 processId, WaitSignalType waitState, + NdbApiSignal* signal, bool force = false); + + /** + * Send a signal and wait for an answer signal + * @param processId: Id of the receiver process + * @param waitState: State denoting a set of signals we accept to receive. + * @param signal: The signal to send + * @return 0 if succeeded, -1 otherwise (for example failed to send or + * failed to receive expected signal). + */ + int sendRecSignal(Uint16 processId, WaitSignalType waitState, + NdbApiSignal* signal, bool force = false, + int waitTime = WAIT_FOR_RESPONSE_TIMEOUT); + + /** + * Wait for a signal to arrive. + * @return 0 if signal arrived, -1 otherwise + */ + int receiveOptimisedResponse(int waitTime); + + /** + * This function is called from "outside" of MgmtSrvr + * when a signal is sent to MgmtSrvr. + * @param mgmtSrvr: The MgmtSrvr object which shall recieve the signal. + * @param signal: The received signal. + */ + static void signalReceivedNotification(void* mgmtSrvr, + NdbApiSignal* signal, + class LinearSectionPtr ptr[3]); + + /** + * Called from "outside" of MgmtSrvr when a DB process has died. + * @param mgmtSrvr: The MgmtSrvr object wreceiveOptimisedResponsehich + * shall receive the notification. + * @param processId: Id of the dead process. + */ + static void nodeStatusNotification(void* mgmSrv, NodeId nodeId, + bool alive, bool nfCompleted); + + /** + * An event from <i>nodeId</i> has arrived + */ + void eventReport(NodeId nodeId, const Uint32 * theData); + + + //************************************************************************** + //************************************************************************** + // General signal handling data + + static const unsigned int WAIT_FOR_RESPONSE_TIMEOUT = 300000; // Milliseconds + // Max time to wait for a signal to arrive + + NdbApiSignal* theSignalIdleList; + // List of unused signals + + WaitSignalType theWaitState; + // State denoting a set of signals we accept to recieve. + + NdbCondition* theMgmtWaitForResponseCondPtr; + // Condition variable used when we wait for a signal to arrive/a + // signal arrives. + // We wait in receiveOptimisedResponse and signal in handleReceivedSignal. + + class TransporterFacade * theFacade; + + class SignalQueue m_signalRecvQueue; + + enum ndb_mgm_node_type nodeTypes[MAX_NODES]; + + int theConfCount; // The number of expected conf signals + + StatisticsListner * m_statisticsListner; // Used for sending statistics info + bool _isStatPortActive; + bool _isClusterLogStatActive; + + struct StopRecord { + StopRecord(){ inUse = false; callback = 0; singleUserMode = false;} + bool inUse; + bool singleUserMode; + int sentCount; + int reply; + int nodeId; + void * anyData; + StopCallback callback; + }; + StopRecord m_stopRec; + + struct VersionRecord { + VersionRecord(){ inUse = false; callback = 0;} + bool inUse; + Uint32 version[MAX_NODES]; + VersionCallback callback; + }; + VersionRecord m_versionRec; + int sendVersionReq( int processId); + + + void handleStopReply(NodeId nodeId, Uint32 errCode); + int translateStopRef(Uint32 errCode); + + bool _isStopThread; + int _logLevelThreadSleep; + int _startedNodeId; + + /** + * Handles the thread wich upon a 'Node is started' event will + * set the node's previous loglevel settings. + */ + struct NdbThread* _logLevelThread; + static void *logLevelThread_C(void *); + void logLevelThreadRun(); + + struct NdbThread *m_signalRecvThread; + static void *signalRecvThread_C(void *); + void signalRecvThreadRun(); + + NodeLogLevelList* _nodeLogLevelList; + NodeLogLevelList* _clusterLogLevelList; + + void backupCallback(BackupEvent &); + BackupCallback m_backupCallback; + BackupEvent m_lastBackupEvent; + + Config *_props; + +public: + /** + * This method does not exist + */ + struct Area51 { + class TransporterFacade * theFacade; + class TransporterRegistry * theRegistry; + }; + Area51 getStuff(); +}; + +inline +const Config * +MgmtSrvr::getConfig() const { + return _config; +} + +#endif // MgmtSrvr_H |