diff options
author | unknown <joreland@mysql.com> | 2004-05-27 11:36:10 +0200 |
---|---|---|
committer | unknown <joreland@mysql.com> | 2004-05-27 11:36:10 +0200 |
commit | da2ae1899885b985b035a951a4a4278450c93c1c (patch) | |
tree | 7862a781e675e63710a9a14890d55b31d68af986 /ndb | |
parent | 489aa9be1ce31a0b7f4e8901faa818b21a8f7c7a (diff) | |
parent | 910b86cdac28d2bed391298e67e4b22b6361ff80 (diff) | |
download | mariadb-git-da2ae1899885b985b035a951a4a4278450c93c1c.tar.gz |
Merge
ndb/include/ndbapi/Ndb.hpp:
Auto merged
ndb/include/ndbapi/NdbConnection.hpp:
Auto merged
ndb/include/ndbapi/NdbIndexOperation.hpp:
Auto merged
ndb/Epilogue.mk_old:
Auto merged
ndb/src/common/debugger/signaldata/Makefile_old:
Auto merged
ndb/src/common/mgmcommon/Makefile_old:
Auto merged
ndb/src/common/util/Makefile_old:
Auto merged
ndb/src/kernel/Makefile_old:
Auto merged
ndb/src/kernel/ndb-main/Main.cpp:
Auto merged
ndb/src/kernel/ndb-main/Makefile_old:
Auto merged
ndb/src/kernel/vm/Makefile_old:
Auto merged
ndb/src/mgmapi/Makefile_old:
Auto merged
ndb/src/mgmclient/Makefile_old:
Auto merged
ndb/src/mgmsrv/Makefile_old:
Auto merged
ndb/src/mgmsrv/MgmtSrvr.cpp:
Auto merged
ndb/src/ndbapi/ClusterMgr.cpp:
Auto merged
ndb/src/ndbapi/Makefile_old:
Auto merged
ndb/src/ndbapi/Ndb.cpp:
Auto merged
ndb/src/ndbapi/NdbApiSignal.cpp:
Auto merged
ndb/src/ndbapi/NdbConnection.cpp:
Auto merged
ndb/src/ndbapi/NdbDictionaryImpl.cpp:
Auto merged
ndb/src/ndbapi/NdbEventOperationImpl.cpp:
Auto merged
ndb/src/ndbapi/NdbIndexOperation.cpp:
Auto merged
ndb/src/ndbapi/NdbOperation.cpp:
Auto merged
ndb/src/ndbapi/NdbOperationDefine.cpp:
Auto merged
ndb/src/ndbapi/NdbOperationExec.cpp:
Auto merged
ndb/src/ndbapi/NdbOperationInt.cpp:
Auto merged
ndb/src/ndbapi/Ndbinit.cpp:
Auto merged
ndb/src/ndbapi/TransporterFacade.cpp:
Auto merged
ndb/src/ndbapi/TransporterFacade.hpp:
Auto merged
ndb/test/ndbapi/Makefile_old:
Auto merged
ndb/test/ndbapi/ScanFunctions.hpp:
Auto merged
ndb/test/ndbapi/ScanInterpretTest.hpp:
Auto merged
ndb/test/ndbapi/testDataBuffers.cpp:
Auto merged
ndb/test/ndbapi/old_dirs/testBackup/Makefile:
Auto merged
ndb/test/ndbapi/old_dirs/testGrep/Makefile:
Auto merged
ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile:
Auto merged
ndb/test/ndbapi/testDict.cpp:
Auto merged
ndb/test/ndbapi/testGrep.cpp:
Auto merged
ndb/test/ndbapi/testIndex.cpp:
Auto merged
ndb/test/ndbapi/testOIBasic.cpp:
Auto merged
ndb/test/ndbapi/testSystemRestart.cpp:
Auto merged
ndb/test/ndbapi/testTimeout.cpp:
Auto merged
ndb/test/src/Makefile_old:
Auto merged
ndb/test/src/UtilTransactions.cpp:
Auto merged
ndb/test/tools/create_index.cpp:
Auto merged
ndb/tools/select_all.cpp:
Auto merged
Diffstat (limited to 'ndb')
195 files changed, 11898 insertions, 12033 deletions
diff --git a/ndb/Epilogue.mk_old b/ndb/Epilogue.mk_old index bcdc54a87f1..36d9ebd6751 100644 --- a/ndb/Epilogue.mk_old +++ b/ndb/Epilogue.mk_old @@ -90,6 +90,7 @@ CCFLAGS_LOC += \ -I$(call fixpath,$(NDB_TOP)/include/transporter) \ -I$(call fixpath,$(NDB_TOP)/include/debugger) \ -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) \ + -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ -I$(call fixpath,$(NDB_TOP)/include/ndbapi) \ -I$(call fixpath,$(NDB_TOP)/include/util) \ -I$(call fixpath,$(NDB_TOP)/include/portlib) \ @@ -105,6 +106,7 @@ CCFLAGS_LOC += \ -I$(call fixpath,$(NDB_TOP)/include/transporter) \ -I$(call fixpath,$(NDB_TOP)/include/debugger) \ -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) \ + -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ -I$(call fixpath,$(NDB_TOP)/include/ndbapi) \ -I$(call fixpath,$(NDB_TOP)/include/util) \ -I$(call fixpath,$(NDB_TOP)/include/portlib) \ diff --git a/ndb/include/kernel/BlockNumbers.h b/ndb/include/kernel/BlockNumbers.h index 84c3fc656a9..e89a82ee0cb 100644 --- a/ndb/include/kernel/BlockNumbers.h +++ b/ndb/include/kernel/BlockNumbers.h @@ -37,6 +37,7 @@ #define DBTUP 0xF9 #define DBDICT 0xFA #define NDBCNTR 0xFB +#define CNTR 0xFB #define QMGR 0xFC #define NDBFS 0xFD #define CMVMI 0xFE diff --git a/ndb/include/kernel/GlobalSignalNumbers.h b/ndb/include/kernel/GlobalSignalNumbers.h index 87385de1f14..7b70f4c3ac0 100644 --- a/ndb/include/kernel/GlobalSignalNumbers.h +++ b/ndb/include/kernel/GlobalSignalNumbers.h @@ -177,43 +177,43 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_API_FAILCONF 113 #define GSN_API_FAILREQ 114 -#define GSN_APPL_CHANGEREP 115 +#define GSN_CNTR_START_REQ 115 // 116 not unused -#define GSN_APPL_HB 117 -#define GSN_APPL_HBREQ 118 -#define GSN_APPL_REGCONF 119 -#define GSN_APPL_REGREF 120 -#define GSN_APPL_REGREQ 121 -#define GSN_APPL_RUN 122 -#define GSN_APPL_STARTCONF 123 -#define GSN_APPL_STARTREG 124 +#define GSN_CNTR_START_REF 117 +#define GSN_CNTR_START_CONF 118 +#define GSN_CNTR_START_REP 119 +// 120 unused +// 121 unused +// 122 unused +// 123 unused +// 124 unused #define GSN_CHECK_LCP_STOP 125 -#define GSN_CLOSE_COMCONF 126 -#define GSN_CLOSE_COMREQ 127 -#define GSN_CM_ACKADD 128 -#define GSN_CM_ACKALARM 129 -#define GSN_CM_ADD 130 -#define GSN_CM_APPCHG 131 +#define GSN_CLOSE_COMCONF 126 // local +#define GSN_CLOSE_COMREQ 127 // local +#define GSN_CM_ACKADD 128 // distr. +// 129 unused +#define GSN_CM_ADD 130 // distr. +// 131 unused // 132 not unused // 133 not unused -#define GSN_CM_HEARTBEAT 134 -#define GSN_CM_INFOCONF 135 -#define GSN_CM_INFOREQ 136 -#define GSN_CM_INIT 137 -#define GSN_CM_NODEINFOCONF 138 -#define GSN_CM_NODEINFOREF 139 -#define GSN_CM_NODEINFOREQ 140 -#define GSN_CM_REGCONF 141 -#define GSN_CM_REGREF 142 -#define GSN_CM_REGREQ 143 -#define GSN_CM_RUN 144 -#define GSN_CMVMI_CFGCONF 145 -#define GSN_CMVMI_CFGREQ 146 -#define GSN_CNTR_CHANGEREP 147 -#define GSN_CNTR_MASTERCONF 148 -#define GSN_CNTR_MASTERREF 149 -#define GSN_CNTR_MASTERREQ 150 -#define GSN_CNTR_WAITREP 151 +#define GSN_CM_HEARTBEAT 134 // distr. +// 135 unused +// 136 unused +// 137 unused +#define GSN_CM_NODEINFOCONF 138 // distr. +#define GSN_CM_NODEINFOREF 139 // distr. +#define GSN_CM_NODEINFOREQ 140 // distr. +#define GSN_CM_REGCONF 141 // distr. +#define GSN_CM_REGREF 142 // distr. +#define GSN_CM_REGREQ 143 // distr. +// 144 unused +// 145 unused +// 146 unused +#define GSN_CM_ADD_REP 147 // local +// 148 unused +// 149 unused +// 150 unused +#define GSN_CNTR_WAITREP 151 // distr. #define GSN_COMMIT 152 #define GSN_COMMIT_FAILCONF 153 #define GSN_COMMIT_FAILREQ 154 @@ -426,11 +426,13 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_NEXT_SCANREF 331 #define GSN_NEXT_SCANREQ 332 #define GSN_NEXTOPERATION 333 -#define GSN_SIZEALT_ACK 334 -#define GSN_SIZEALT_REP 335 -#define GSN_NODE_STATESCONF 336 -#define GSN_NODE_STATESREF 337 -#define GSN_NODE_STATESREQ 338 + +#define GSN_READ_CONFIG_REQ 334 // new name for sizealt, local +#define GSN_READ_CONFIG_CONF 335 // new name for sizealt, local + +// 336 unused +// 337 unused +// 338 unused #define GSN_OPEN_COMCONF 339 #define GSN_OPEN_COMREF 340 #define GSN_OPEN_COMREQ 341 @@ -511,8 +513,8 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_TEST_ORD 407 #define GSN_TESTSIG 408 #define GSN_TIME_SIGNAL 409 -#define GSN_VOTE_MASTERORD 410 -// 411 unused +// 410 unused +// 411 unused // 412 unused #define GSN_TUP_ABORTREQ 414 #define GSN_TUP_ADD_ATTCONF 415 @@ -580,7 +582,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_CHECKNODEGROUPSREQ 471 #define GSN_CHECKNODEGROUPSCONF 472 -#define GSN_ARBIT_CFG 473 +// 473 unused #define GSN_ARBIT_PREPREQ 474 #define GSN_ARBIT_PREPCONF 475 #define GSN_ARBIT_PREPREF 476 diff --git a/ndb/include/kernel/LogLevel.hpp b/ndb/include/kernel/LogLevel.hpp index 3363dc2befd..10cd0d43bee 100644 --- a/ndb/include/kernel/LogLevel.hpp +++ b/ndb/include/kernel/LogLevel.hpp @@ -18,6 +18,7 @@ #define _LOG_LEVEL_HPP #include <ndb_global.h> +#include <mgmapi_config_parameters.h> /** * @@ -45,53 +46,60 @@ public: */ LogLevel & operator= (const LogLevel &); + static const Uint32 MIN_LOGLEVEL_ID = CFG_LOGLEVEL_STARTUP; + enum EventCategory { /** * Events during all kind of startups */ - llStartUp = 0, + llStartUp = CFG_LOGLEVEL_STARTUP - MIN_LOGLEVEL_ID, /** * Events during shutdown */ - llShutdown = 1, + llShutdown = CFG_LOGLEVEL_SHUTDOWN - MIN_LOGLEVEL_ID, /** * Transaction statistics * Job level * TCP/IP speed */ - llStatistic = 2, + llStatistic = CFG_LOGLEVEL_STATISTICS - MIN_LOGLEVEL_ID, /** * Checkpoints */ - llCheckpoint = 3, + llCheckpoint = CFG_LOGLEVEL_CHECKPOINT - MIN_LOGLEVEL_ID, /** * Events during node restart */ - llNodeRestart = 4, + llNodeRestart = CFG_LOGLEVEL_NODERESTART - MIN_LOGLEVEL_ID, /** * Events related to connection / communication */ - llConnection = 5, + llConnection = CFG_LOGLEVEL_CONNECTION - MIN_LOGLEVEL_ID, /** * Assorted event w.r.t unexpected happenings */ - llError = 6, + llError = CFG_LOGLEVEL_ERROR - MIN_LOGLEVEL_ID, + + /** + * Assorted event w.r.t warning + */ + llWarning = CFG_LOGLEVEL_WARNING - MIN_LOGLEVEL_ID, /** * Assorted event w.r.t information */ - llInfo = 7, + llInfo = CFG_LOGLEVEL_INFO - MIN_LOGLEVEL_ID, /** * Events related to global replication */ - llGrep = 8 + llGrep = CFG_LOGLEVEL_GREP - MIN_LOGLEVEL_ID }; struct LogLevelCategoryName { @@ -107,7 +115,7 @@ public: /** * No of categories */ -#define _LOGLEVEL_CATEGORIES 9 +#define _LOGLEVEL_CATEGORIES 10 static const Uint32 LOGLEVEL_CATEGORIES = _LOGLEVEL_CATEGORIES; void clear(); diff --git a/ndb/include/kernel/kernel_config_parameters.h b/ndb/include/kernel/kernel_config_parameters.h new file mode 100644 index 00000000000..2f63efa4b6c --- /dev/null +++ b/ndb/include/kernel/kernel_config_parameters.h @@ -0,0 +1,56 @@ +#ifndef DB_CONFIG_PARAMTERS_H +#define DB_CONFIG_PARAMTERS_H + +#define PRIVATE_BASE 14000 + +#define CFG_ACC_DIR_RANGE (PRIVATE_BASE + 1) +#define CFG_ACC_DIR_ARRAY (PRIVATE_BASE + 2) +#define CFG_ACC_FRAGMENT (PRIVATE_BASE + 3) +#define CFG_ACC_OP_RECS (PRIVATE_BASE + 4) +#define CFG_ACC_OVERFLOW_RECS (PRIVATE_BASE + 5) +#define CFG_ACC_PAGE8 (PRIVATE_BASE + 6) +#define CFG_ACC_ROOT_FRAG (PRIVATE_BASE + 7) +#define CFG_ACC_TABLE (PRIVATE_BASE + 8) +#define CFG_ACC_SCAN (PRIVATE_BASE + 9) + +#define CFG_DICT_ATTRIBUTE (PRIVATE_BASE + 10) +#define CFG_DICT_CONNECT (PRIVATE_BASE + 11) +#define CFG_DICT_FRAG_CONNECT (PRIVATE_BASE + 12) +#define CFG_DICT_TABLE (PRIVATE_BASE + 13) +#define CFG_DICT_TC_CONNECT (PRIVATE_BASE + 14) + +#define CFG_DIH_API_CONNECT (PRIVATE_BASE + 15) +#define CFG_DIH_CONNECT (PRIVATE_BASE + 16) +#define CFG_DIH_FRAG_CONNECT (PRIVATE_BASE + 17) +#define CFG_DIH_MORE_NODES (PRIVATE_BASE + 18) +#define CFG_DIH_REPLICAS (PRIVATE_BASE + 19) +#define CFG_DIH_TABLE (PRIVATE_BASE + 20) + +#define CFG_LQH_FRAG (PRIVATE_BASE + 21) +#define CFG_LQH_CONNECT (PRIVATE_BASE + 22) +#define CFG_LQH_TABLE (PRIVATE_BASE + 23) +#define CFG_LQH_TC_CONNECT (PRIVATE_BASE + 24) +#define CFG_LQH_REPLICAS (PRIVATE_BASE + 25) +#define CFG_LQH_LOG_FILES (PRIVATE_BASE + 26) +#define CFG_LQH_SCAN (PRIVATE_BASE + 27) + +#define CFG_TC_API_CONNECT (PRIVATE_BASE + 28) +#define CFG_TC_TC_CONNECT (PRIVATE_BASE + 29) +#define CFG_TC_TABLE (PRIVATE_BASE + 30) +#define CFG_TC_SCAN (PRIVATE_BASE + 31) +#define CFG_TC_LOCAL_SCAN (PRIVATE_BASE + 32) + +#define CFG_TUP_FRAG (PRIVATE_BASE + 33) +#define CFG_TUP_OP_RECS (PRIVATE_BASE + 34) +#define CFG_TUP_PAGE (PRIVATE_BASE + 35) +#define CFG_TUP_PAGE_RANGE (PRIVATE_BASE + 36) +#define CFG_TUP_TABLE (PRIVATE_BASE + 37) +#define CFG_TUP_TABLE_DESC (PRIVATE_BASE + 38) +#define CFG_TUP_STORED_PROC (PRIVATE_BASE + 39) + +#define CFG_TUX_INDEX (PRIVATE_BASE + 40) +#define CFG_TUX_FRAGMENT (PRIVATE_BASE + 41) +#define CFG_TUX_ATTRIBUTE (PRIVATE_BASE + 42) +#define CFG_TUX_SCAN_OP (PRIVATE_BASE + 43) + +#endif diff --git a/ndb/include/kernel/signaldata/CheckNodeGroups.hpp b/ndb/include/kernel/signaldata/CheckNodeGroups.hpp index 9b2f847e128..b3e79949c68 100644 --- a/ndb/include/kernel/signaldata/CheckNodeGroups.hpp +++ b/ndb/include/kernel/signaldata/CheckNodeGroups.hpp @@ -37,13 +37,11 @@ public: Uint32 requestType; // direct flag, output code Uint32 output; }; - union { - Uint32 nodeId; // nodeId input for GetNodeGroupMembers - NodeBitmask mask; /* set of NDB nodes, input for ArbitCheck, - * output for GetNodeGroupMembers - */ - }; + Uint32 nodeId; // nodeId input for GetNodeGroupMembers + NodeBitmask mask; /* set of NDB nodes, input for ArbitCheck, + * output for GetNodeGroupMembers + */ enum RequestType { Direct = 0x1, ArbitCheck = 0x2, @@ -57,7 +55,7 @@ public: Partitioning = 3 // possible network partitioning }; - STATIC_CONST( SignalLength = 2 + NodeBitmask::Size ); + STATIC_CONST( SignalLength = 3 + NodeBitmask::Size ); }; #endif diff --git a/ndb/include/kernel/signaldata/CntrStart.hpp b/ndb/include/kernel/signaldata/CntrStart.hpp new file mode 100644 index 00000000000..abdd1003c0f --- /dev/null +++ b/ndb/include/kernel/signaldata/CntrStart.hpp @@ -0,0 +1,69 @@ +#ifndef CNTR_START_HPP +#define CNTR_START_HPP + +#include <NodeBitmask.hpp> + +/** + * + */ +class CntrStartReq { + /** + * Sender(s) / Reciver(s) + */ + friend class Ndbcntr; + + friend bool printCNTR_START_REQ(FILE*, const Uint32 *, Uint32, Uint16); + +public: + STATIC_CONST( SignalLength = 3 ); +private: + + Uint32 nodeId; + Uint32 startType; + Uint32 lastGci; +}; + +class CntrStartRef { + /** + * Sender(s) / Reciver(s) + */ + friend class Ndbcntr; + + friend bool printCNTR_START_REF(FILE*, const Uint32 *, Uint32, Uint16); +public: + STATIC_CONST( SignalLength = 2 ); + + enum ErrorCode { + OK = 0, + NotMaster = 1, + StopInProgress = 2 + }; +private: + + Uint32 errorCode; + Uint32 masterNodeId; +}; + +class CntrStartConf { + /** + * Sender(s) / Reciver(s) + */ + friend class Ndbcntr; + friend struct UpgradeStartup; + + friend bool printCNTR_START_CONF(FILE*, const Uint32 *, Uint32, Uint16); + +public: + STATIC_CONST( SignalLength = 4 + 2 * NdbNodeBitmask::Size ); + +private: + + Uint32 startType; + Uint32 startGci; + Uint32 masterNodeId; + Uint32 noStartNodes; + Uint32 startedNodes[NdbNodeBitmask::Size]; + Uint32 startingNodes[NdbNodeBitmask::Size]; +}; + +#endif diff --git a/ndb/include/kernel/signaldata/CreateFragmentation.hpp b/ndb/include/kernel/signaldata/CreateFragmentation.hpp index a2f45a9580d..7d53dd91154 100644 --- a/ndb/include/kernel/signaldata/CreateFragmentation.hpp +++ b/ndb/include/kernel/signaldata/CreateFragmentation.hpp @@ -88,7 +88,7 @@ class CreateFragmentationConf { friend bool printCREATE_FRAGMENTATION_CONF(FILE *, const Uint32 *, Uint32, Uint16); public: - STATIC_CONST( SignalLength = 3 ); + STATIC_CONST( SignalLength = 4 ); SECTION( FRAGMENTS = 0 ); private: diff --git a/ndb/include/kernel/signaldata/DictTabInfo.hpp b/ndb/include/kernel/signaldata/DictTabInfo.hpp index 791388d5df8..813b0063d35 100644 --- a/ndb/include/kernel/signaldata/DictTabInfo.hpp +++ b/ndb/include/kernel/signaldata/DictTabInfo.hpp @@ -100,6 +100,7 @@ public: CustomTriggerId = 25, FrmLen = 26, FrmData = 27, + FragmentCount = 128, // No of fragments in table (!fragment replicas) TableEnd = 999, AttributeName = 1000, // String, Mandatory @@ -277,6 +278,7 @@ public: Uint32 CustomTriggerId; Uint32 FrmLen; char FrmData[MAX_FRM_DATA_SIZE]; + Uint32 FragmentCount; void init(); }; diff --git a/ndb/include/kernel/signaldata/DropTab.hpp b/ndb/include/kernel/signaldata/DropTab.hpp index 906f952d852..dd3946d8cc0 100644 --- a/ndb/include/kernel/signaldata/DropTab.hpp +++ b/ndb/include/kernel/signaldata/DropTab.hpp @@ -101,7 +101,8 @@ public: NoSuchTable = 1, DropWoPrep = 2, // Calling Drop with first calling PrepDrop PrepDropInProgress = 3, - DropInProgress = 4 + DropInProgress = 4, + NF_FakeErrorREF = 5 }; private: diff --git a/ndb/include/kernel/signaldata/EventSubscribeReq.hpp b/ndb/include/kernel/signaldata/EventSubscribeReq.hpp index 2ac62be19a3..fd2821ea31d 100644 --- a/ndb/include/kernel/signaldata/EventSubscribeReq.hpp +++ b/ndb/include/kernel/signaldata/EventSubscribeReq.hpp @@ -39,7 +39,7 @@ class EventSubscribeReq { friend class MgmtSrvr; public: - STATIC_CONST( SignalLength = 14 ); + STATIC_CONST( SignalLength = 22 ); private: /** * Note: If you use the same blockRef as you have used earlier, @@ -53,8 +53,8 @@ private: */ Uint32 noOfEntries; - Uint32 theCategories[6]; - Uint32 theLevels[6]; + Uint32 theCategories[10]; + Uint32 theLevels[10]; }; #endif diff --git a/ndb/include/kernel/signaldata/FsOpenReq.hpp b/ndb/include/kernel/signaldata/FsOpenReq.hpp index b84d78ba9dd..906bb947128 100644 --- a/ndb/include/kernel/signaldata/FsOpenReq.hpp +++ b/ndb/include/kernel/signaldata/FsOpenReq.hpp @@ -39,6 +39,7 @@ class FsOpenReq { friend class Backup; friend class Dbdict; friend class Ndbcntr; // For initial start... + friend class Dbdih; /** * For printing diff --git a/ndb/include/kernel/signaldata/KeyInfo.hpp b/ndb/include/kernel/signaldata/KeyInfo.hpp index b839a2c2035..a4c698f89b2 100644 --- a/ndb/include/kernel/signaldata/KeyInfo.hpp +++ b/ndb/include/kernel/signaldata/KeyInfo.hpp @@ -25,6 +25,7 @@ class KeyInfo { */ friend class DbUtil; friend class NdbOperation; + friend class NdbScanOperation; /** * Reciver(s) diff --git a/ndb/include/kernel/signaldata/PrepDropTab.hpp b/ndb/include/kernel/signaldata/PrepDropTab.hpp index e9cc28fed0c..c54b2474aa3 100644 --- a/ndb/include/kernel/signaldata/PrepDropTab.hpp +++ b/ndb/include/kernel/signaldata/PrepDropTab.hpp @@ -88,7 +88,8 @@ public: NoSuchTable = 1, PrepDropInProgress = 2, DropInProgress = 3, - InvalidTableState = 4 + InvalidTableState = 4, + NF_FakeErrorREF = 5 }; private: @@ -137,7 +138,8 @@ public: enum ErrorCode { NoSuchTable = 1, IllegalTableState = 2, - DropInProgress = 3 + DropInProgress = 3, + NF_FakeErrorREF = 4 }; Uint32 tableId; diff --git a/ndb/include/kernel/signaldata/ReadConfig.hpp b/ndb/include/kernel/signaldata/ReadConfig.hpp new file mode 100644 index 00000000000..0835b252a32 --- /dev/null +++ b/ndb/include/kernel/signaldata/ReadConfig.hpp @@ -0,0 +1,24 @@ +#ifndef READ_CONFIG_HPP +#define READ_CONFIG_HPP + +/** + */ +class ReadConfigReq { +public: + STATIC_CONST( SignalLength = 3 ); + + Uint32 senderRef; + Uint32 senderData; + Uint32 noOfParameters; // 0 Means read all relevant for block + Uint32 parameters[1]; // see mgmapi_config_parameters.h +}; + +class ReadConfigConf { +public: + STATIC_CONST( SignalLength = 2 ); + + Uint32 senderRef; + Uint32 senderData; +}; + +#endif diff --git a/ndb/include/kernel/signaldata/ReadNodesConf.hpp b/ndb/include/kernel/signaldata/ReadNodesConf.hpp index f3176cbf0e8..0507007f71a 100644 --- a/ndb/include/kernel/signaldata/ReadNodesConf.hpp +++ b/ndb/include/kernel/signaldata/ReadNodesConf.hpp @@ -48,11 +48,13 @@ class ReadNodesConf { friend class Suma; friend class Grep; + friend bool printREAD_NODES_CONF(FILE*, const Uint32 *, Uint32, Uint16); public: - STATIC_CONST( SignalLength = 2 + 6*NodeBitmask::Size ); + STATIC_CONST( SignalLength = 3 + 5*NdbNodeBitmask::Size ); private: Uint32 noOfNodes; + Uint32 ndynamicId; /** * @@ -63,47 +65,21 @@ private: /** * This array defines all the ndb nodes in the system */ - Uint32 allNodes[NodeBitmask::Size]; - - /** - * This array describes wheather the nodes are currently active - * - * NOTE Not valid when send from Qmgr - */ - Uint32 inactiveNodes[NodeBitmask::Size]; + union { + Uint32 allNodes[NdbNodeBitmask::Size]; + Uint32 definedNodes[NdbNodeBitmask::Size]; + }; /** - * This array describes the version id of the nodes - * The version id is a 4 bit number + * This array describes wheather the nodes are currently active * * NOTE Not valid when send from Qmgr */ - Uint32 theVersionIds[4*NodeBitmask::Size]; + Uint32 inactiveNodes[NdbNodeBitmask::Size]; - static void setVersionId(NodeId, Uint8 versionId, Uint32 theVersionIds[]); - static Uint8 getVersionId(NodeId, const Uint32 theVersionIds[]); + Uint32 clusterNodes[NdbNodeBitmask::Size]; // From Qmgr + Uint32 startingNodes[NdbNodeBitmask::Size]; // From Cntr + Uint32 startedNodes[NdbNodeBitmask::Size]; // From Cntr }; -inline -void -ReadNodesConf::setVersionId(NodeId nodeId, Uint8 versionId, - Uint32 theVersionIds[]){ - const int word = nodeId >> 3; - const int shift = (nodeId & 7) << 2; - - const Uint32 mask = ~(((Uint32)15) << shift); - const Uint32 tmp = theVersionIds[word]; - - theVersionIds[word] = (tmp & mask) | ((((Uint32)versionId) & 15) << shift); -} - -inline -Uint8 -ReadNodesConf::getVersionId(NodeId nodeId, const Uint32 theVersionIds[]){ - const int word = nodeId >> 3; - const int shift = (nodeId & 7) << 2; - - return (theVersionIds[word] >> shift) & 15; -} - #endif diff --git a/ndb/include/kernel/signaldata/ScanTab.hpp b/ndb/include/kernel/signaldata/ScanTab.hpp index efd8a4918ab..6cef4381c07 100644 --- a/ndb/include/kernel/signaldata/ScanTab.hpp +++ b/ndb/include/kernel/signaldata/ScanTab.hpp @@ -33,8 +33,8 @@ class ScanTabReq { /** * Sender(s) */ - friend class NdbOperation; friend class NdbConnection; + friend class NdbScanOperation; /** * For printing @@ -73,6 +73,7 @@ private: static Uint8 getHoldLockFlag(const UintR & requestInfo); static Uint8 getReadCommittedFlag(const UintR & requestInfo); static Uint8 getRangeScanFlag(const UintR & requestInfo); + static Uint8 getScanBatch(const UintR & requestInfo); /** * Set:ers for requestInfo @@ -83,7 +84,7 @@ private: static void setHoldLockFlag(UintR & requestInfo, Uint32 flag); static void setReadCommittedFlag(UintR & requestInfo, Uint32 flag); static void setRangeScanFlag(UintR & requestInfo, Uint32 flag); - + static void setScanBatch(Uint32& requestInfo, Uint32 sz); }; /** @@ -94,10 +95,11 @@ private: h = Hold lock mode - 1 Bit 10 c = Read Committed - 1 Bit 11 x = Range Scan (TUX) - 1 Bit 15 + b = Scan batch - 5 Bit 16-19 (max 15) 1111111111222222222233 01234567890123456789012345678901 - ppppppppl hc x + ppppppppl hc xbbbbb */ #define PARALLELL_SHIFT (0) @@ -115,6 +117,9 @@ private: #define RANGE_SCAN_SHIFT (15) #define RANGE_SCAN_MASK (1) +#define SCAN_BATCH_SHIFT (16) +#define SCAN_BATCH_MASK (31) + inline Uint8 ScanTabReq::getParallelism(const UintR & requestInfo){ @@ -146,6 +151,12 @@ ScanTabReq::getRangeScanFlag(const UintR & requestInfo){ } inline +Uint8 +ScanTabReq::getScanBatch(const Uint32 & requestInfo){ + return (Uint8)((requestInfo >> SCAN_BATCH_SHIFT) & SCAN_BATCH_MASK); +} + +inline void ScanTabReq::clearRequestInfo(UintR & requestInfo){ requestInfo = 0; @@ -186,6 +197,12 @@ ScanTabReq::setRangeScanFlag(UintR & requestInfo, Uint32 flag){ requestInfo |= (flag << RANGE_SCAN_SHIFT); } +inline +void +ScanTabReq::setScanBatch(Uint32 & requestInfo, Uint32 flag){ + ASSERT_MAX(flag, SCAN_BATCH_MASK, "ScanTabReq::setScanBatch"); + requestInfo |= (flag << SCAN_BATCH_SHIFT); +} /** * @@ -213,7 +230,8 @@ public: * Length of signal */ STATIC_CONST( SignalLength = 4 ); - + static const Uint32 EndOfData = (1 << 31); + private: // Type definitions @@ -225,29 +243,15 @@ private: UintR requestInfo; // DATA 1 UintR transId1; // DATA 2 UintR transId2; // DATA 3 -#if 0 - UintR operLenAndIdx[16]; // DATA 4-19 - - /** - * Get:ers for operLenAndIdx - */ - static Uint32 getLen(const UintR & operLenAndIdx); - static Uint8 getIdx(const UintR & operLenAndIdx); -#endif - - /** - * Get:ers for requestInfo - */ - static Uint8 getOperations(const UintR & reqInfo); - static Uint8 getScanStatus(const UintR & reqInfo); - - /** - * Set:ers for requestInfo - */ - static void setOperations(UintR & reqInfo, Uint32 ops); - static void setScanStatus(UintR & reqInfo, Uint32 stat); + struct OpData { + Uint32 apiPtrI; + Uint32 tcPtrI; + Uint32 info; + }; + static Uint32 getLength(Uint32 opDataInfo) { return opDataInfo >> 5; }; + static Uint32 getRows(Uint32 opDataInfo) { return opDataInfo & 31;} }; /** @@ -267,33 +271,6 @@ private: #define STATUS_SHIFT (8) #define STATUS_MASK (0xFF) -inline -Uint8 -ScanTabConf::getOperations(const UintR & reqInfo){ - return (Uint8)((reqInfo >> OPERATIONS_SHIFT) & OPERATIONS_MASK); -} - -inline -void -ScanTabConf::setOperations(UintR & requestInfo, Uint32 ops){ - ASSERT_MAX(ops, OPERATIONS_MASK, "ScanTabConf::setOperations"); - requestInfo |= (ops << OPERATIONS_SHIFT); -} - -inline -Uint8 -ScanTabConf::getScanStatus(const UintR & reqInfo){ - return (Uint8)((reqInfo >> STATUS_SHIFT) & STATUS_MASK); -} - -inline -void -ScanTabConf::setScanStatus(UintR & requestInfo, Uint32 stat){ - ASSERT_MAX(stat, STATUS_MASK, "ScanTabConf::setScanStatus"); - requestInfo |= (stat << STATUS_SHIFT); -} - - /** * * SENDER: Dbtc, API diff --git a/ndb/include/kernel/signaldata/SetLogLevelOrd.hpp b/ndb/include/kernel/signaldata/SetLogLevelOrd.hpp index 680e9b25a49..c3be808cc41 100644 --- a/ndb/include/kernel/signaldata/SetLogLevelOrd.hpp +++ b/ndb/include/kernel/signaldata/SetLogLevelOrd.hpp @@ -18,6 +18,7 @@ #define SET_LOGLEVEL_ORD_HPP #include <LogLevel.hpp> +#include "SignalData.hpp" /** * diff --git a/ndb/include/kernel/signaldata/TcCommit.hpp b/ndb/include/kernel/signaldata/TcCommit.hpp index 43eb7be1c39..b7f3fbbb361 100644 --- a/ndb/include/kernel/signaldata/TcCommit.hpp +++ b/ndb/include/kernel/signaldata/TcCommit.hpp @@ -33,6 +33,7 @@ class TcCommitConf { * Reciver(s) */ friend class Ndb; + friend class NdbConnection; public: STATIC_CONST( SignalLength = 3 ); diff --git a/ndb/include/kernel/signaldata/TcKeyReq.hpp b/ndb/include/kernel/signaldata/TcKeyReq.hpp index df0a00da3e0..f7d3c2e3282 100644 --- a/ndb/include/kernel/signaldata/TcKeyReq.hpp +++ b/ndb/include/kernel/signaldata/TcKeyReq.hpp @@ -38,6 +38,7 @@ class TcKeyReq { friend class Ndbcntr; friend class NdbOperation; friend class NdbIndexOperation; + friend class NdbScanOperation; friend class DbUtil; /** diff --git a/ndb/include/kernel/signaldata/UpgradeStartup.hpp b/ndb/include/kernel/signaldata/UpgradeStartup.hpp new file mode 100644 index 00000000000..badc7ca0e4d --- /dev/null +++ b/ndb/include/kernel/signaldata/UpgradeStartup.hpp @@ -0,0 +1,36 @@ +#ifndef NDB_UPGRADE_STARTUP +#define NDB_UPGRADE_STARTUP + +struct UpgradeStartup { + + static void installEXEC(SimulatedBlock*); + + static const Uint32 GSN_CM_APPCHG = 131; + static const Uint32 GSN_CNTR_MASTERCONF = 148; + static const Uint32 GSN_CNTR_MASTERREF = 149; + static const Uint32 GSN_CNTR_MASTERREQ = 150; + + static void sendCmAppChg(Ndbcntr&, Signal *, Uint32 startLevel); + static void execCM_APPCHG(SimulatedBlock& block, Signal*); + static void sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n); + static void execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal); + + struct CntrMasterReq { + STATIC_CONST( SignalLength = 4 + NdbNodeBitmask::Size ); + + Uint32 userBlockRef; + Uint32 userNodeId; + Uint32 typeOfStart; + Uint32 noRestartNodes; + Uint32 theNodes[NdbNodeBitmask::Size]; + }; + + struct CntrMasterConf { + STATIC_CONST( SignalLength = 1 + NdbNodeBitmask::Size ); + + Uint32 noStartNodes; + Uint32 theNodes[NdbNodeBitmask::Size]; + }; +}; + +#endif diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h index 0ecb19eaa76..7b2f728bda8 100644 --- a/ndb/include/mgmapi/mgmapi.h +++ b/ndb/include/mgmapi/mgmapi.h @@ -84,9 +84,10 @@ extern "C" { NDB_MGM_NODE_TYPE_API = 0, /*/< An application node (API)*/ NDB_MGM_NODE_TYPE_NDB = 1, /*/< A database node (DB)*/ NDB_MGM_NODE_TYPE_MGM = 2, /*/< A management server node (MGM)*/ + NDB_MGM_NODE_TYPE_REP = 3, ///< A replication node NDB_MGM_NODE_TYPE_MIN = 0, /*/< Min valid value*/ - NDB_MGM_NODE_TYPE_MAX = 2 /*/< Max valid value*/ + NDB_MGM_NODE_TYPE_MAX = 3 /*/< Max valid value*/ }; /** @@ -199,6 +200,8 @@ extern "C" { int node_group; ///< Node group of node ///< (only valid for DB nodes) int version; ///< Internal version number + int connect_count; ///< No of times node has connected + ///< or disconnected to the mgm srv }; /** @@ -654,6 +657,36 @@ extern "C" { int ndb_mgm_exit_single_user(NdbMgmHandle handle, struct ndb_mgm_reply* reply); + /** + * Get configuration + * @param handle NDB management handle. + * @param version Version of configuration, 0 means latest + * @see MAKE_VERSION + * @Note the caller must free the pointer returned. + */ + struct ndb_mgm_configuration * ndb_mgm_get_configuration(NdbMgmHandle handle, + unsigned version); + /** + * Config iterator + */ + typedef struct ndb_mgm_configuration_iterator ndb_mgm_configuration_iterator; + + ndb_mgm_configuration_iterator* ndb_mgm_create_configuration_iterator + (struct ndb_mgm_configuration *, unsigned type_of_section); + void ndb_mgm_destroy_iterator(ndb_mgm_configuration_iterator*); + + int ndb_mgm_first(ndb_mgm_configuration_iterator*); + int ndb_mgm_next(ndb_mgm_configuration_iterator*); + int ndb_mgm_valid(const ndb_mgm_configuration_iterator*); + int ndb_mgm_find(ndb_mgm_configuration_iterator*, + int param, unsigned value); + + int ndb_mgm_get_int_parameter(const ndb_mgm_configuration_iterator*, + int param, unsigned * value); + int ndb_mgm_get_int64_parameter(const ndb_mgm_configuration_iterator*, + int param, unsigned long long * value); + int ndb_mgm_get_string_parameter(const ndb_mgm_configuration_iterator*, + int param, const char ** value); #ifdef __cplusplus } #endif diff --git a/ndb/include/mgmapi/mgmapi_config_parameters.h b/ndb/include/mgmapi/mgmapi_config_parameters.h new file mode 100644 index 00000000000..9ad0967854f --- /dev/null +++ b/ndb/include/mgmapi/mgmapi_config_parameters.h @@ -0,0 +1,142 @@ +#ifndef MGMAPI_CONFIG_PARAMTERS_H +#define MGMAPI_CONFIG_PARAMTERS_H + + +#define CFG_SYS_NAME 3 +#define CFG_SYS_PRIMARY_MGM_NODE 1 +#define CFG_SYS_CONFIG_GENERATION 2 +#define CFG_SYS_REPLICATION_ROLE 7 + +#define CFG_NODE_ID 3 +#define CFG_NODE_BYTE_ORDER 4 +#define CFG_NODE_HOST 5 +#define CFG_NODE_SYSTEM 6 + +/** + * DB config parameters + */ +#define CFG_DB_NO_SAVE_MSGS 100 + +#define CFG_DB_NO_REPLICAS 101 +#define CFG_DB_NO_TABLES 102 +#define CFG_DB_NO_ATTRIBUTES 103 +#define CFG_DB_NO_INDEXES 104 +#define CFG_DB_NO_TRIGGERS 105 + +#define CFG_DB_NO_TRANSACTIONS 106 +#define CFG_DB_NO_OPS 107 +#define CFG_DB_NO_SCANS 108 +#define CFG_DB_NO_TRIGGER_OPS 109 +#define CFG_DB_NO_INDEX_OPS 110 + +#define CFG_DB_TRANS_BUFFER_MEM 111 +#define CFG_DB_DATA_MEM 112 +#define CFG_DB_INDEX_MEM 113 +#define CFG_DB_MEMLOCK 114 + +#define CFG_DB_START_PARTIAL_TIMEOUT 115 +#define CFG_DB_START_PARTITION_TIMEOUT 116 +#define CFG_DB_START_FAILURE_TIMEOUT 117 + +#define CFG_DB_HEARTBEAT_INTERVAL 118 +#define CFG_DB_API_HEARTBEAT_INTERVAL 119 +#define CFG_DB_LCP_INTERVAL 120 +#define CFG_DB_GCP_INTERVAL 121 +#define CFG_DB_ARBIT_TIMEOUT 122 + +#define CFG_DB_WATCHDOG_INTERVAL 123 +#define CFG_DB_STOP_ON_ERROR 124 + +#define CFG_DB_FILESYSTEM_PATH 125 +#define CFG_DB_NO_REDOLOG_FILES 126 +#define CFG_DB_DISC_BANDWIDTH 127 +#define CFG_DB_SR_DISC_BANDWITH 128 + +#define CFG_DB_TRANSACTION_CHECK_INTERVAL 129 +#define CFG_DB_TRANSACTION_INACTIVE_TIMEOUT 130 +#define CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT 131 + +#define CFG_DB_PARALLEL_BACKUPS 132 +#define CFG_DB_BACKUP_MEM 133 +#define CFG_DB_BACKUP_DATA_BUFFER_MEM 134 +#define CFG_DB_BACKUP_LOG_BUFFER_MEM 135 +#define CFG_DB_BACKUP_WRITE_SIZE 136 + +#define CFG_LOGLEVEL_STARTUP 137 +#define CFG_LOGLEVEL_SHUTDOWN 138 +#define CFG_LOGLEVEL_STATISTICS 139 +#define CFG_LOGLEVEL_CHECKPOINT 140 +#define CFG_LOGLEVEL_NODERESTART 141 +#define CFG_LOGLEVEL_CONNECTION 142 +#define CFG_LOGLEVEL_INFO 143 +#define CFG_LOGLEVEL_WARNING 144 +#define CFG_LOGLEVEL_ERROR 145 +#define CFG_LOGLEVEL_GREP 146 +#define CFG_LOG_DESTINATION 147 + +#define CFG_NODE_ARBIT_RANK 200 +#define CFG_NODE_ARBIT_DELAY 201 + +#define CFG_MGM_PORT 300 + +#define CFG_CONNECTION_NODE_1 400 +#define CFG_CONNECTION_NODE_2 401 +#define CFG_CONNECTION_SEND_SIGNAL_ID 402 +#define CFG_CONNECTION_CHECKSUM 403 +#define CFG_CONNECTION_NODE_1_SYSTEM 404 +#define CFG_CONNECTION_NODE_2_SYSTEM 405 + +#define CFG_TCP_HOSTNAME_1 450 +#define CFG_TCP_HOSTNAME_2 451 +#define CFG_TCP_SERVER 452 +#define CFG_TCP_SERVER_PORT 453 +#define CFG_TCP_SEND_BUFFER_SIZE 454 +#define CFG_TCP_RECEIVE_BUFFER_SIZE 455 +#define CFG_TCP_PROXY 456 + +#define CFG_SHM_SEND_SIGNAL_ID 500 +#define CFG_SHM_CHECKSUM 501 +#define CFG_SHM_KEY 502 +#define CFG_SHM_BUFFER_MEM 503 + +#define CFG_SCI_ID_0 550 +#define CFG_SCI_ID_1 551 +#define CFG_SCI_SEND_LIMIT 552 +#define CFG_SCI_BUFFER_MEM 553 +#define CFG_SCI_NODE1_ADAPTERS 554 +#define CFG_SCI_NODE1_ADAPTER0 555 +#define CFG_SCI_NODE1_ADAPTER1 556 +#define CFG_SCI_NODE2_ADAPTERS 554 +#define CFG_SCI_NODE2_ADAPTER0 555 +#define CFG_SCI_NODE2_ADAPTER1 556 + +#define CFG_OSE_HOSTNAME_1 600 +#define CFG_OSE_HOSTNAME_2 601 +#define CFG_OSE_PRIO_A_SIZE 602 +#define CFG_OSE_PRIO_B_SIZE 603 +#define CFG_OSE_RECEIVE_ARRAY_SIZE 604 + +#define CFG_REP_HEARTBEAT_INTERVAL 700 + +/** + * Internal + */ +#define CFG_DB_STOP_ON_ERROR_INSERT 1 + +#define CFG_TYPE_OF_SECTION 999 +#define CFG_SECTION_SYSTEM 1000 +#define CFG_SECTION_NODE 2000 +#define CFG_SECTION_CONNECTION 3000 + +#define NODE_TYPE_DB 0 +#define NODE_TYPE_API 1 +#define NODE_TYPE_MGM 2 +#define NODE_TYPE_REP 3 +#define NODE_TYPE_EXT_REP 4 + +#define CONNECTION_TYPE_TCP 0 +#define CONNECTION_TYPE_SHM 1 +#define CONNECTION_TYPE_SCI 2 +#define CONNECTION_TYPE_OSE 3 + +#endif diff --git a/ndb/include/mgmapi/mgmapi_config_parameters_debug.h b/ndb/include/mgmapi/mgmapi_config_parameters_debug.h new file mode 100644 index 00000000000..0241dca90ef --- /dev/null +++ b/ndb/include/mgmapi/mgmapi_config_parameters_debug.h @@ -0,0 +1,8 @@ +#ifndef MGMAPI_CONFIG_PARAMTERS_DEBUG_H +#define MGMAPI_CONFIG_PARAMTERS_DEBUG_H + +#include "mgmapi_config_parameters.h" + +#define CFG_DB_STOP_ON_ERROR_INSERT 1 + +#endif diff --git a/ndb/include/mgmcommon/ConfigRetriever.hpp b/ndb/include/mgmcommon/ConfigRetriever.hpp index ff60e730d45..50d333b54dd 100644 --- a/ndb/include/mgmcommon/ConfigRetriever.hpp +++ b/ndb/include/mgmcommon/ConfigRetriever.hpp @@ -18,7 +18,7 @@ #define ConfigRetriever_H #include <ndb_types.h> -#include <Properties.hpp> +#include <mgmapi.h> /** * @class ConfigRetriever @@ -44,11 +44,11 @@ public: * to establish a connection. This is repeated until a connection is * established, so the function hangs until a connection is established. * - * @return Properties object if succeeded, + * @return ndb_mgm_configuration object if succeeded, * NULL if erroneous local config file or configuration error. */ - class Properties * getConfig(const char * nodeType, int versionId); - + struct ndb_mgm_configuration * getConfig(int versionId, int nodeType); + const char * getErrorString(); /** @@ -71,22 +71,17 @@ public: * @return Node id of this node (as stated in local config or connectString) */ inline Uint32 getOwnNodeId() { return _ownNodeId; } - - /** - * Get configuration object - */ - class Properties * getConfig(int versionId); + /** * Get config using socket */ - class Properties * getConfig(const char * mgmhost, unsigned int port, - Uint32 nodeId, int versionId); + struct ndb_mgm_configuration * getConfig(const char * mgmhost, short port, + int versionId); /** * Get config from file */ - class Properties * getConfig(const char * filename, Uint32 nodeId, - int versionId); + struct ndb_mgm_configuration * getConfig(const char * file, int versionId); private: char * errorString; enum ErrorType { @@ -97,18 +92,17 @@ private: void setError(ErrorType, const char * errorMsg); - /** - * Verifies that received configuration is correct - */ - bool verifyProperties(const char* nodeType, Properties *p, - Uint32 nodeId, int versionId); - char * _localConfigFileName; struct LocalConfig * _localConfig; int _ownNodeId; char * m_connectString; char * m_defaultConnectString; + + /** + * Verify config + */ + bool verifyConfig(const struct ndb_mgm_configuration *, int type); }; #endif diff --git a/ndb/include/mgmcommon/IPCConfig.hpp b/ndb/include/mgmcommon/IPCConfig.hpp index 626242865cb..ebe65b53b59 100644 --- a/ndb/include/mgmcommon/IPCConfig.hpp +++ b/ndb/include/mgmcommon/IPCConfig.hpp @@ -58,6 +58,10 @@ public: void print() const { props->print(); } + static Uint32 configureTransporters(Uint32 nodeId, + const class ndb_mgm_configuration &, + class TransporterRegistry &); + private: NodeId the_ownId; Properties * props; diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp index 3acfcd194e8..e903deef83b 100644 --- a/ndb/include/ndbapi/Ndb.hpp +++ b/ndb/include/ndbapi/Ndb.hpp @@ -867,6 +867,7 @@ class NdbObjectIdMap; class NdbOperation; class NdbEventOperationImpl; class NdbScanOperation; +class NdbIndexScanOperation; class NdbIndexOperation; class NdbConnection; class NdbApiSignal; @@ -875,7 +876,6 @@ class NdbLabel; class NdbBranch; class NdbSubroutine; class NdbCall; -class NdbScanReceiver; class Table; class BaseString; class NdbEventOperation; @@ -960,8 +960,9 @@ class Ndb friend class NdbConnection; friend class Table; friend class NdbApiSignal; - friend class NdbScanReceiver; friend class NdbIndexOperation; + friend class NdbScanOperation; + friend class NdbIndexScanOperation; friend class NdbDictionaryImpl; friend class NdbDictInterface; @@ -1439,7 +1440,7 @@ private: NdbConnection* doConnect(Uint32 nodeId); void doDisconnect(); - NdbScanReceiver* getNdbScanRec();// Get a NdbScanReceiver from idle list + NdbReceiver* getNdbScanRec();// Get a NdbScanReceiver from idle list NdbLabel* getNdbLabel(); // Get a NdbLabel from idle list NdbBranch* getNdbBranch(); // Get a NdbBranch from idle list NdbSubroutine* getNdbSubroutine();// Get a NdbSubroutine from idle @@ -1448,21 +1449,21 @@ private: NdbRecAttr* getRecAttr(); // Get a receeive attribute object from // idle list of the Ndb object. NdbOperation* getOperation(); // Get an operation from idle list - NdbScanOperation* getScanOperation(); // Get a scan operation from idle + NdbIndexScanOperation* getScanOperation(); // Get a scan operation from idle NdbIndexOperation* getIndexOperation();// Get an index operation from idle class NdbGlobalEventBufferHandle* getGlobalEventBufferHandle(); void releaseSignal(NdbApiSignal* anApiSignal); void releaseSignalsInList(NdbApiSignal** pList); - void releaseNdbScanRec(NdbScanReceiver* aNdbScanRec); + void releaseNdbScanRec(NdbReceiver* aNdbScanRec); void releaseNdbLabel(NdbLabel* anNdbLabel); void releaseNdbBranch(NdbBranch* anNdbBranch); void releaseNdbSubroutine(NdbSubroutine* anNdbSubroutine); void releaseNdbCall(NdbCall* anNdbCall); void releaseRecAttr (NdbRecAttr* aRecAttr); void releaseOperation(NdbOperation* anOperation); - void releaseScanOperation(NdbScanOperation* aScanOperation); + void releaseScanOperation(NdbIndexScanOperation*); void check_send_timeout(); void remove_sent_list(Uint32); @@ -1558,7 +1559,6 @@ private: void* int2void (Uint32 val); NdbReceiver* void2rec (void* val); NdbConnection* void2con (void* val); - NdbScanReceiver* void2rec_srec(void* val); NdbOperation* void2rec_op (void* val); NdbIndexOperation* void2rec_iop (void* val); @@ -1598,7 +1598,7 @@ private: NdbOperation* theOpIdleList; // First operation in the idle list. - NdbScanOperation* theScanOpIdleList; // First scan operation in the idle list. + NdbIndexScanOperation* theScanOpIdleList; // First scan operation in the idle list. NdbIndexOperation* theIndexOpIdleList; // First index operation in the idle list. NdbConnection* theTransactionList; NdbConnection** theConnectionArray; @@ -1608,7 +1608,7 @@ private: NdbBranch* theBranchList; // First branch descriptor in list NdbSubroutine* theSubroutineList; // First subroutine descriptor in NdbCall* theCallList; // First call descriptor in list - NdbScanReceiver* theScanList; + NdbReceiver* theScanList; Uint32 theMyRef; // My block reference Uint32 theNode; // The node number of our node diff --git a/ndb/include/ndbapi/NdbApi.hpp b/ndb/include/ndbapi/NdbApi.hpp index b9b52708789..5f55c8951ba 100644 --- a/ndb/include/ndbapi/NdbApi.hpp +++ b/ndb/include/ndbapi/NdbApi.hpp @@ -23,6 +23,10 @@ #include "NdbOperation.hpp" #include "NdbScanOperation.hpp" #include "NdbIndexOperation.hpp" +#include "NdbIndexScanOperation.hpp" +#include "NdbScanFilter.hpp" +#include "NdbSchemaCon.hpp" +#include "NdbSchemaOp.hpp" #include "NdbRecAttr.hpp" #include "NdbResultSet.hpp" #include "NdbDictionary.hpp" diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp index d8c395162f6..65f6bd2995f 100644 --- a/ndb/include/ndbapi/NdbConnection.hpp +++ b/ndb/include/ndbapi/NdbConnection.hpp @@ -22,12 +22,11 @@ class NdbConnection; class NdbOperation; -class NdbCursorOperation; class NdbScanOperation; +class NdbIndexScanOperation; class NdbIndexOperation; class NdbApiSignal; class Ndb; -class NdbScanReceiver; /** @@ -159,7 +158,7 @@ class NdbConnection friend class NdbOperation; friend class NdbScanOperation; friend class NdbIndexOperation; - friend class NdbScanReceiver; + friend class NdbIndexScanOperation; public: @@ -176,56 +175,31 @@ public: NdbOperation* getNdbOperation(const char* aTableName); /** - * Get an NdbOperation for index scan of a table. - * Note that the operation has to be defined before it is executed. - * - * @note All operations within the same transaction need to - * be initialized with this method. - * - * @param anIndexName The index name. - * @param aTableName The table name. - * @return Pointer to an NdbOperation object if successful, otherwise NULL. - */ - NdbOperation* getNdbOperation(const char* anIndexName, - const char* aTableName); - -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL - /** * Get an operation from NdbScanOperation idlelist and * get the NdbConnection object which * was fetched by startTransaction pointing to this operation. - * This operation will set the theTableId - * in the NdbOperation object.synchronous. * * @param aTableName a table name. * @return pointer to an NdbOperation object if successful, otherwise NULL */ NdbScanOperation* getNdbScanOperation(const char* aTableName); -#endif -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL /** * Get an operation from NdbScanOperation idlelist and * get the NdbConnection object which * was fetched by startTransaction pointing to this operation. - * This operation will set the theTableId - * in the NdbOperation object.synchronous. * * @param anIndexName The index name. * @param aTableName a table name. * @return pointer to an NdbOperation object if successful, otherwise NULL */ - NdbScanOperation* getNdbScanOperation(const char* anIndexName, - const char* aTableName); -#endif - - + NdbIndexScanOperation* getNdbIndexScanOperation(const char* anIndexName, + const char* aTableName); + /** * Get an operation from NdbIndexOperation idlelist and * get the NdbConnection object that * was fetched by startTransaction pointing to this operation. - * This operation will set the theTableId - * in the NdbOperation object. Synchronous. * * @param indexName An index name (as created by createIndex). * @param tableName A table name. @@ -338,75 +312,6 @@ public: /** @} *********************************************************************/ /** - * @name Scan Transactions - * @{ - */ - - /** - * Execute a scan transaction. This will define - * and start the scan transaction in the NDB kernel. - * - * @return 0 if successful otherwise -1. - */ - int executeScan(); - - /** - * Get the next tuple in a scan transaction. - * - * After each call to NdbConnection::nextScanResult - * the buffers and NdbRecAttr objects defined in - * NdbOperation::getValue are updated with values - * from the scanned tuple. - * - * @param fetchAllowed If set to false, then fetching is disabled - * - * The NDB API will contact the NDB Kernel for more tuples - * when necessary to do so unless you set the fetchAllowed - * to false. - * This will force NDB to process any records it - * already has in it's caches. When there are no more cached - * records it will return 2. You must then call nextScanResult - * with fetchAllowed = true in order to contact NDB for more - * records. - * - * fetchAllowed = false is useful when you want to update or - * delete all the records fetched in one transaction(This will save a - * lot of round trip time and make updates or deletes of scanned - * records a lot faster). - * While nextScanResult(false) - * returns 0 take over the record to another transaction. When - * nextScanResult(false) returns 2 you must execute and commit the other - * transaction. This will cause the locks to be transferred to the - * other transaction, updates or deletes will be made and then the - * locks will be released. - * After that, call nextScanResult(true) which will fetch new records and - * cache them in the NdbApi. - * - * @note If you don't take over the records to another transaction the - * locks on those records will be released the next time NDB Kernel - * is contacted for more records. - * - * @note Please contact for examples of efficient scan - * updates and deletes. - * - * @return - * - -1: if unsuccessful,<br> - * - 0: if another tuple was received, and<br> - * - 1: if there are no more tuples to scan. - * - 2: if there are no more cached records in NdbApi - */ - int nextScanResult(bool fetchAllowed = true); - - /** - * Stops the scan. Used if no more tuples are wanted. - * The transaction should still be closed with - * Ndb::closeTransaction. - * - * @return 0 if successful otherwise -1. - */ - int stopScan(); - - /** * @name Meta Information * @{ */ @@ -581,13 +486,7 @@ private: int receiveTCINDXCONF(const class TcIndxConf *, Uint32 aDataLength); int receiveTCINDXREF(NdbApiSignal*); int receiveSCAN_TABREF(NdbApiSignal*); - int receiveSCAN_TABCONF(NdbApiSignal*); - int receiveSCAN_TABINFO(NdbApiSignal*); - - int checkNextScanResultComplete(); - int sendScanStart(); - int sendScanNext(bool stopScanFlag); - int fetchNextScanResult(); + int receiveSCAN_TABCONF(NdbApiSignal*, const Uint32*, Uint32 len); int doSend(); // Send all operations int sendROLLBACK(); // Send of an ROLLBACK @@ -610,7 +509,7 @@ private: // Release all cursor operations in connection void releaseOps(NdbOperation*); - void releaseCursorOperations(NdbCursorOperation*); + void releaseScanOperations(NdbIndexScanOperation*); // Set the transaction identity of the transaction void setTransactionId(Uint64 aTransactionId); @@ -626,7 +525,7 @@ private: int checkMagicNumber(); // Verify correct object NdbOperation* getNdbOperation(class NdbTableImpl* aTable); - NdbScanOperation* getNdbScanOperation(class NdbTableImpl* aTable); + NdbIndexScanOperation* getNdbScanOperation(class NdbTableImpl* aTable); NdbIndexOperation* getNdbIndexOperation(class NdbIndexImpl* anIndex, class NdbTableImpl* aTable); @@ -679,7 +578,6 @@ private: Uint32 theNoOfOpSent; // How many operations have been sent Uint32 theNoOfOpCompleted; // How many operations have completed Uint32 theNoOfOpFetched; // How many operations was actually fetched - Uint32 theNoOfSCANTABCONFRecv; // How many SCAN_TABCONF have been received Uint32 theMyRef; // Our block reference Uint32 theTCConPtr; // Transaction Co-ordinator connection pointer. Uint64 theTransactionId; // theTransactionId of the transaction @@ -715,20 +613,16 @@ private: Uint32 theNodeSequence; // The sequence no of the db node bool theReleaseOnClose; - // Cursor operations + // Scan operations bool m_waitForReply; - NdbCursorOperation* m_theFirstCursorOperation; - NdbCursorOperation* m_theLastCursorOperation; + NdbIndexScanOperation* m_theFirstScanOperation; + NdbIndexScanOperation* m_theLastScanOperation; - NdbCursorOperation* m_firstExecutedCursorOp; - // Scan operations - bool theScanFinished; + NdbIndexScanOperation* m_firstExecutedScanOp; - NdbScanReceiver* theCurrentScanRec; // The current operation to - // distribute to the app. - NdbScanReceiver* thePreviousScanRec; // The previous operation read by - // nextScanResult. - NdbOperation* theScanningOp; // The operation actually performing the scan + // Scan operations + // The operation actually performing the scan + NdbScanOperation* theScanningOp; Uint32 theBuddyConPtr; static void sendTC_COMMIT_ACK(NdbApiSignal *, @@ -739,6 +633,17 @@ private: #ifdef VM_TRACE void printState(); #endif + + bool checkState_TransId(const Uint32 * transId) const { + const Uint32 tTmp1 = transId[0]; + const Uint32 tTmp2 = transId[1]; + Uint64 tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32); + bool b = theStatus == Connected && theTransactionId == tRecTransId; +#ifdef NDB_NO_DROPPED_SIGNAL + if(!b) abort(); +#endif + return b; + } }; inline diff --git a/ndb/include/ndbapi/NdbCursorOperation.hpp b/ndb/include/ndbapi/NdbCursorOperation.hpp index cd76b045ea2..e7eeb54ba2d 100644 --- a/ndb/include/ndbapi/NdbCursorOperation.hpp +++ b/ndb/include/ndbapi/NdbCursorOperation.hpp @@ -17,77 +17,4 @@ #ifndef NdbCursorOperation_H #define NdbCursorOperation_H -#include <NdbOperation.hpp> - -class NdbResultSet; - -/** - * @class NdbCursorOperation - * @brief Operation using cursors - */ -class NdbCursorOperation : public NdbOperation -{ - friend class NdbResultSet; - friend class NdbConnection; - -public: - /** - * Type of cursor - */ - enum CursorType { - NoCursor = 0, - ScanCursor = 1, - IndexCursor = 2 - }; - - /** - * Lock when performing scan - */ - enum LockMode { - LM_Read = 0, - LM_Exclusive = 1, - LM_CommittedRead = 2, -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL - LM_Dirty = 2 -#endif - }; - - virtual CursorType cursorType() = 0; - - /** - * readTuples returns a NdbResultSet where tuples are stored. - * Tuples are not stored in NdbResultSet until execute(NoCommit) - * has been executed and nextResult has been called. - * - * @param parallel Scan parallelism - * @param LockMode Scan lock handling - * @returns NdbResultSet. - */ - virtual NdbResultSet* readTuples(unsigned parallel = 0, - LockMode = LM_Read ) = 0; - - inline NdbResultSet* readTuplesExclusive(int parallell = 0){ - return readTuples(parallell, LM_Exclusive); - } - -protected: - NdbCursorOperation(Ndb* aNdb); - - ~NdbCursorOperation(); - - void cursInit(); - - virtual int executeCursor(int ProcessorId) = 0; - - NdbResultSet* getResultSet(); - NdbResultSet* m_resultSet; - -private: - - virtual int nextResult(bool fetchAllowed) = 0; - - virtual void closeScan() = 0; -}; - - #endif diff --git a/ndb/include/ndbapi/NdbIndexOperation.hpp b/ndb/include/ndbapi/NdbIndexOperation.hpp index baf31dca0ee..2d873c52e56 100644 --- a/ndb/include/ndbapi/NdbIndexOperation.hpp +++ b/ndb/include/ndbapi/NdbIndexOperation.hpp @@ -29,7 +29,7 @@ #ifndef NdbIndexOperation_H #define NdbIndexOperation_H -#include <NdbCursorOperation.hpp> +#include "NdbOperation.hpp" class Index; class NdbResultSet; diff --git a/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/ndb/include/ndbapi/NdbIndexScanOperation.hpp new file mode 100644 index 00000000000..3f64880bbc0 --- /dev/null +++ b/ndb/include/ndbapi/NdbIndexScanOperation.hpp @@ -0,0 +1,140 @@ +/* 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 NdbIndexScanOperation_H +#define NdbIndexScanOperation_H + +#include <NdbScanOperation.hpp> + +/** + * @class NdbIndexScanOperation + * @brief Class of scan operations for use to scan ordered index + */ +class NdbIndexScanOperation : public NdbScanOperation { + friend class Ndb; + friend class NdbConnection; + friend class NdbResultSet; + friend class NdbOperation; + friend class NdbScanOperation; +public: + /** + * readTuples returns a NdbResultSet where tuples are stored. + * Tuples are not stored in NdbResultSet until execute(NoCommit) + * has been executed and nextResult has been called. + * + * @param parallel Scan parallelism + * @param batch No of rows to fetch from each fragment at a time + * @param LockMode Scan lock handling + * @param order_by Order result set in index order + * @returns NdbResultSet. + * @see NdbScanOperation::readTuples + */ + NdbResultSet* readTuples(LockMode = LM_Read, + Uint32 batch = 0, + Uint32 parallel = 0, + bool order_by = false); + + inline NdbResultSet* readTuples(int parallell){ + return readTuples(LM_Read, 0, parallell, false); + } + + inline NdbResultSet* readTuplesExclusive(int parallell = 0){ + return readTuples(LM_Exclusive, 0, parallell, false); + } + + /** + * @name Define Range Scan + * + * A range scan is a scan on an ordered index. The operation is on + * the index table but tuples are returned from the primary table. + * The index contains all tuples where at least one index key has not + * null value. + * + * A range scan is currently opened via a normal open scan method. + * Bounds can be defined for each index key. After setting bounds, + * usual scan methods can be used (get value, interpreter, take over). + * These operate on the primary table. + * + * @{ + */ + + /** + * Type of ordered index key bound. The values (0-4) will not change + * and can be used explicitly (e.g. they could be computed). + */ + enum BoundType { + BoundLE = 0, ///< lower bound, + BoundLT = 1, ///< lower bound, strict + BoundGE = 2, ///< upper bound + BoundGT = 3, ///< upper bound, strict + BoundEQ = 4 ///< equality + }; + + /** + * Define bound on index key in range scan. + * + * Each index key can have not null lower and/or upper bound, or can + * be set equal to not null value. The bounds can be defined in any + * order but a duplicate definition is an error. + * + * The scan is most effective when bounds are given for an initial + * sequence of non-nullable index keys, and all but the last one is an + * equality. In this case the scan returns a contiguous range from + * each ordered index fragment. + * + * @note This release implements only the case described above, + * except for the non-nullable limitation. Other sets of + * bounds return error or empty result set. + * + * @note In this release a null key value satisfies any lower + * bound and no upper bound. This may change. + * + * @param attrName Attribute name, alternatively: + * @param anAttrId Index column id (starting from 0). + * @param type Type of bound + * @param value Pointer to bound value + * @param len Value length in bytes. + * Fixed per datatype and can be omitted + * @return 0 if successful otherwise -1 + */ + int setBound(const char* attr, int type, const void* aValue, Uint32 len = 0); + + /** + * Define bound on index key in range scan using index column id. + * See the other setBound() method for details. + */ + int setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len = 0); + + /** @} *********************************************************************/ + +private: + NdbIndexScanOperation(Ndb* aNdb); + virtual ~NdbIndexScanOperation(); + + int setBound(const NdbColumnImpl*, int type, const void* aValue, Uint32 len); + + virtual int equal_impl(const NdbColumnImpl*, const char*, Uint32); + 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 compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*); + + Uint32 m_sort_columns; +}; + +#endif diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp index 5fa903994b7..89f83f4ee4b 100644 --- a/ndb/include/ndbapi/NdbOperation.hpp +++ b/ndb/include/ndbapi/NdbOperation.hpp @@ -41,7 +41,8 @@ class NdbOperation friend class NdbScanReceiver; friend class NdbScanFilter; friend class NdbScanFilterImpl; - + friend class NdbReceiver; + public: /** * @name Define Standard Operation Type @@ -194,196 +195,7 @@ public: */ virtual int interpretedDeleteTuple(); - /** - * Scan a table to read tuples. - * - * The operation only sets a temporary read lock while - * reading the tuple. - * The tuple lock is released when the result of the read reaches the - * application. - * - * @param Parallelism Number of parallel tuple reads are performed - * in the scan. - * Currently a maximum of 256 parallel tuple - * reads are allowed. - * The parallelism can in reality be lower - * than specified - * depending on the number of nodes - * in the cluster - * @return 0 if successful otherwise -1. - */ - int openScanRead(Uint32 Parallelism = 16 ); - - /** - * Scan a table to write or update tuples. - * - * The operation sets an exclusive lock on the tuple and sends the result - * to the application. - * Thus when the application reads the data, the tuple is - * still locked with an exclusive lock. - * - * @param parallelism Number of parallel tuple reads are performed - * in the scan. - * Currently a maximum of 256 parallel tuple - * reads are allowed. - * The parallelism can in reality be lower - * than specified depending on the number - * of nodes in the cluster - * @return 0 if successful otherwise -1. - * - */ - int openScanExclusive(Uint32 parallelism = 16); - - /** - * Scan a table to read tuples. - * - * The operation only sets a read lock while - * reading the tuple. - * Thus when the application reads the data, the tuple is - * still locked with a read lock. - * - * @param parallelism Number of parallel tuple reads are performed - * in the scan. - * Currently a maximum of 256 parallel tuple - * reads are allowed. - * The parallelism can in reality be lower - * than specified - * depending on the number of nodes - * in the cluster - * @return 0 if successful otherwise -1. - */ - int openScanReadHoldLock(Uint32 parallelism = 16); - - /** - * Scan a table to read tuples. - * - * The operation does not wait for locks held by other transactions - * but returns the latest committed tuple instead. - * - * @param parallelism Number of parallel tuple reads are performed - * in the scan. - * Currently a maximum of 256 parallel tuple - * reads are allowed. - * The parallelism can in reality be lower - * than specified - * depending on the number of nodes - * in the cluster - * @return 0 if successful otherwise -1. - */ - int openScanReadCommitted(Uint32 parallelism = 16); - - /** @} *********************************************************************/ - - /** - * @name Define Range Scan - * - * A range scan is a scan on an ordered index. The operation is on - * the index table but tuples are returned from the primary table. - * The index contains all tuples where at least one index key has not - * null value. - * - * A range scan is currently opened via a normal open scan method. - * Bounds can be defined for each index key. After setting bounds, - * usual scan methods can be used (get value, interpreter, take over). - * These operate on the primary table. - * - * @{ - */ - - /** - * Type of ordered index key bound. The values (0-4) will not change - * and can be used explicitly (e.g. they could be computed). - */ - enum BoundType { - BoundLE = 0, ///< lower bound, - BoundLT = 1, ///< lower bound, strict - BoundGE = 2, ///< upper bound - BoundGT = 3, ///< upper bound, strict - BoundEQ = 4 ///< equality - }; - - /** - * Define bound on index key in range scan. - * - * Each index key can have not null lower and/or upper bound, or can - * be set equal to not null value. The bounds can be defined in any - * order but a duplicate definition is an error. - * - * The scan is most effective when bounds are given for an initial - * sequence of non-nullable index keys, and all but the last one is an - * equality. In this case the scan returns a contiguous range from - * each ordered index fragment. - * - * @note This release implements only the case described above, - * except for the non-nullable limitation. Other sets of - * bounds return error or empty result set. - * - * @note In this release a null key value satisfies any lower - * bound and no upper bound. This may change. - * - * @param attrName Attribute name, alternatively: - * @param anAttrId Index column id (starting from 0). - * @param type Type of bound - * @param value Pointer to bound value - * @param len Value length in bytes. - * Fixed per datatype and can be omitted - * @return 0 if successful otherwise -1 - */ - int setBound(const char* anAttrName, int type, const void* aValue, Uint32 len = 0); - - /** - * Define bound on index key in range scan using index column id. - * See the other setBound() method for details. - */ - int setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len = 0); - /** @} *********************************************************************/ - - /** - * Validate parallelism parameter by checking the number - * against number of executing Ndb nodes. - * - * @param Parallelism - * @return 0 if correct parallelism value, otherwise -1. - * - */ - int checkParallelism(Uint32 Parallelism); - - /** - * Transfer scan operation to an updating transaction. Use this function - * when a scan has found a record that you want to update. - * 1. Start a new transaction. - * 2. Call the function takeOverForUpdate using your new transaction - * as parameter, all the properties of the found record will be copied - * to the new transaction. - * 3. When you execute the new transaction, the lock held by the scan will - * be transferred to the new transaction(it's taken over). - * - * @note You must have started the scan with openScanExclusive - * to be able to update the found tuple. - * - * @param updateTrans the update transaction connection. - * @return an NdbOperation or NULL. - */ - NdbOperation* takeOverForUpdate(NdbConnection* updateTrans); - - /** - * Transfer scan operation to a deleting transaction. Use this function - * when a scan has found a record that you want to delete. - * 1. Start a new transaction. - * 2. Call the function takeOverForDelete using your new transaction - * as parameter, all the properties of the found record will be copied - * to the new transaction. - * 3. When you execute the new transaction, the lock held by the scan will - * be transferred to the new transaction(its taken over). - * - * @note You must have started the scan with openScanExclusive - * to be able to delete the found tuple. - * - * @param deleteTrans the delete transaction connection. - * @return an NdbOperation or NULL. - */ - NdbOperation* takeOverForDelete(NdbConnection* deleteTrans); /** * @name Specify Search Conditions @@ -865,16 +677,7 @@ protected: // Initialise after allocating operation to a transaction //-------------------------------------------------------------- int init(class NdbTableImpl*, NdbConnection* aCon); - - void initScan(); // Initialise after allocating operation - // to a scan transaction - virtual void releaseScan(); // Release scan parts of transaction - void releaseSignals(); - void releaseScanSignals(); - void prepareNextScanResult(); - - // Common part for Read and Exclusive - int openScan(Uint32 aParallelism, bool, bool, bool); + void initInterpreter(); void next(NdbOperation*); // Set next pointer @@ -920,11 +723,6 @@ protected: *****************************************************************************/ int doSend(int ProcessorId, Uint32 lastFlag); - int doSendScan(int ProcessorId); - - int prepareSendScan(Uint32 TC_ConnectPtr, - Uint64 TransactionId); - virtual int prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId); virtual void setLastFlag(NdbApiSignal* signal, Uint32 lastFlag); @@ -951,7 +749,7 @@ protected: virtual int equal_impl(const NdbColumnImpl* anAttrObject, const char* aValue, Uint32 len); - NdbRecAttr* getValue(const NdbColumnImpl* anAttrObject, char* aValue = 0); + NdbRecAttr* getValue_impl(const NdbColumnImpl* anAttrObject, char* aValue = 0); int setValue(const NdbColumnImpl* anAttrObject, const char* aValue, Uint32 len); int incValue(const NdbColumnImpl* anAttrObject, Uint32 aValue); int incValue(const NdbColumnImpl* anAttrObject, Uint64 aValue); @@ -962,15 +760,12 @@ protected: int branch_reg_reg(Uint32 type, Uint32, Uint32, Uint32); int branch_col(Uint32 type, Uint32, const char *, Uint32, bool, Uint32 Label); int branch_col_null(Uint32 type, Uint32 col, Uint32 Label); - int setBound(const NdbColumnImpl* anAttrObject, int type, const void* aValue, Uint32 len); // Handle ATTRINFO signals int receiveREAD_AI(Uint32* aDataPtr, Uint32 aLength); int insertATTRINFO(Uint32 aData); int insertATTRINFOloop(const Uint32* aDataPtr, Uint32 aLength); - int getFirstATTRINFOScan(); - int saveBoundATTRINFO(); int insertKEYINFO(const char* aValue, Uint32 aStartPosition, @@ -994,9 +789,6 @@ protected: Uint32 ptr2int() { return theReceiver.getId(); }; - NdbOperation* - takeOverScanOp(OperationType opType, NdbConnection* updateTrans); - /****************************************************************************** * These are the private variables that are defined in the operation objects. *****************************************************************************/ @@ -1009,7 +801,6 @@ protected: Ndb* theNdb; // Point back to the Ndb object. NdbConnection* theNdbCon; // Point back to the connection object. NdbOperation* theNext; // Next pointer to operation. - NdbOperation* theNextScanOp; NdbApiSignal* theTCREQ; // The TC[KEY/INDX]REQ signal object NdbApiSignal* theFirstATTRINFO; // The first ATTRINFO signal object NdbApiSignal* theCurrentATTRINFO; // The current ATTRINFO signal object @@ -1020,9 +811,6 @@ protected: NdbApiSignal* theFirstKEYINFO; // The first KEYINFO signal object NdbApiSignal* theLastKEYINFO; // The first KEYINFO signal object - NdbRecAttr* theFirstRecAttr; // The first receive attribute object - NdbRecAttr* theCurrentRecAttr; // The current receive attribute object - class NdbLabel* theFirstLabel; class NdbLabel* theLastLabel; class NdbBranch* theFirstBranch; @@ -1037,11 +825,6 @@ protected: Uint32* theKEYINFOptr; // Pointer to where to write KEYINFO Uint32* theATTRINFOptr; // Pointer to where to write ATTRINFO - Uint32 theTotalRecAI_Len; // The total length received according - // to the TCKEYCONF signal - Uint32 theCurrRecAI_Len; // The currently received length - Uint32 theAI_ElementLen; // How many words long is this element - Uint32* theCurrElemPtr; // The current pointer to the element class NdbTableImpl* m_currentTable; // The current table class NdbTableImpl* m_accessTable; @@ -1083,15 +866,6 @@ protected: Uint16 m_keyInfoGSN; Uint16 m_attrInfoGSN; - // Scan related variables - Uint32 theParallelism; - NdbScanReceiver** theScanReceiversArray; - NdbApiSignal* theSCAN_TABREQ; - NdbApiSignal* theFirstSCAN_TABINFO_Send; - NdbApiSignal* theLastSCAN_TABINFO_Send; - NdbApiSignal* theFirstSCAN_TABINFO_Recv; - NdbApiSignal* theLastSCAN_TABINFO_Recv; - NdbApiSignal* theSCAN_TABCONF_Recv; // saveBoundATTRINFO() moves ATTRINFO here when setBound() is ready NdbApiSignal* theBoundATTRINFO; Uint32 theTotalBoundAI_Len; diff --git a/ndb/include/ndbapi/NdbRecAttr.hpp b/ndb/include/ndbapi/NdbRecAttr.hpp index 0960c035abe..30bb7753413 100644 --- a/ndb/include/ndbapi/NdbRecAttr.hpp +++ b/ndb/include/ndbapi/NdbRecAttr.hpp @@ -74,8 +74,9 @@ class AttrInfo; class NdbRecAttr { friend class NdbOperation; + friend class NdbIndexScanOperation; friend class NdbEventOperationImpl; - friend class NdbScanReceiver; + friend class NdbReceiver; friend class Ndb; public: @@ -244,9 +245,8 @@ private: NdbRecAttr(); Uint32 attrId() const; /* Get attribute id */ - void setNULL(); /* Set NULL indicator */ - void setNotNULL(); /* Set Not NULL indicator */ - void setUNDEFINED(); /* Set UNDEFINED indicator */ + bool setNULL(); /* Set NULL indicator */ + bool receive_data(const Uint32*, Uint32); void release(); /* Release memory if allocated */ void init(); /* Initialise object when allocated */ @@ -254,6 +254,7 @@ private: void next(NdbRecAttr* aRecAttr); NdbRecAttr* next() const; + int setup(const class NdbColumnImpl* anAttrInfo, char* aValue); /* Set up attributes and buffers */ bool copyoutRequired() const; /* Need to copy data to application */ @@ -268,6 +269,7 @@ private: Uint32 theAttrId; /* The attribute id */ int theNULLind; + bool m_nullable; Uint32 theAttrSize; Uint32 theArraySize; const NdbDictionary::Column* m_column; @@ -288,29 +290,7 @@ NdbRecAttr::getColumn() const { inline Uint32 NdbRecAttr::attrSize() const { - - switch(getType()){ - case NdbDictionary::Column::Int: - case NdbDictionary::Column::Unsigned: - case NdbDictionary::Column::Float: - return 4; - case NdbDictionary::Column::Decimal: - case NdbDictionary::Column::Char: - case NdbDictionary::Column::Varchar: - case NdbDictionary::Column::Binary: - case NdbDictionary::Column::Varbinary: - return 1; - case NdbDictionary::Column::Bigint: - case NdbDictionary::Column::Bigunsigned: - case NdbDictionary::Column::Double: - case NdbDictionary::Column::Datetime: - return 8; - case NdbDictionary::Column::Timespec: - return 12; - case NdbDictionary::Column::Undefined: - default: - return 0; - } + return theAttrSize; } inline @@ -448,24 +428,11 @@ NdbRecAttr::attrId() const } inline -void +bool NdbRecAttr::setNULL() { theNULLind = 1; -} - -inline -void -NdbRecAttr::setNotNULL() -{ - theNULLind = 0; -} - -inline -void -NdbRecAttr::setUNDEFINED() -{ - theNULLind = -1; + return m_nullable; } inline diff --git a/ndb/include/ndbapi/NdbReceiver.hpp b/ndb/include/ndbapi/NdbReceiver.hpp index a1a08a9735a..5f69887f402 100644 --- a/ndb/include/ndbapi/NdbReceiver.hpp +++ b/ndb/include/ndbapi/NdbReceiver.hpp @@ -23,6 +23,12 @@ class Ndb; class NdbReceiver { + friend class Ndb; + friend class NdbOperation; + friend class NdbScanOperation; + friend class NdbIndexOperation; + friend class NdbIndexScanOperation; + friend class NdbConnection; public: enum ReceiverType { NDB_UNINITIALIZED, NDB_OPERATION = 1, @@ -31,7 +37,8 @@ public: }; NdbReceiver(Ndb *aNdb); - void init(ReceiverType type, void* owner); + void init(ReceiverType type, void* owner, bool keyInfo); + void release(); ~NdbReceiver(); Uint32 getId(){ @@ -42,18 +49,51 @@ public: return m_type; } + inline NdbConnection * getTransaction(); void* getOwner(){ return m_owner; } bool checkMagicNumber() const; + inline void next(NdbReceiver* next) { m_next = next;} + inline NdbReceiver* next() { return m_next; } + private: Uint32 theMagicNumber; Ndb* m_ndb; Uint32 m_id; + Uint32 m_tcPtrI; + Uint32 m_key_info; ReceiverType m_type; void* m_owner; + NdbReceiver* m_next; + + /** + * At setup + */ + class NdbRecAttr * getValue(const class NdbColumnImpl*, char * user_dst_ptr); + void do_get_value(NdbReceiver*, Uint32 rows, Uint32 key_size); + void prepareSend(); + + int execKEYINFO20(Uint32 info, const Uint32* ptr, Uint32 len); + int execTRANSID_AI(const Uint32* ptr, Uint32 len); + int execTCOPCONF(Uint32 len); + int execSCANOPCONF(Uint32 tcPtrI, Uint32 len, Uint32 rows); + class NdbRecAttr* theFirstRecAttr; + class NdbRecAttr* theCurrentRecAttr; + class NdbRecAttr** m_rows; + + Uint32 m_list_index; // When using multiple + Uint32 m_current_row; + Uint32 m_result_rows; + Uint32 m_defined_rows; + + Uint32 m_expected_result_length; + Uint32 m_received_result_length; + + bool nextResult() const { return m_current_row < m_result_rows; } + void copyout(NdbReceiver&); }; #ifdef NDB_NO_DROPPED_SIGNAL @@ -72,5 +112,32 @@ NdbReceiver::checkMagicNumber() const { return retVal; } +inline +void +NdbReceiver::prepareSend(){ + m_current_row = 0; + m_received_result_length = 0; + m_expected_result_length = 0; + theCurrentRecAttr = theFirstRecAttr; +} + +inline +int +NdbReceiver::execTCOPCONF(Uint32 len){ + Uint32 tmp = m_received_result_length; + m_expected_result_length = len; + return (tmp == len ? 1 : 0); +} + +inline +int +NdbReceiver::execSCANOPCONF(Uint32 tcPtrI, Uint32 len, Uint32 rows){ + m_tcPtrI = tcPtrI; + m_result_rows = rows; + Uint32 tmp = m_received_result_length; + m_expected_result_length = len; + return (tmp == len ? 1 : 0); +} + #endif #endif diff --git a/ndb/include/ndbapi/NdbResultSet.hpp b/ndb/include/ndbapi/NdbResultSet.hpp index d48df01214e..7cf18a6685d 100644 --- a/ndb/include/ndbapi/NdbResultSet.hpp +++ b/ndb/include/ndbapi/NdbResultSet.hpp @@ -30,17 +30,15 @@ #define NdbResultSet_H -#include <NdbCursorOperation.hpp> -#include <NdbIndexOperation.hpp> #include <NdbScanOperation.hpp> /** * @class NdbResultSet - * @brief NdbResultSet contains a NdbCursorOperation. + * @brief NdbResultSet contains a NdbScanOperation. */ class NdbResultSet { - friend class NdbCursorOperation; + friend class NdbScanOperation; public: @@ -93,22 +91,57 @@ public: */ int nextResult(bool fetchAllowed = true); + /** + * Close result set (scan) + */ void close(); + /** + * Transfer scan operation to an updating transaction. Use this function + * when a scan has found a record that you want to update. + * 1. Start a new transaction. + * 2. Call the function takeOverForUpdate using your new transaction + * as parameter, all the properties of the found record will be copied + * to the new transaction. + * 3. When you execute the new transaction, the lock held by the scan will + * be transferred to the new transaction(it's taken over). + * + * @note You must have started the scan with openScanExclusive + * to be able to update the found tuple. + * + * @param updateTrans the update transaction connection. + * @return an NdbOperation or NULL. + */ NdbOperation* updateTuple(); - NdbOperation* updateTuple(NdbConnection* takeOverTransaction); - + NdbOperation* updateTuple(NdbConnection* updateTrans); + + /** + * Transfer scan operation to a deleting transaction. Use this function + * when a scan has found a record that you want to delete. + * 1. Start a new transaction. + * 2. Call the function takeOverForDelete using your new transaction + * as parameter, all the properties of the found record will be copied + * to the new transaction. + * 3. When you execute the new transaction, the lock held by the scan will + * be transferred to the new transaction(its taken over). + * + * @note You must have started the scan with openScanExclusive + * to be able to delete the found tuple. + * + * @param deleteTrans the delete transaction connection. + * @return an NdbOperation or NULL. + */ int deleteTuple(); int deleteTuple(NdbConnection* takeOverTransaction); private: - NdbResultSet(NdbCursorOperation*); + NdbResultSet(NdbScanOperation*); ~NdbResultSet(); void init(); - NdbCursorOperation* m_operation; + NdbScanOperation* m_operation; }; #endif diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp index f83669fb616..8ff640dc6ec 100644 --- a/ndb/include/ndbapi/NdbScanOperation.hpp +++ b/ndb/include/ndbapi/NdbScanOperation.hpp @@ -29,16 +29,13 @@ #ifndef NdbScanOperation_H #define NdbScanOperation_H - #include <NdbOperation.hpp> -#include <NdbCursorOperation.hpp> /** * @class NdbScanOperation * @brief Class of scan operations for use in transactions. */ -class NdbScanOperation : public NdbCursorOperation -{ +class NdbScanOperation : public NdbOperation { friend class Ndb; friend class NdbConnection; friend class NdbResultSet; @@ -46,50 +43,60 @@ class NdbScanOperation : public NdbCursorOperation public: /** + * Type of cursor + */ + enum CursorType { + NoCursor = 0, + ScanCursor = 1, + IndexCursor = 2 + }; + + /** + * Lock when performing scan + */ + enum LockMode { + LM_Read = 0, + LM_Exclusive = 1, + LM_CommittedRead = 2, +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + LM_Dirty = 2 +#endif + }; + + /** + * Type of cursor + */ + CursorType get_cursor_type() const; + + /** * readTuples returns a NdbResultSet where tuples are stored. * Tuples are not stored in NdbResultSet until execute(NoCommit) * has been executed and nextResult has been called. * * @param parallel Scan parallelism + * @param batch No of rows to fetch from each fragment at a time * @param LockMode Scan lock handling * @returns NdbResultSet. + * @note specifying 0 for batch and parallall means max performance */ - virtual NdbResultSet* readTuples(unsigned parallel = 0, - LockMode = LM_Read ); + NdbResultSet* readTuples(LockMode = LM_Read, + Uint32 batch = 0, Uint32 parallel = 0); -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + inline NdbResultSet* readTuples(int parallell){ + return readTuples(LM_Read, 0, parallell); + } + + inline NdbResultSet* readTuplesExclusive(int parallell = 0){ + return readTuples(LM_Exclusive, 0, parallell); + } + +protected: + CursorType m_cursor_type; - int updateTuples(); - int updateTuples(Uint32 parallelism); - - int deleteTuples(); - int deleteTuples(Uint32 parallelism); - - // Overload setValue for updateTuples - int setValue(const char* anAttrName, const char* aValue, Uint32 len = 0); - int setValue(const char* anAttrName, Int32 aValue); - int setValue(const char* anAttrName, Uint32 aValue); - int setValue(const char* anAttrName, Int64 aValue); - int setValue(const char* anAttrName, Uint64 aValue); - int setValue(const char* anAttrName, float aValue); - int setValue(const char* anAttrName, double aValue); - - int setValue(Uint32 anAttrId, const char* aValue, Uint32 len = 0); - int setValue(Uint32 anAttrId, Int32 aValue); - int setValue(Uint32 anAttrId, Uint32 aValue); - int setValue(Uint32 anAttrId, Int64 aValue); - int setValue(Uint32 anAttrId, Uint64 aValue); - int setValue(Uint32 anAttrId, float aValue); - int setValue(Uint32 anAttrId, double aValue); -#endif -private: NdbScanOperation(Ndb* aNdb); - ~NdbScanOperation(); - NdbCursorOperation::CursorType cursorType(); - - virtual int nextResult(bool fetchAllowed = true); + int nextResult(bool fetchAllowed = true); virtual void release(); void closeScan(); @@ -105,125 +112,51 @@ private: virtual void setErrorCode(int aErrorCode); virtual void setErrorCodeAbort(int aErrorCode); - virtual int equal_impl(const NdbColumnImpl* anAttrObject, - const char* aValue, - Uint32 len); -private: + NdbResultSet * m_resultSet; + NdbResultSet* getResultSet(); NdbConnection *m_transConnection; - bool m_autoExecute; - bool m_updateOp; - bool m_writeOp; - bool m_deleteOp; - class SetValueRecList* m_setValueList; -}; -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL -class AttrInfo; -class SetValueRecList; + // Scan related variables + Uint32 theBatchSize; + Uint32 theParallelism; + Uint32 m_keyInfo; + NdbApiSignal* theSCAN_TABREQ; -class SetValueRec { - friend class SetValueRecList; -public: - SetValueRec(); - ~SetValueRec(); - - enum SetValueType { - SET_STRING_ATTR1 = 0, - SET_INT32_ATTR1 = 1, - SET_UINT32_ATTR1 = 2, - SET_INT64_ATTR1 = 3, - SET_UINT64_ATTR1 = 4, - SET_FLOAT_ATTR1 = 5, - SET_DOUBLE_ATTR1 = 6, - SET_STRING_ATTR2 = 7, - SET_INT32_ATTR2 = 8, - SET_UINT32_ATTR2 = 9, - SET_INT64_ATTR2 = 10, - SET_UINT64_ATTR2 = 11, - SET_FLOAT_ATTR2 = 12, - SET_DOUBLE_ATTR2 = 13 - }; + int getFirstATTRINFOScan(); + int saveBoundATTRINFO(); + int doSendScan(int ProcessorId); + int prepareSendScan(Uint32 TC_ConnectPtr, Uint64 TransactionId); + + int fix_receivers(Uint32 parallel, bool keyInfo); + Uint32 m_allocated_receivers; + NdbReceiver** m_receivers; // All receivers - SetValueType stype; - union { - char* anAttrName; - Uint32 anAttrId; - }; - struct String { - char* aStringValue; - Uint32 len; - }; - union { - String stringStruct; - Int32 anInt32Value; - Uint32 anUint32Value; - Int64 anInt64Value; - Uint64 anUint64Value; - float aFloatValue; - double aDoubleValue; - }; -private: - SetValueRec* next; -}; + Uint32* m_prepared_receivers; // These are to be sent + + Uint32 m_current_api_receiver; + Uint32 m_api_receivers_count; + NdbReceiver** m_api_receivers; // These are currently used by api + + Uint32 m_conf_receivers_count; // NOTE needs mutex to access + NdbReceiver** m_conf_receivers; // receive thread puts them here + + 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); + void receiver_delivered(NdbReceiver*); + void receiver_completed(NdbReceiver*); + void execCLOSE_SCAN_REP(Uint32 errCode); -inline -SetValueRec::SetValueRec() : - next(0) -{ -} + NdbOperation* takeOverScanOp(OperationType opType, NdbConnection*); -class SetValueRecList { -public: - SetValueRecList(); - ~SetValueRecList(); - - void add(const char* anAttrName, const char* aValue, Uint32 len = 0); - void add(const char* anAttrName, Int32 aValue); - void add(const char* anAttrName, Uint32 aValue); - void add(const char* anAttrName, Int64 aValue); - void add(const char* anAttrName, Uint64 aValue); - void add(const char* anAttrName, float aValue); - void add(const char* anAttrName, double aValue); - void add(Uint32 anAttrId, const char* aValue, Uint32 len = 0); - void add(Uint32 anAttrId, Int32 aValue); - void add(Uint32 anAttrId, Uint32 aValue); - void add(Uint32 anAttrId, Int64 aValue); - void add(Uint32 anAttrId, Uint64 aValue); - void add(Uint32 anAttrId, float aValue); - void add(Uint32 anAttrId, double aValue); - - typedef void(* IterateFn)(SetValueRec&, NdbOperation&); - static void callSetValueFn(SetValueRec&, NdbOperation&); - void iterate(IterateFn nextfn, NdbOperation&); -private: - SetValueRec* first; - SetValueRec* last; + Uint32 m_ordered; }; inline -SetValueRecList::SetValueRecList() : - first(0), - last(0) -{ -} - -inline -SetValueRecList::~SetValueRecList() { - if (first) delete first; - first = last = 0; +NdbScanOperation::CursorType +NdbScanOperation::get_cursor_type() const { + return m_cursor_type; } - -inline -void SetValueRecList::iterate(SetValueRecList::IterateFn nextfn, NdbOperation& oper) -{ - SetValueRec* recPtr = first; - while(recPtr) { - (*nextfn)(*recPtr, oper); - recPtr = recPtr->next; // Move to next in list - MASV - } -} - -#endif - #endif diff --git a/ndb/include/util/Base64.hpp b/ndb/include/util/Base64.hpp index a8678da946c..1156636eec8 100644 --- a/ndb/include/util/Base64.hpp +++ b/ndb/include/util/Base64.hpp @@ -20,7 +20,8 @@ #include <UtilBuffer.hpp> #include <BaseString.hpp> -int base64_encode(UtilBuffer &src, BaseString &dst); -int base64_decode(BaseString &src, UtilBuffer &dst); +int base64_encode(const UtilBuffer &src, BaseString &dst); +int base64_decode(const BaseString &src, UtilBuffer &dst); +int base64_decode(const char * s, size_t len, UtilBuffer &dst); #endif /* !__BASE64_HPP_INCLUDED__ */ diff --git a/ndb/include/util/Bitmask.hpp b/ndb/include/util/Bitmask.hpp index 00255d3a86b..7355742f845 100644 --- a/ndb/include/util/Bitmask.hpp +++ b/ndb/include/util/Bitmask.hpp @@ -134,7 +134,7 @@ public: /** * getText - Return as hex-digits (only for debug routines). */ - static void getText(unsigned size, const Uint32 data[], char* buf); + static char* getText(unsigned size, const Uint32 data[], char* buf); }; inline bool @@ -302,9 +302,10 @@ BitmaskImpl::setField(unsigned size, Uint32 data[], set(size, data, pos + i, val & (1 << i)); } -inline void +inline char * BitmaskImpl::getText(unsigned size, const Uint32 data[], char* buf) { + char * org = buf; const char* const hex = "0123456789abcdef"; for (int i = (size-1); i >= 0; i--) { Uint32 x = data[i]; @@ -315,6 +316,7 @@ BitmaskImpl::getText(unsigned size, const Uint32 data[], char* buf) buf += 8; } *buf = 0; + return org; } /** @@ -333,7 +335,7 @@ public: Uint32 data[size]; #if 0 Data & operator=(const Bitmask<size> & src) { - src.assign(size, data); + src.copyto(size, data); return *this; } #endif @@ -346,6 +348,8 @@ public: STATIC_CONST( NotFound = BitmaskImpl::NotFound ); STATIC_CONST( TextLength = size * 8 ); + Bitmask() { clear();} + /** * assign - Set all bits in <em>dst</em> to corresponding in <em>src/<em> */ @@ -359,9 +363,9 @@ public: void assign(const Bitmask<size> & src); /** - * assign <em>dst</em> of size <em>sz</em> to <em>this</em> + * copy this to <em>dst</em> */ - void assign(unsigned sz, Uint32 dst[]) const; + void copyto(unsigned sz, Uint32 dst[]) const; /** * assign <em>this</em> according to <em>src/em> @@ -469,7 +473,7 @@ public: /** * getText - Return as hex-digits (only for debug routines). */ - static void getText(const Uint32 data[], char* buf); + static char* getText(const Uint32 data[], char* buf); char* getText(char* buf) const; }; @@ -498,12 +502,12 @@ template <unsigned size> inline void Bitmask<size>::assign(const Bitmask<size> & src) { - assign(rep.data, src); + assign(rep.data, src.rep.data); } template <unsigned size> inline void -Bitmask<size>::assign(unsigned sz, Uint32 dst[]) const +Bitmask<size>::copyto(unsigned sz, Uint32 dst[]) const { BitmaskImpl::assign(sz, dst, rep.data); } @@ -716,18 +720,17 @@ Bitmask<size>::bitXOR(const Bitmask<size>& mask2) } template <unsigned size> -void +char * Bitmask<size>::getText(const Uint32 data[], char* buf) { - BitmaskImpl::getText(size, data, buf); + return BitmaskImpl::getText(size, data, buf); } template <unsigned size> inline char * Bitmask<size>::getText(char* buf) const { - getText(rep.data, buf); - return buf; + return getText(rep.data, buf); } template <unsigned size> diff --git a/ndb/include/util/ConfigValues.hpp b/ndb/include/util/ConfigValues.hpp new file mode 100644 index 00000000000..48e1363bf4a --- /dev/null +++ b/ndb/include/util/ConfigValues.hpp @@ -0,0 +1,252 @@ +#ifndef __CONFIG_VALUES_HPP +#define __CONFIG_VALUES_HPP + +#include <ndb_types.h> +#include <UtilBuffer.hpp> + +class ConfigValues { + friend class ConfigValuesFactory; + ConfigValues(Uint32 sz, Uint32 data); + +public: + ~ConfigValues(); + + enum ValueType { + InvalidType = 0, + IntType = 1, + StringType = 2, + SectionType = 3, + Int64Type = 4 + }; + + struct Entry { + Uint32 m_key; + ValueType m_type; + union { + Uint32 m_int; + const char * m_string; + Uint64 m_int64; + }; + }; + + class ConstIterator { + friend class ConfigValuesFactory; + const ConfigValues & m_cfg; + protected: + Uint32 m_currentSection; + public: + ConstIterator(const ConfigValues&c) : m_cfg(c) { m_currentSection = 0;} + + bool openSection(Uint32 key, Uint32 no); + bool closeSection(); + + bool get(Uint32 key, Entry *) const; + + bool get(Uint32 key, Uint32 * value) const; + bool get(Uint32 key, Uint64 * value) const; + bool get(Uint32 key, const char ** value) const; + bool getTypeOf(Uint32 key, ValueType * type) const; + + Uint32 get(Uint32 key, Uint32 notFound) const; + Uint64 get64(Uint32 key, Uint64 notFound) const; + const char * get(Uint32 key, const char * notFound) const; + ValueType getTypeOf(Uint32 key) const; + }; + + class Iterator : public ConstIterator { + ConfigValues & m_cfg; + public: + Iterator(ConfigValues&c) : ConstIterator(c), m_cfg(c) {} + + bool set(Uint32 key, Uint32 value); + bool set(Uint32 key, Uint64 value); + bool set(Uint32 key, const char * value); + }; + + Uint32 getPackedSize() const; // get size in bytes needed to pack + Uint32 pack(UtilBuffer&) const; + Uint32 pack(void * dst, Uint32 len) const;// pack into dst(of len %d); + +private: + friend class Iterator; + friend class ConstIterator; + + bool getByPos(Uint32 pos, Entry *) const; + Uint64 & get64(Uint32 index) const; + char * & getString(Uint32 index) const; + + Uint32 m_size; + Uint32 m_dataSize; + Uint32 m_stringCount; + Uint32 m_int64Count; + + Uint32 m_values[1]; + void * m_data[1]; +}; + +class ConfigValuesFactory { + Uint32 m_currentSection; +public: + Uint32 m_sectionCounter; + Uint32 m_freeKeys; + Uint32 m_freeData; + +public: + ConfigValuesFactory(Uint32 keys = 50, Uint32 data = 10); // Initial + ConfigValuesFactory(ConfigValues * m_cfg); // + + ConfigValues * m_cfg; + ConfigValues * getConfigValues(); + + bool openSection(Uint32 key, Uint32 no); + bool put(const ConfigValues::Entry & ); + bool put(Uint32 key, Uint32 value); + bool put64(Uint32 key, Uint64 value); + bool put(Uint32 key, const char * value); + bool closeSection(); + + void expand(Uint32 freeKeys, Uint32 freeData); + void shrink(); + + bool unpack(const UtilBuffer&); + bool unpack(const void * src, Uint32 len); + + static ConfigValues * extractCurrentSection(const ConfigValues::ConstIterator &); + +private: + static ConfigValues * create(Uint32 keys, Uint32 data); + void put(const ConfigValues & src); +}; + +inline +bool +ConfigValues::ConstIterator::get(Uint32 key, Uint32 * value) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == IntType){ + * value = tmp.m_int; + return true; + } + return false; +} + +inline +bool +ConfigValues::ConstIterator::get(Uint32 key, Uint64 * value) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == Int64Type){ + * value = tmp.m_int64; + return true; + } + return false; +} + +inline +bool +ConfigValues::ConstIterator::get(Uint32 key, const char ** value) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == StringType){ + * value = tmp.m_string; + return true; + } + return false; +} + +inline +bool +ConfigValues::ConstIterator::getTypeOf(Uint32 key, ValueType * type) const{ + Entry tmp; + if(get(key, &tmp)){ + * type = tmp.m_type; + return true; + } + return false; +} + +inline +Uint32 +ConfigValues::ConstIterator::get(Uint32 key, Uint32 notFound) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == IntType){ + return tmp.m_int; + } + return notFound; +} + +inline +Uint64 +ConfigValues::ConstIterator::get64(Uint32 key, Uint64 notFound) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == Int64Type){ + return tmp.m_int64; + } + return notFound; +} + +inline +const char * +ConfigValues::ConstIterator::get(Uint32 key, const char * notFound) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == StringType){ + return tmp.m_string; + } + return notFound; +} + +inline +ConfigValues::ValueType +ConfigValues::ConstIterator::getTypeOf(Uint32 key) const{ + Entry tmp; + if(get(key, &tmp)){ + return tmp.m_type; + } + return ConfigValues::InvalidType; +} + +inline +bool +ConfigValuesFactory::put(Uint32 key, Uint32 val){ + ConfigValues::Entry tmp; + tmp.m_key = key; + tmp.m_type = ConfigValues::IntType; + tmp.m_int = val; + return put(tmp); +} + +inline +bool +ConfigValuesFactory::put64(Uint32 key, Uint64 val){ + ConfigValues::Entry tmp; + tmp.m_key = key; + tmp.m_type = ConfigValues::Int64Type; + tmp.m_int64 = val; + return put(tmp); +} + +inline +bool +ConfigValuesFactory::put(Uint32 key, const char * val){ + ConfigValues::Entry tmp; + tmp.m_key = key; + tmp.m_type = ConfigValues::StringType; + tmp.m_string = val; + return put(tmp); +} + +inline +Uint32 +ConfigValues::pack(UtilBuffer& buf) const { + Uint32 len = getPackedSize(); + void * tmp = buf.append(len); + if(tmp == 0){ + return 0; + } + return pack(tmp, len); +} + +inline +bool +ConfigValuesFactory::unpack(const UtilBuffer& buf){ + return unpack(buf.get_data(), buf.length()); +} + +#endif diff --git a/ndb/include/util/Properties.hpp b/ndb/include/util/Properties.hpp index ff5d1338c79..2c30f7f7e3c 100644 --- a/ndb/include/util/Properties.hpp +++ b/ndb/include/util/Properties.hpp @@ -22,9 +22,10 @@ #include <UtilBuffer.hpp> enum PropertiesType { - PropertiesType_Uint32, - PropertiesType_char, - PropertiesType_Properties + PropertiesType_Uint32 = 0, + PropertiesType_char = 1, + PropertiesType_Properties = 2, + PropertiesType_Uint64 = 3 }; /** @@ -36,6 +37,7 @@ enum PropertiesType { */ struct Property { Property(const char* name, Uint32 val); + Property(const char* name, Uint64 val); Property(const char* name, const char * value); Property(const char* name, const class Properties * value); ~Property(); @@ -75,6 +77,7 @@ public: void put(const Property *, int len); bool put(const char * name, Uint32 value, bool replace = false); + bool put64(const char * name, Uint64 value, bool replace = false); bool put(const char * name, const char * value, bool replace = false); bool put(const char * name, const Properties * value, bool replace = false); @@ -84,6 +87,7 @@ public: * Compare get(name, no) */ bool put(const char *, Uint32 no, Uint32, bool replace = false); + bool put64(const char *, Uint32 no, Uint64, bool replace = false); bool put(const char *, Uint32 no, const char *, bool replace = false); bool put(const char *, Uint32 no, const Properties *, bool replace = false); @@ -94,6 +98,7 @@ public: bool contains(const char * name) const; bool get(const char * name, Uint32 * value) const; + bool get(const char * name, Uint64 * value) const; bool get(const char * name, const char ** value) const; bool get(const char * name, BaseString & value) const; bool get(const char * name, const Properties ** value) const; @@ -109,6 +114,7 @@ public: bool contains(const char * name, Uint32 no) const; bool get(const char * name, Uint32 no, Uint32 * value) const; + bool get(const char * name, Uint32 no, Uint64 * value) const; bool get(const char * name, Uint32 no, const char ** value) const; bool get(const char * name, Uint32 no, const Properties ** value) const; @@ -230,11 +236,12 @@ Properties::unpack(UtilBuffer &buf) { inline bool Properties::pack(UtilBuffer &buf) const { Uint32 size = getPackedSize(); - char *tmp_buf = new char[size]; + void *tmp_buf = buf.append(size); + if(tmp_buf == 0) + return false; bool ret = pack((Uint32 *)tmp_buf); if(ret == false) return false; - buf.append(tmp_buf, size); return true; } diff --git a/ndb/include/util/UtilBuffer.hpp b/ndb/include/util/UtilBuffer.hpp index b357fa0fdf2..f43fc960a16 100644 --- a/ndb/include/util/UtilBuffer.hpp +++ b/ndb/include/util/UtilBuffer.hpp @@ -63,6 +63,15 @@ public: return 0; }; + void * append(size_t l){ + if(grow(len+l) != 0) + return 0; + + void * ret = (char*)data+len; + len += l; + return ret; + } + int assign(const void * d, size_t l) { if (data) free(data); data = NULL; diff --git a/ndb/src/common/debugger/LogLevel.cpp b/ndb/src/common/debugger/LogLevel.cpp index 5348924bbbb..f9e2f318432 100644 --- a/ndb/src/common/debugger/LogLevel.cpp +++ b/ndb/src/common/debugger/LogLevel.cpp @@ -17,13 +17,14 @@ #include <LogLevel.hpp> const LogLevel::LogLevelCategoryName LogLevel::LOGLEVEL_CATEGORY_NAME[] = { - {"LogLevelStartup"}, - {"LogLevelShutdown"}, - {"LogLevelStatistic"}, - {"LogLevelCheckpoint"}, - {"LogLevelNodeRestart"}, - {"LogLevelConnection"}, - {"LogLevelError"}, - {"LogLevelInfo"}, - {"LogLevelGrep"} + { "LogLevelStartup" }, + { "LogLevelShutdown" }, + { "LogLevelStatistic" }, + { "LogLevelCheckpoint" }, + { "LogLevelNodeRestart" }, + { "LogLevelConnection" }, + { "LogLevelError" }, + { "LogLevelWarning" }, + { "LogLevelInfo" }, + { "LogLevelGrep" } }; diff --git a/ndb/src/common/debugger/signaldata/CntrStart.cpp b/ndb/src/common/debugger/signaldata/CntrStart.cpp new file mode 100644 index 00000000000..154013f40b0 --- /dev/null +++ b/ndb/src/common/debugger/signaldata/CntrStart.cpp @@ -0,0 +1,37 @@ +#include <signaldata/CntrStart.hpp> + +bool +printCNTR_START_REQ(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const CntrStartReq * const sig = (CntrStartReq *)theData; + fprintf(output, " nodeId: %x\n", sig->nodeId); + fprintf(output, " startType: %x\n", sig->startType); + fprintf(output, " lastGci: %x\n", sig->lastGci); + return true; +} + +bool +printCNTR_START_REF(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const CntrStartRef * const sig = (CntrStartRef *)theData; + fprintf(output, " errorCode: %x\n", sig->errorCode); + fprintf(output, " masterNodeId: %x\n", sig->masterNodeId); + return true; +} + +bool +printCNTR_START_CONF(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const CntrStartConf * const sig = (CntrStartConf *)theData; + fprintf(output, " startType: %x\n", sig->startType); + fprintf(output, " startGci: %x\n", sig->startGci); + fprintf(output, " masterNodeId: %x\n", sig->masterNodeId); + fprintf(output, " noStartNodes: %x\n", sig->noStartNodes); + + char buf[32*NdbNodeBitmask::Size+1]; + fprintf(output, " startedNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startedNodes, buf)); + fprintf(output, " startingNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startingNodes, buf)); + return true; +} diff --git a/ndb/src/common/debugger/signaldata/DictTabInfo.cpp b/ndb/src/common/debugger/signaldata/DictTabInfo.cpp index a0e0195adad..7e7bf87e2db 100644 --- a/ndb/src/common/debugger/signaldata/DictTabInfo.cpp +++ b/ndb/src/common/debugger/signaldata/DictTabInfo.cpp @@ -48,6 +48,7 @@ DictTabInfo::TableMapping[] = { DTIMAP(Table, CustomTriggerId, CustomTriggerId), DTIMAP2(Table, FrmLen, FrmLen, 0, MAX_FRM_DATA_SIZE), DTIMAPB(Table, FrmData, FrmData, 0, MAX_FRM_DATA_SIZE, FrmLen), + DTIMAP(Table, FragmentCount, FragmentCount), DTIBREAK(AttributeName) }; @@ -128,6 +129,7 @@ DictTabInfo::Table::init(){ CustomTriggerId = RNIL; FrmLen = 0; memset(FrmData, 0, sizeof(FrmData)); + FragmentCount = 0; } void diff --git a/ndb/src/common/debugger/signaldata/Makefile_old b/ndb/src/common/debugger/signaldata/Makefile_old index 5e86aaf97c0..bd00667b482 100644 --- a/ndb/src/common/debugger/signaldata/Makefile_old +++ b/ndb/src/common/debugger/signaldata/Makefile_old @@ -25,6 +25,7 @@ SOURCES = TcKeyReq.cpp TcKeyConf.cpp TcKeyRef.cpp \ CopyGCI.cpp SystemError.cpp StartRec.cpp NFCompleteRep.cpp \ FailRep.cpp DisconnectRep.cpp SignalDroppedRep.cpp \ SumaImpl.cpp NdbSttor.cpp CreateFragmentation.cpp \ + CntrStart.cpp ReadNodesConf.cpp \ UtilLock.cpp TuxMaint.cpp TupAccess.cpp AccLock.cpp \ LqhTrans.cpp diff --git a/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp b/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp new file mode 100644 index 00000000000..103f4a884f1 --- /dev/null +++ b/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp @@ -0,0 +1,24 @@ +#include <signaldata/ReadNodesConf.hpp> + +bool +printREAD_NODES_CONF(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const ReadNodesConf * const sig = (ReadNodesConf *)theData; + fprintf(output, " noOfNodes: %x\n", sig->noOfNodes); + fprintf(output, " ndynamicId: %x\n", sig->ndynamicId); + fprintf(output, " masterNodeId: %x\n", sig->masterNodeId); + + char buf[32*NdbNodeBitmask::Size+1]; + fprintf(output, " allNodes(defined): %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->allNodes, buf)); + fprintf(output, " inactiveNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->inactiveNodes, buf)); + fprintf(output, " clusterNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->clusterNodes, buf)); + fprintf(output, " startedNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startedNodes, buf)); + fprintf(output, " startingNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startingNodes, buf)); + return true; +} + diff --git a/ndb/src/common/debugger/signaldata/ScanTab.cpp b/ndb/src/common/debugger/signaldata/ScanTab.cpp index b4246059f6a..776e9cf3bfc 100644 --- a/ndb/src/common/debugger/signaldata/ScanTab.cpp +++ b/ndb/src/common/debugger/signaldata/ScanTab.cpp @@ -30,20 +30,34 @@ printSCANTABREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiv fprintf(output, " apiConnectPtr: H\'%.8x\n", sig->apiConnectPtr); fprintf(output, " requestInfo: H\'%.8x:\n", requestInfo); - fprintf(output, " Parallellism: %u, LockMode: %u, Holdlock: %u, RangeScan: %u\n", - sig->getParallelism(requestInfo), sig->getLockMode(requestInfo), sig->getHoldLockFlag(requestInfo), sig->getRangeScanFlag(requestInfo)); - + fprintf(output, " Parallellism: %u, Batch: %u LockMode: %u, Holdlock: %u, RangeScan: %u\n", + sig->getParallelism(requestInfo), + sig->getScanBatch(requestInfo), + sig->getLockMode(requestInfo), + sig->getHoldLockFlag(requestInfo), + sig->getRangeScanFlag(requestInfo)); + fprintf(output, " attrLen: %d, tableId: %d, tableSchemaVer: %d\n", sig->attrLen, sig->tableId, sig->tableSchemaVersion); fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x) storedProcId: H\'%.8x\n", sig->transId1, sig->transId2, sig->storedProcId); - fprintf(output, " OperationPtr(s):\n"); - for(int i = 0; i<16; i=i+4){ - fprintf(output, " H\'%.8x, H\'%.8x, H\'%.8x, H\'%.8x\n", - sig->apiOperationPtr[i], sig->apiOperationPtr[i+1], - sig->apiOperationPtr[i+2], sig->apiOperationPtr[i+3]); + fprintf(output, " OperationPtr(s):\n "); + Uint32 restLen = (len - 9); + const Uint32 * rest = &sig->apiOperationPtr[0]; + while(restLen >= 7){ + fprintf(output, + " H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x\n", + rest[0], rest[1], rest[2], rest[3], + rest[4], rest[5], rest[6]); + restLen -= 7; + rest += 7; + } + if(restLen > 0){ + for(Uint32 i = 0; i<restLen; i++) + fprintf(output, " H\'%.8x", rest[i]); + fprintf(output, "\n"); } return false; } @@ -60,23 +74,8 @@ printSCANTABCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 recei fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x)\n", sig->transId1, sig->transId2); - fprintf(output, " requestInfo: H\'%.8x(Operations: %u, ScanStatus: %u(\"", - requestInfo, sig->getOperations(requestInfo), sig->getScanStatus(requestInfo)); - switch(sig->getScanStatus(requestInfo)){ - case 0: - fprintf(output, "ZFALSE"); - break; - case 1: - fprintf(output, "ZTRUE"); - break; - case 2: - fprintf(output, "ZCLOSED"); - break; - default: - fprintf(output, "UNKNOWN"); - break; - } - fprintf(output, "\"))\n"); + fprintf(output, " requestInfo: H\'%.8x(EndOfData: %d)\n", + requestInfo, (requestInfo & ScanTabConf::EndOfData != 0)); #if 0 fprintf(output, " Operation(s):\n"); for(int i = 0; i<16; i++){ diff --git a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp index 2236d0c0af1..d49e316ad38 100644 --- a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp +++ b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp @@ -70,6 +70,8 @@ #include <signaldata/NdbSttor.hpp> #include <signaldata/CreateFragmentation.hpp> #include <signaldata/UtilLock.hpp> +#include <signaldata/CntrStart.hpp> +#include <signaldata/ReadNodesConf.hpp> #include <signaldata/TuxMaint.hpp> #include <signaldata/TupAccess.hpp> #include <signaldata/AccLock.hpp> @@ -240,6 +242,12 @@ SignalDataPrintFunctions[] = { ,{ GSN_UTIL_UNLOCK_REQ, printUTIL_UNLOCK_REQ } ,{ GSN_UTIL_UNLOCK_REF, printUTIL_UNLOCK_REF } ,{ GSN_UTIL_UNLOCK_CONF, printUTIL_UNLOCK_CONF } + ,{ GSN_CNTR_START_REQ, printCNTR_START_REQ } + ,{ GSN_CNTR_START_REF, printCNTR_START_REF } + ,{ GSN_CNTR_START_CONF, printCNTR_START_CONF } + + ,{ GSN_READ_NODESCONF, printREAD_NODES_CONF } + ,{ GSN_TUX_MAINT_REQ, printTUX_MAINT_REQ } ,{ GSN_TUP_READ_ATTRS, printTUP_READ_ATTRS } ,{ GSN_TUP_QUERY_TH, printTUP_QUERY_TH } diff --git a/ndb/src/common/debugger/signaldata/SignalNames.cpp b/ndb/src/common/debugger/signaldata/SignalNames.cpp index 4e5c8603db1..377a588dbb0 100644 --- a/ndb/src/common/debugger/signaldata/SignalNames.cpp +++ b/ndb/src/common/debugger/signaldata/SignalNames.cpp @@ -101,40 +101,23 @@ const GsnName SignalNames [] = { ,{ GSN_ADD_FRAGREQ, "ADD_FRAGREQ" } ,{ GSN_API_FAILCONF, "API_FAILCONF" } ,{ GSN_API_FAILREQ, "API_FAILREQ" } - ,{ GSN_APPL_CHANGEREP, "APPL_CHANGEREP" } - // ,{ GSN_APPL_ERROR, "APPL_ERROR" } - ,{ GSN_APPL_HB, "APPL_HB" } - ,{ GSN_APPL_HBREQ, "APPL_HBREQ" } - ,{ GSN_APPL_REGCONF, "APPL_REGCONF" } - ,{ GSN_APPL_REGREF, "APPL_REGREF" } - ,{ GSN_APPL_REGREQ, "APPL_REGREQ" } - ,{ GSN_APPL_RUN, "APPL_RUN" } - ,{ GSN_APPL_STARTCONF, "APPL_STARTCONF" } - ,{ GSN_APPL_STARTREG, "APPL_STARTREG" } ,{ GSN_CHECK_LCP_STOP, "CHECK_LCP_STOP" } ,{ GSN_CLOSE_COMCONF, "CLOSE_COMCONF" } ,{ GSN_CLOSE_COMREQ, "CLOSE_COMREQ" } ,{ GSN_CM_ACKADD, "CM_ACKADD" } - ,{ GSN_CM_ACKALARM, "CM_ACKALARM" } ,{ GSN_CM_ADD, "CM_ADD" } - ,{ GSN_CM_APPCHG, "CM_APPCHG" } + ,{ GSN_CM_ADD_REP, "CM_ADD_REP" } ,{ GSN_CM_HEARTBEAT, "CM_HEARTBEAT" } - ,{ GSN_CM_INFOCONF, "CM_INFOCONF" } - ,{ GSN_CM_INFOREQ, "CM_INFOREQ" } - ,{ GSN_CM_INIT, "CM_INIT" } ,{ GSN_CM_NODEINFOCONF, "CM_NODEINFOCONF" } ,{ GSN_CM_NODEINFOREF, "CM_NODEINFOREF" } ,{ GSN_CM_NODEINFOREQ, "CM_NODEINFOREQ" } ,{ GSN_CM_REGCONF, "CM_REGCONF" } ,{ GSN_CM_REGREF, "CM_REGREF" } ,{ GSN_CM_REGREQ, "CM_REGREQ" } - ,{ GSN_CM_RUN, "CM_RUN" } - ,{ GSN_CMVMI_CFGCONF, "CMVMI_CFGCONF" } - ,{ GSN_CMVMI_CFGREQ, "CMVMI_CFGREQ" } - ,{ GSN_CNTR_CHANGEREP, "CNTR_CHANGEREP" } - ,{ GSN_CNTR_MASTERCONF, "CNTR_MASTERCONF" } - ,{ GSN_CNTR_MASTERREF, "CNTR_MASTERREF" } - ,{ GSN_CNTR_MASTERREQ, "CNTR_MASTERREQ" } + ,{ GSN_CNTR_START_REQ, "CNTR_START_REQ" } + ,{ GSN_CNTR_START_REF, "CNTR_START_REF" } + ,{ GSN_CNTR_START_CONF, "CNTR_START_CONF" } + ,{ GSN_CNTR_START_REP, "CNTR_START_REP" } ,{ GSN_CNTR_WAITREP, "CNTR_WAITREP" } ,{ GSN_COMMIT, "COMMIT" } ,{ GSN_COMMIT_FAILCONF, "COMMIT_FAILCONF" } @@ -294,9 +277,6 @@ const GsnName SignalNames [] = { ,{ GSN_NEXT_SCANREQ, "NEXT_SCANREQ" } ,{ GSN_NEXTOPERATION, "NEXTOPERATION" } ,{ GSN_NF_COMPLETEREP, "NF_COMPLETEREP" } - ,{ GSN_NODE_STATESCONF, "NODE_STATESCONF" } - ,{ GSN_NODE_STATESREF, "NODE_STATESREF" } - ,{ GSN_NODE_STATESREQ, "NODE_STATESREQ" } ,{ GSN_OPEN_COMCONF, "OPEN_COMCONF" } ,{ GSN_OPEN_COMREF, "OPEN_COMREF" } ,{ GSN_OPEN_COMREQ, "OPEN_COMREQ" } @@ -318,8 +298,8 @@ const GsnName SignalNames [] = { ,{ GSN_SEND_PACKED, "SEND_PACKED" } ,{ GSN_SET_LOGLEVELORD, "SET_LOGLEVELORD" } ,{ GSN_SHRINKCHECK2, "SHRINKCHECK2" } - ,{ GSN_SIZEALT_ACK, "SIZEALT_ACK" } - ,{ GSN_SIZEALT_REP, "SIZEALT_REP" } + ,{ GSN_READ_CONFIG_REQ, "READ_CONFIG_REQ" } + ,{ GSN_READ_CONFIG_CONF, "READ_CONFIG_CONF" } ,{ GSN_SR_FRAGIDCONF, "SR_FRAGIDCONF" } ,{ GSN_SR_FRAGIDREF, "SR_FRAGIDREF" } ,{ GSN_SR_FRAGIDREQ, "SR_FRAGIDREQ" } @@ -396,7 +376,6 @@ const GsnName SignalNames [] = { ,{ GSN_UPDATE_TOCONF, "UPDATE_TOCONF" } ,{ GSN_UPDATE_TOREF, "UPDATE_TOREF" } ,{ GSN_UPDATE_TOREQ, "UPDATE_TOREQ" } - ,{ GSN_VOTE_MASTERORD, "VOTE_MASTERORD" } ,{ GSN_TUP_ALLOCREQ, "TUP_ALLOCREQ" } ,{ GSN_LQH_ALLOCREQ, "LQH_ALLOCREQ" } ,{ GSN_TUP_DEALLOCREQ, "TUP_DEALLOCREQ" } @@ -428,7 +407,6 @@ const GsnName SignalNames [] = { ,{ GSN_CHECKNODEGROUPSREQ, "CHECKNODEGROUPSREQ" } ,{ GSN_CHECKNODEGROUPSCONF, "CHECKNODEGROUPSCONF" } - ,{ GSN_ARBIT_CFG, "ARBIT_CFG" } ,{ GSN_ARBIT_PREPREQ, "ARBIT_PREPREQ" } ,{ GSN_ARBIT_PREPCONF, "ARBIT_PREPCONF" } ,{ GSN_ARBIT_PREPREF, "ARBIT_PREPREF" } diff --git a/ndb/src/common/mgmcommon/Config.cpp b/ndb/src/common/mgmcommon/Config.cpp index 5492394ee4a..c0819b9f463 100644 --- a/ndb/src/common/mgmcommon/Config.cpp +++ b/ndb/src/common/mgmcommon/Config.cpp @@ -26,23 +26,17 @@ //***************************************************************************** Config::Config() { - m_info = new ConfigInfo(); -} - -Config::Config(const Config & org) : - Properties(org) { - - m_info = new ConfigInfo(); -} - -Config::Config(const Properties & org) : - Properties(org) { - - m_info = new ConfigInfo(); + m_oldConfig = 0; + m_configValues = 0; } Config::~Config() { - delete m_info; + if(m_configValues != 0){ + free(m_configValues); + } + + if(m_oldConfig != 0) + delete m_oldConfig; } /*****************************************************************************/ @@ -52,25 +46,33 @@ Config::printAllNameValuePairs(NdbOut &out, const Properties *prop, const char* s) const { Properties::Iterator it(prop); - const Properties * section = m_info->getInfo(s); + const Properties * section = m_info.getInfo(s); for (const char* n = it.first(); n != NULL; n = it.next()) { Uint32 int_value; const char* str_value; + Uint64 int_64; - if (m_info->getStatus(section, n) == ConfigInfo::INTERNAL) + if(!section->contains(n)) continue; - if (m_info->getStatus(section, n) == ConfigInfo::DEPRICATED) + if (m_info.getStatus(section, n) == ConfigInfo::INTERNAL) continue; - if (m_info->getStatus(section, n) == ConfigInfo::NOTIMPLEMENTED) + if (m_info.getStatus(section, n) == ConfigInfo::DEPRICATED) + continue; + if (m_info.getStatus(section, n) == ConfigInfo::NOTIMPLEMENTED) continue; out << n << ": "; - switch (m_info->getType(section, n)) { + switch (m_info.getType(section, n)) { case ConfigInfo::INT: MGM_REQUIRE(prop->get(n, &int_value)); out << int_value; break; + + case ConfigInfo::INT64: + MGM_REQUIRE(prop->get(n, &int_64)); + out << int_64; + break; case ConfigInfo::BOOL: MGM_REQUIRE(prop->get(n, &int_value)); @@ -92,6 +94,7 @@ Config::printAllNameValuePairs(NdbOut &out, /*****************************************************************************/ void Config::printConfigFile(NdbOut &out) const { +#if 0 Uint32 noOfNodes, noOfConnections, noOfComputers; MGM_REQUIRE(get("NoOfNodes", &noOfNodes)); MGM_REQUIRE(get("NoOfConnections", &noOfConnections)); @@ -172,15 +175,12 @@ void Config::printConfigFile(NdbOut &out) const { endl; } } -} - -const -ConfigInfo* Config::getConfigInfo() const { - return m_info; +#endif } Uint32 Config::getGenerationNumber() const { +#if 0 Uint32 ret; const Properties *prop = NULL; @@ -191,10 +191,14 @@ Config::getGenerationNumber() const { return ret; return 0; +#else + return 0; +#endif } int Config::setGenerationNumber(Uint32 gen) { +#if 0 Properties *prop = NULL; getCopy("SYSTEM", &prop); @@ -205,12 +209,16 @@ Config::setGenerationNumber(Uint32 gen) { return 0; } return -1; +#else + return -1; +#endif } bool Config::change(const BaseString §ion, const BaseString ¶m, const BaseString &value) { +#if 0 const char *name; Properties::Iterator it(this); @@ -252,4 +260,7 @@ Config::change(const BaseString §ion, } } return true; +#else + return false; +#endif } diff --git a/ndb/src/common/mgmcommon/Config.hpp b/ndb/src/common/mgmcommon/Config.hpp index 284256d9ed6..26fd53dbed2 100644 --- a/ndb/src/common/mgmcommon/Config.hpp +++ b/ndb/src/common/mgmcommon/Config.hpp @@ -17,7 +17,6 @@ #ifndef Config_H #define Config_H -#include <signaldata/ConfigParamId.hpp> #include <LogLevel.hpp> #include <kernel_types.h> @@ -25,6 +24,9 @@ #include <NdbOut.hpp> #include <ndb_limits.h> #include <Properties.hpp> +#include "ConfigInfo.hpp" + +class ConfigInfo; /** * @class Config @@ -38,14 +40,14 @@ * * The following categories (sections) of configuration parameters exists: * - COMPUTER, DB, MGM, API, TCP, SCI, SHM, OSE + * */ -class Config : public Properties { + +class Config { public: /** * Constructor which loads the object with an Properties object */ - Config(const Config & org); - Config(const Properties & org); Config(); virtual ~Config(); @@ -58,8 +60,6 @@ public: printConfigFile(ndb); } - const class ConfigInfo* getConfigInfo() const; - Uint32 getGenerationNumber() const; int setGenerationNumber(Uint32); @@ -69,7 +69,13 @@ public: const BaseString ¶m, const BaseString &value); + + /** + * Info + */ + const ConfigInfo * getConfigInfo() const { return &m_info;} private: + ConfigInfo m_info; void printAllNameValuePairs(NdbOut &out, const Properties *prop, @@ -78,7 +84,9 @@ private: /** * Information about parameters (min, max values etc) */ - const class ConfigInfo* m_info; +public: + Properties * m_oldConfig; + struct ndb_mgm_configuration * m_configValues; }; #endif // Config_H diff --git a/ndb/src/common/mgmcommon/ConfigInfo.cpp b/ndb/src/common/mgmcommon/ConfigInfo.cpp index da6024d946f..57d1a2fe8fd 100644 --- a/ndb/src/common/mgmcommon/ConfigInfo.cpp +++ b/ndb/src/common/mgmcommon/ConfigInfo.cpp @@ -15,7 +15,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ConfigInfo.hpp" +#include <mgmapi_config_parameters.h> + #define MAX_LINE_LENGTH 255 +#define KEY_INTERNAL 0 /**************************************************************************** * Section names @@ -56,9 +59,12 @@ bool fixPortNumber(InitConfigFileParser::Context & ctx, const char *); bool fixShmkey(InitConfigFileParser::Context & ctx, const char *); bool checkDbConstraints(InitConfigFileParser::Context & ctx, const char *); bool checkConnectionConstraints(InitConfigFileParser::Context &, const char *); +bool fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data); bool fixHostname(InitConfigFileParser::Context & ctx, const char * data); bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data); bool fixExtConnection(InitConfigFileParser::Context & ctx, const char * data); +bool fixDepricated(InitConfigFileParser::Context & ctx, const char *); +bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char *); const ConfigInfo::SectionRule ConfigInfo::m_SectionRules[] = { @@ -79,21 +85,12 @@ ConfigInfo::m_SectionRules[] = { { "TCP", fixPortNumber, 0 }, //{ "SHM", fixShmKey, 0 }, - - { "COMPUTER", applyDefaultValues, 0 }, - - { "DB", applyDefaultValues, 0 }, - { "API", applyDefaultValues, 0 }, - { "MGM", applyDefaultValues, 0 }, - { "REP", applyDefaultValues, 0 }, - { "EXTERNAL REP", applyDefaultValues, 0 }, - - { "TCP", applyDefaultValues, 0 }, - { "SHM", applyDefaultValues, 0 }, - { "SCI", applyDefaultValues, 0 }, - { "OSE", applyDefaultValues, 0 }, - { "DB", checkDbConstraints, 0 }, + { "DB", fixNodeHostname, 0 }, + { "API", fixNodeHostname, 0 }, + { "MGM", fixNodeHostname, 0 }, + { "REP", fixNodeHostname, 0 }, + //{ "EXTERNAL REP", fixNodeHostname, 0 }, { "TCP", fixNodeId, "NodeId1" }, { "TCP", fixNodeId, "NodeId2" }, @@ -103,6 +100,11 @@ ConfigInfo::m_SectionRules[] = { { "SCI", fixNodeId, "NodeId2" }, { "OSE", fixNodeId, "NodeId1" }, { "OSE", fixNodeId, "NodeId2" }, + + { "TCP", fixHostname, "HostName1" }, + { "TCP", fixHostname, "HostName2" }, + { "OSE", fixHostname, "HostName1" }, + { "OSE", fixHostname, "HostName2" }, /** * fixExtConnection must be after fixNodeId @@ -112,6 +114,12 @@ ConfigInfo::m_SectionRules[] = { { "SCI", fixExtConnection, 0 }, { "OSE", fixExtConnection, 0 }, + { "*", applyDefaultValues, "user" }, + { "*", fixDepricated, 0 }, + { "*", applyDefaultValues, "system" }, + + { "DB", checkDbConstraints, 0 }, + /** * checkConnectionConstraints must be after fixExtConnection */ @@ -120,24 +128,50 @@ ConfigInfo::m_SectionRules[] = { { "SCI", checkConnectionConstraints, 0 }, { "OSE", checkConnectionConstraints, 0 }, - { "COMPUTER", checkMandatory, 0 }, - { "DB", checkMandatory, 0 }, - { "API", checkMandatory, 0 }, - { "MGM", checkMandatory, 0 }, - { "REP", checkMandatory, 0 }, + { "*", checkMandatory, 0 }, + + { "DB", saveInConfigValues, 0 }, + { "API", saveInConfigValues, 0 }, + { "MGM", saveInConfigValues, 0 }, + { "REP", saveInConfigValues, 0 }, + + { "TCP", saveInConfigValues, 0 }, + { "SHM", saveInConfigValues, 0 }, + { "SCI", saveInConfigValues, 0 }, + { "OSE", saveInConfigValues, 0 } +}; +const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule); - { "TCP", checkMandatory, 0 }, - { "SHM", checkMandatory, 0 }, - { "SCI", checkMandatory, 0 }, - { "OSE", checkMandatory, 0 }, +struct DepricationTransform { + const char * m_section; + const char * m_oldName; + const char * m_newName; + double m_add; + double m_mul; +}; - { "TCP", fixHostname, "HostName1" }, - { "TCP", fixHostname, "HostName2" }, - { "OSE", fixHostname, "HostName1" }, - { "OSE", fixHostname, "HostName2" }, +static +const DepricationTransform f_deprication[] = { + { "DB", "NoOfIndexPages", "IndexMemory", 0, 8192 } + ,{ "DB", "MemorySpaceIndexes", "IndexMemory", 0, 8192 } + ,{ "DB", "NoOfDataPages", "DataMemory", 0, 8192 } + ,{ "DB", "MemorySpaceTuples", "DataMemory", 0, 8192 } + ,{ "DB", "TransactionInactiveTimeBeforeAbort", "TransactionInactiveTimeout", + 0, 1 } + ,{ "TCP", "ProcessId1", "NodeId1", 0, 1} + ,{ "TCP", "ProcessId2", "NodeId2", 0, 1} + ,{ "TCP", "SendBufferSize", "SendBufferMemory", 0, 16384 } + ,{ "TCP", "MaxReceiveSize", "ReceiveBufferMemory", 0, 16384 } + + ,{ "SHM", "ProcessId1", "NodeId1", 0, 1} + ,{ "SHM", "ProcessId2", "NodeId2", 0, 1} + ,{ "SCI", "ProcessId1", "NodeId1", 0, 1} + ,{ "SCI", "ProcessId2", "NodeId2", 0, 1} + ,{ "OSE", "ProcessId1", "NodeId1", 0, 1} + ,{ "OSE", "ProcessId2", "NodeId2", 0, 1} + ,{ 0, 0, 0, 0, 0} }; -const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule); /** * The default constructors create objects with suitable values for the @@ -166,224 +200,340 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { /**************************************************************************** * COMPUTER - ****************************************************************************/ - - {"Id", - "Id", - "COMPUTER", - "Name of computer", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0}, - - {"HostName", - "HostName", - "COMPUTER", - "Hostname of computer (e.g. mysql.com)", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ByteOrder", - "ByteOrder", - "COMPUTER", - "Not yet implemented", - ConfigInfo::USED, // Actually not used, but since it is MANDATORY, - // we don't want any warning message - false, - ConfigInfo::STRING, - MANDATORY, // Big == 0, Little == 1, NotSet == 2 (?) - 0, - 0x7FFFFFFF}, + ***************************************************************************/ + { + KEY_INTERNAL, + "COMPUTER", + "COMPUTER", + "Computer section", + ConfigInfo::INTERNAL, + false, + ConfigInfo::SECTION, + 0, + 0, 0 }, + + { + KEY_INTERNAL, + "Id", + "COMPUTER", + "Name of computer", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0 }, + + { + KEY_INTERNAL, + "HostName", + "COMPUTER", + "Hostname of computer (e.g. alzato.com)", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_BYTE_ORDER, + "ByteOrder", + "COMPUTER", + "Not yet implemented", + ConfigInfo::USED, // Actually not used, but since it is MANDATORY, + // we don't want any warning message + false, + ConfigInfo::STRING, + MANDATORY, // Big == 0, Little == 1, NotSet == 2 (?) + 0, + 1 }, /**************************************************************************** - * DB - ****************************************************************************/ - - {"Id", - "Id", - "DB", - "Number identifying the database node (DB)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - (MAX_NODES - 1)}, - - {"Type", - "Type", - "DB", - "Type of node (Should have value DB)", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"NoOfReplicas", - "NoOfReplicas", - "DB", - "Number of copies of all data in the database (1-4)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - 4}, - - {"MaxNoOfAttributes", - "MaxNoOfAttributes", - "DB", - "Total number of attributes stored in database. I.e. sum over all tables", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1000, - 32, - 4096}, + * SYSTEM + ***************************************************************************/ + { + CFG_SECTION_SYSTEM, + "SYSTEM", + "SYSTEM", + "System section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + CFG_SECTION_SYSTEM, + 0, + 0 }, + + { + CFG_SYS_NAME, + "Name", + "SYSTEM", + "Name of system (NDB Cluster)", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0 }, - {"MaxNoOfTables", - "MaxNoOfTables", - "DB", - "Total number of tables stored in the database", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 32, - 8, - 128}, + { + CFG_SYS_REPLICATION_ROLE, + "ReplicationRole", + "SYSTEM", + "Role in Global Replication (None, Primary, or Standby)", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0 }, - {"MaxNoOfIndexes", - "MaxNoOfIndexes", - "DB", - "Total number of indexes that can be defined in the system", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 128, - 0, - 2048}, - - {"MaxNoOfConcurrentIndexOperations", - "MaxNoOfConcurrentIndexOperations", - "DB", - "Total number of index operations that can execute simultaneously on one DB node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 8192, - 0, - 1000000 + { + CFG_SYS_PRIMARY_MGM_NODE, + "PrimaryMGMNode", + "SYSTEM", + "Node id of Primary MGM node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 0x7FFFFFFF }, + + { + CFG_SYS_CONFIG_GENERATION, + "ConfigGenerationNumber", + "SYSTEM", + "Configuration generation number", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 0x7FFFFFFF }, + + /*************************************************************************** + * DB + ***************************************************************************/ + { + CFG_SECTION_NODE, + "DB", + "DB", + "Node section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + NODE_TYPE_DB, + 0, 0 }, - {"MaxNoOfTriggers", - "MaxNoOfTriggers", - "DB", - "Total number of triggers that can be defined in the system", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 768, - 0, - 2432}, - - {"MaxNoOfFiredTriggers", - "MaxNoOfFiredTriggers", - "DB", - "Total number of triggers that can fire simultaneously in one DB node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1000, - 0, - 1000000}, - - {"ExecuteOnComputer", - "ExecuteOnComputer", - "DB", - "String referencing an earlier defined COMPUTER", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, + { + CFG_NODE_HOST, + "HostName", + "DB", + "Name of computer for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_SYSTEM, + "System", + "DB", + "Name of system for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ID, + "Id", + "DB", + "Number identifying the database node (DB)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 1, + (MAX_NODES - 1) }, + + { + CFG_DB_NO_REPLICAS, + "NoOfReplicas", + "DB", + "Number of copies of all data in the database (1-4)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 1, + 2 }, + + { + CFG_DB_NO_ATTRIBUTES, + "MaxNoOfAttributes", + "DB", + "Total number of attributes stored in database. I.e. sum over all tables", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1000, + 32, + 4096 }, - {"MaxNoOfSavedMessages", - "MaxNoOfSavedMessages", - "DB", - "Max number of error messages in error log and max number of trace files", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 25, - 0, - 0x7FFFFFFF}, - - {"LockPagesInMainMemory", - "LockPagesInMainMemory", - "DB", - "If set to yes, then NDB Cluster data will not be swapped out to disk", - ConfigInfo::USED, - true, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"SleepWhenIdle", - "SleepWhenIdle", - "DB", - "?", - ConfigInfo::DEPRICATED, - true, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - {"NoOfSignalsToExecuteBetweenCommunicationInterfacePoll", - "NoOfSignalsToExecuteBetweenCommunicationInterfacePoll", - "DB", - "?", - ConfigInfo::DEPRICATED, - true, - ConfigInfo::INT, - 20, - 1, - 0x7FFFFFFF}, + { + CFG_DB_NO_TABLES, + "MaxNoOfTables", + "DB", + "Total number of tables stored in the database", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 32, + 8, + 128 }, - {"TimeBetweenWatchDogCheck", - "TimeBetweenWatchDogCheck", - "DB", - "Time between execution checks inside a database node", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 4000, - 70, - 0x7FFFFFFF}, - - {"StopOnError", - "StopOnError", - "DB", - "If set to N, the DB automatically restarts/recovers in case of node failure", - ConfigInfo::USED, - true, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - { "RestartOnErrorInsert", + { + CFG_DB_NO_INDEXES, + "MaxNoOfIndexes", + "DB", + "Total number of indexes that can be defined in the system", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 128, + 0, + 2048 }, + + { + CFG_DB_NO_INDEX_OPS, + "MaxNoOfConcurrentIndexOperations", + "DB", + "Total number of index operations that can execute simultaneously on one DB node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 8192, + 0, + 1000000 + }, + + { + CFG_DB_NO_TRIGGERS, + "MaxNoOfTriggers", + "DB", + "Total number of triggers that can be defined in the system", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 768, + 0, + 2432 }, + + { + CFG_DB_NO_TRIGGER_OPS, + "MaxNoOfFiredTriggers", + "DB", + "Total number of triggers that can fire simultaneously in one DB node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1000, + 0, + 1000000 }, + + { + KEY_INTERNAL, + "ExecuteOnComputer", + "DB", + "String referencing an earlier defined COMPUTER", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_DB_NO_SAVE_MSGS, + "MaxNoOfSavedMessages", + "DB", + "Max number of error messages in error log and max number of trace files", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 25, + 0, + 0x7FFFFFFF }, + + { + CFG_DB_MEMLOCK, + "LockPagesInMainMemory", + "DB", + "If set to yes, then NDB Cluster data will not be swapped out to disk", + ConfigInfo::USED, + true, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "SleepWhenIdle", + "DB", + 0, + ConfigInfo::DEPRICATED, + true, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "NoOfSignalsToExecuteBetweenCommunicationInterfacePoll", + "DB", + 0, + ConfigInfo::DEPRICATED, + true, + ConfigInfo::INT, + 20, + 1, + 0x7FFFFFFF }, + + { + CFG_DB_WATCHDOG_INTERVAL, + "TimeBetweenWatchDogCheck", + "DB", + "Time between execution checks inside a database node", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 4000, + 70, + 0x7FFFFFFF }, + + { + CFG_DB_STOP_ON_ERROR, + "StopOnError", + "DB", + "If set to N, the DB automatically restarts/recovers in case of node failure", + ConfigInfo::USED, + true, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, + + { + CFG_DB_STOP_ON_ERROR_INSERT, "RestartOnErrorInsert", "DB", "See src/kernel/vm/Emulator.hpp NdbRestartType for details", @@ -394,41 +544,45 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 4 }, - {"MaxNoOfConcurrentOperations", - "MaxNoOfConcurrentOperations", - "DB", - "Max no of op:s on DB (op:s within a transaction are concurrently executed)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 8192, - 32, - 1000000}, - - {"MaxNoOfConcurrentTransactions", - "MaxNoOfConcurrentTransactions", - "DB", - "Max number of transaction executing concurrently on the DB node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 4096, - 32, - 1000000}, - - {"MaxNoOfConcurrentScans", - "MaxNoOfConcurrentScans", - "DB", - "Max number of scans executing concurrently on the DB node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 25, - 2, - 500}, - - {"TransactionBufferMemory", - "TransactionBufferMemory", + { + CFG_DB_NO_OPS, + "MaxNoOfConcurrentOperations", + "DB", + "Max no of op:s on DB (op:s within a transaction are concurrently executed)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 8192, + 32, + 1000000 }, + + { + CFG_DB_NO_TRANSACTIONS, + "MaxNoOfConcurrentTransactions", + "DB", + "Max number of transaction executing concurrently on the DB node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 4096, + 32, + 1000000 }, + + { + CFG_DB_NO_SCANS, + "MaxNoOfConcurrentScans", + "DB", + "Max number of scans executing concurrently on the DB node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 25, + 2, + 500 }, + + { + CFG_DB_TRANS_BUFFER_MEM, + "TransactionBufferMemory", "DB", "Dynamic buffer space (in bytes) for key and attribute data allocated for each DB node", ConfigInfo::USED, @@ -436,437 +590,429 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::INT, 1024000, 1024, - 0x7FFFFFFF}, + 0x7FFFFFFF }, - {"NoOfIndexPages", - "NoOfIndexPages", - "DB", - "Number of 8k byte pages on each DB node for storing indexes", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 3000, - 128, - 192000}, - - {"MemorySpaceIndexes", - "NoOfIndexPages", - "DB", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 128, - 192000}, - - {"NoOfDataPages", - "NoOfDataPages", - "DB", - "Number of 8k byte pages on each DB node for storing data", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 10000, - 128, - 400000}, - - {"MemorySpaceTuples", - "NoOfDataPages", - "DB", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 128, - 400000}, - - {"NoOfDiskBufferPages", - "NoOfDiskBufferPages", - "DB", - "?", - ConfigInfo::NOTIMPLEMENTED, - false, - ConfigInfo::INT, - 0, - 0, - 0}, - - {"MemoryDiskPages", - "NoOfDiskBufferPages", - "DB", - "?", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0}, - - {"NoOfFreeDiskClusters", - "NoOfFreeDiskClusters", - "DB", - "?", - ConfigInfo::NOTIMPLEMENTED, - false, - ConfigInfo::INT, - 0, - 0, - 0}, - - {"NoOfDiskClusters", - "NoOfDiskClusters", - "DB", - "?", - ConfigInfo::NOTIMPLEMENTED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, + { + CFG_DB_INDEX_MEM, + "IndexMemory", + "DB", + "Number bytes on each DB node allocated for storing indexes", + ConfigInfo::USED, + false, + ConfigInfo::INT64, + 3000 * 8192, + 128 * 8192, + 192000 * 8192 }, + + { + KEY_INTERNAL, + "NoOfIndexPages", + "DB", + "IndexMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + 3000, + 128, + 192000 }, + + { + KEY_INTERNAL, + "MemorySpaceIndexes", + "DB", + "IndexMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 128, + 192000 }, + + { + CFG_DB_DATA_MEM, + "DataMemory", + "DB", + "Number bytes on each DB node allocated for storing data", + ConfigInfo::USED, + false, + ConfigInfo::INT64, + 10000 * 8192, + 128 * 8192, + 400000 * 8192 }, + + { + KEY_INTERNAL, + "NoOfDataPages", + "DB", + "DataMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + 10000, + 128, + 400000 }, + + { + KEY_INTERNAL, + "MemorySpaceTuples", + "DB", + "DataMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 128, + 400000 }, - {"TimeToWaitAlive", - "TimeToWaitAlive", - "DB", - "Time to wait for other nodes to become alive during initial system start", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 25, - 2, - 4000}, - - {"HeartbeatIntervalDbDb", - "HeartbeatIntervalDbDb", - "DB", - "Time between DB-to-DB heartbeats. DB considered dead after 3 missed HBs", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1500, - 10, - 0x7FFFFFFF}, - - {"HeartbeatIntervalDbApi", - "HeartbeatIntervalDbApi", - "DB", - "Time between API-to-DB heartbeats. API connection closed after 3 missed HBs", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1500, - 100, - 0x7FFFFFFF}, - - {"TimeBetweenLocalCheckpoints", - "TimeBetweenLocalCheckpoints", - "DB", - "Time between taking snapshots of the database (expressed in 2log of bytes)", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 20, - 0, - 31}, - - {"TimeBetweenGlobalCheckpoints", - "TimeBetweenGlobalCheckpoints", - "DB", - "Time between doing group commit of transactions to disk", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 2000, - 10, - 32000}, - - {"NoOfFragmentLogFiles", - "NoOfFragmentLogFiles", - "DB", - "No of 16 Mbyte Redo log files in each of 4 file sets belonging to DB node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 8, - 1, - 0x7FFFFFFF}, - - {"MaxNoOfOpenFiles", - "MaxNoOfOpenFiles", - "DB", - "Max number of files open per DB node.(One thread is created per file)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 40, - 20, - 256}, - - {"NoOfConcurrentCheckpointsDuringRestart", - "NoOfConcurrentCheckpointsDuringRestart", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1, - 1, - 4}, + { + CFG_DB_START_PARTIAL_TIMEOUT, + "StartPartialTimeout", + "DB", + "Time to wait before trying to start wo/ all nodes. 0=Wait forever", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 30000, + 0, + ~0 }, + + { + CFG_DB_START_PARTITION_TIMEOUT, + "StartPartitionedTimeout", + "DB", + "Time to wait before trying to start partitioned. 0=Wait forever", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 60000, + 0, + ~0 }, - {"TimeBetweenInactiveTransactionAbortCheck", - "TimeBetweenInactiveTransactionAbortCheck", - "DB", - "Time between inactive transaction checks", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1000, - 1000, - 0x7FFFFFFF}, + { + CFG_DB_START_FAILURE_TIMEOUT, + "StartFailureTimeout", + "DB", + "Time to wait before terminating. 0=Wait forever", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 5*60000, + 0, + ~0 }, - {"TransactionInactiveTimeout", - "TransactionInactiveTimeout", - "DB", - "Time application can wait before executing another transaction part (ms).\n" - "This is the time the transaction coordinator waits for the application\n" - "to execute or send another part (query, statement) of the transaction.\n" - "If the application takes too long time, the transaction gets aborted.\n" - "Timeout set to 0 means that we don't timeout at all on application wait.", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 3000, - 0, - 0x7FFFFFFF}, - - {"TransactionDeadlockDetectionTimeout", - "TransactionDeadlockDetectionTimeout", - "DB", - "Time transaction can be executing in a DB node (ms).\n" - "This is the time the transaction coordinator waits for each database node\n" - "of the transaction to execute a request. If the database node takes too\n" - "long time, the transaction gets aborted.", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 3000, - 50, - 0x7FFFFFFF}, - - {"TransactionInactiveTimeBeforeAbort", - "TransactionInactiveTimeBeforeAbort", - "DB", - "Time a transaction can be inactive before getting aborted (ms)", - ConfigInfo::DEPRICATED, - true, - ConfigInfo::INT, - 3000, - 20, - 0x7FFFFFFF}, - - {"NoOfConcurrentProcessesHandleTakeover", - "NoOfConcurrentProcessesHandleTakeover", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1, - 1, - 15}, + { + KEY_INTERNAL, + "TimeToWaitAlive", + "DB", + "Start{Partial/Partitioned/Failure}Time", + ConfigInfo::DEPRICATED, + true, + ConfigInfo::INT, + 25, + 2, + 4000 }, + + { + CFG_DB_HEARTBEAT_INTERVAL, + "HeartbeatIntervalDbDb", + "DB", + "Time between DB-DB heartbeats. DB considered dead after 3 missed HBs", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 1500, + 10, + 0x7FFFFFFF }, + + { + CFG_DB_API_HEARTBEAT_INTERVAL, + "HeartbeatIntervalDbApi", + "DB", + "Time between API-DB heartbeats. API connection closed after 3 missed HBs", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 1500, + 100, + 0x7FFFFFFF }, + + { + CFG_DB_LCP_INTERVAL, + "TimeBetweenLocalCheckpoints", + "DB", + "Time between taking snapshots of the database (expressed in 2log of bytes)", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 20, + 0, + 31 }, + + { + CFG_DB_GCP_INTERVAL, + "TimeBetweenGlobalCheckpoints", + "DB", + "Time between doing group commit of transactions to disk", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 2000, + 10, + 32000 }, + + { + CFG_DB_NO_REDOLOG_FILES, + "NoOfFragmentLogFiles", + "DB", + "No of 16 Mbyte Redo log files in each of 4 file sets belonging to DB node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 8, + 1, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "MaxNoOfOpenFiles", + "DB", + "Max number of files open per DB node.(One thread is created per file)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 40, + 20, + 256 }, + - {"NoOfConcurrentCheckpointsAfterRestart", - "NoOfConcurrentCheckpointsAfterRestart", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1, - 1, - 4}, + { + CFG_DB_TRANSACTION_CHECK_INTERVAL, + "TimeBetweenInactiveTransactionAbortCheck", + "DB", + "Time between inactive transaction checks", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 1000, + 1000, + 0x7FFFFFFF }, - {"NoOfDiskPagesToDiskDuringRestartTUP", - "NoOfDiskPagesToDiskDuringRestartTUP", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 50, - 1, - 0x7FFFFFFF}, - - {"NoOfDiskPagesToDiskAfterRestartTUP", - "NoOfDiskPagesToDiskAfterRestartTUP", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 10, - 1, - 0x7FFFFFFF}, - - {"NoOfDiskPagesToDiskDuringRestartACC", - "NoOfDiskPagesToDiskDuringRestartACC", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 25, - 1, - 0x7FFFFFFF}, - - {"NoOfDiskPagesToDiskAfterRestartACC", - "NoOfDiskPagesToDiskAfterRestartACC", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 5, - 1, - 0x7FFFFFFF}, + { + CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, + "TransactionInactiveTimeout", + "DB", + "Time application can wait before executing another transaction part (ms).\n" + "This is the time the transaction coordinator waits for the application\n" + "to execute or send another part (query, statement) of the transaction.\n" + "If the application takes too long time, the transaction gets aborted.\n" + "Timeout set to 0 means that we don't timeout at all on application wait.", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 3000, + 0, + 0x7FFFFFFF }, + + { + CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, + "TransactionDeadlockDetectionTimeout", + "DB", + "Time transaction can be executing in a DB node (ms).\n" + "This is the time the transaction coordinator waits for each database node\n" + "of the transaction to execute a request. If the database node takes too\n" + "long time, the transaction gets aborted.", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 3000, + 50, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "TransactionInactiveTimeBeforeAbort", + "DB", + "TransactionInactiveTimeout", + ConfigInfo::DEPRICATED, + true, + ConfigInfo::INT, + 3000, + 20, + 0x7FFFFFFF }, - {"NoOfDiskClustersPerDiskFile", - "NoOfDiskClustersPerDiskFile", - "DB", - "?", - ConfigInfo::NOTIMPLEMENTED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, + { + KEY_INTERNAL, + "NoOfDiskPagesToDiskDuringRestartTUP", + "DB", + "?", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 50, + 1, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "NoOfDiskPagesToDiskAfterRestartTUP", + "DB", + "?", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 10, + 1, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "NoOfDiskPagesToDiskDuringRestartACC", + "DB", + "?", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 25, + 1, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "NoOfDiskPagesToDiskAfterRestartACC", + "DB", + "?", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 5, + 1, + 0x7FFFFFFF }, - {"NoOfDiskFiles", - "NoOfDiskFiles", - "DB", - "?", - ConfigInfo::NOTIMPLEMENTED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, - - {"ArbitrationTimeout", - "ArbitrationTimeout", - "DB", - "Max time (milliseconds) database partion waits for arbitration signal", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1000, - 10, - 0x7FFFFFFF}, - - {"FileSystemPath", - "FileSystemPath", - "DB", - "Path to directory where the DB node stores its data (directory must exist)", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"LogLevelStartup", - "LogLevelStartup", - "DB", - "Node startup info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1, - 0, - 15}, + { + CFG_DB_ARBIT_TIMEOUT, + "ArbitrationTimeout", + "DB", + "Max time (milliseconds) database partion waits for arbitration signal", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1000, + 10, + 0x7FFFFFFF }, + + { + CFG_DB_FILESYSTEM_PATH, + "FileSystemPath", + "DB", + "Path to directory where the DB node stores its data (directory must exist)", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_LOGLEVEL_STARTUP, + "LogLevelStartup", + "DB", + "Node startup info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1, + 0, + 15 }, - {"LogLevelShutdown", - "LogLevelShutdown", - "DB", - "Node shutdown info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelStatistic", - "LogLevelStatistic", - "DB", - "Transaction, operation, transporter info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelCheckpoint", - "LogLevelCheckpoint", - "DB", - "Local and Global checkpoint info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelNodeRestart", - "LogLevelNodeRestart", - "DB", - "Node restart, node failure info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelConnection", - "LogLevelConnection", - "DB", - "Node connect/disconnect info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelError", - "LogLevelError", - "DB", - "Transporter, heartbeat errors printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelInfo", - "LogLevelInfo", - "DB", - "Heartbeat and log info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, + { + CFG_LOGLEVEL_SHUTDOWN, + "LogLevelShutdown", + "DB", + "Node shutdown info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_STATISTICS, + "LogLevelStatistic", + "DB", + "Transaction, operation, transporter info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_CHECKPOINT, + "LogLevelCheckpoint", + "DB", + "Local and Global checkpoint info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_NODERESTART, + "LogLevelNodeRestart", + "DB", + "Node restart, node failure info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_CONNECTION, + "LogLevelConnection", + "DB", + "Node connect/disconnect info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_ERROR, + "LogLevelError", + "DB", + "Transporter, heartbeat errors printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_INFO, + "LogLevelInfo", + "DB", + "Heartbeat and log info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, /** * Backup */ - { "ParallelBackups", + { + CFG_DB_PARALLEL_BACKUPS, "ParallelBackups", "DB", "Maximum number of parallel backups", @@ -877,7 +1023,8 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 1, 1 }, - { "BackupMemory", + { + CFG_DB_BACKUP_MEM, "BackupMemory", "DB", "Total memory allocated for backups per node (in bytes)", @@ -888,7 +1035,8 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0x7FFFFFFF }, - { "BackupDataBufferSize", + { + CFG_DB_BACKUP_DATA_BUFFER_MEM, "BackupDataBufferSize", "DB", "Default size of databuffer for a backup (in bytes)", @@ -899,7 +1047,8 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0x7FFFFFFF }, - { "BackupLogBufferSize", + { + CFG_DB_BACKUP_LOG_BUFFER_MEM, "BackupLogBufferSize", "DB", "Default size of logbuffer for a backup (in bytes)", @@ -910,7 +1059,8 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0x7FFFFFFF }, - { "BackupWriteSize", + { + CFG_DB_BACKUP_WRITE_SIZE, "BackupWriteSize", "DB", "Default size of filesystem writes made by backup (in bytes)", @@ -921,967 +1071,1098 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0x7FFFFFFF }, - /**************************************************************************** + /*************************************************************************** * REP - ****************************************************************************/ - - {"Id", - "Id", - "REP", - "Number identifying replication node (REP)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - (MAX_NODES - 1)}, - - {"Type", - "Type", - "REP", - "Type of node (Should have value REP)", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"ExecuteOnComputer", - "ExecuteOnComputer", - "REP", - "String referencing an earlier defined COMPUTER", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, + ***************************************************************************/ + { + CFG_SECTION_NODE, + "REP", + "REP", + "Node section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + NODE_TYPE_REP, + 0, 0 + }, - /**************************************************************************** - * EXTERNAL REP - ****************************************************************************/ - - {"Id", - "Id", - "EXTERNAL REP", - "Number identifying external (i.e. in another NDB Cluster) replication node (REP)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - (MAX_NODES - 1)}, - - {"Type", - "Type", - "EXTERNAL REP", - "Type of node (Should have value REP)", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"System", - "System", - "EXTERNAL REP", - "System name of system hosting node", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"HeartbeatIntervalRepRep", - "HeartbeatIntervalRepRep", - "EXTERNAL REP", - "Time between REP-REP heartbeats. Connection closed after 3 missed HBs", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 3000, - 100, - 0x7FFFFFFF}, + { + CFG_NODE_HOST, + "HostName", + "REP", + "Name of computer for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, - /**************************************************************************** + { + CFG_NODE_SYSTEM, + "System", + "REP", + "Name of system for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ID, + "Id", + "REP", + "Number identifying replication node (REP)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 1, + (MAX_NODES - 1) }, + + { + KEY_INTERNAL, + "ExecuteOnComputer", + "REP", + "String referencing an earlier defined COMPUTER", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_REP_HEARTBEAT_INTERVAL, + "HeartbeatIntervalRepRep", + "REP", + "Time between REP-REP heartbeats. Connection closed after 3 missed HBs", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 3000, + 100, + 0x7FFFFFFF }, + + /*************************************************************************** * API - ****************************************************************************/ - - {"Id", - "Id", - "API", - "Number identifying application node (API)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - (MAX_NODES - 1)}, - - {"Type", - "Type", - "API", - "Type of node (Should have value API)", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"ExecuteOnComputer", - "ExecuteOnComputer", - "API", - "String referencing an earlier defined COMPUTER", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"MaxNoOfSavedMessages", - "MaxNoOfSavedMessages", - "API", - "Max number of error messages in error log and max number of trace files", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 25, - 0, - 0x7FFFFFFF}, - - {"SleepWhenIdle", - "SleepWhenIdle", - "API", - "?", - ConfigInfo::DEPRICATED, - true, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - {"ArbitrationRank", - "ArbitrationRank", - "API", - "If 0, then API is not arbitrator. Kernel selects arbitrators in order 1, 2", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 2, - 0, - 2}, - - {"ArbitrationDelay", - "ArbitrationDelay", - "API", - "When asked to arbitrate, arbitrator waits this long before voting (msec)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, + ***************************************************************************/ + { + CFG_SECTION_NODE, + "API", + "API", + "Node section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + NODE_TYPE_API, + 0, 0 + }, + + { + CFG_NODE_HOST, + "HostName", + "API", + "Name of computer for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_SYSTEM, + "System", + "API", + "Name of system for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ID, + "Id", + "API", + "Number identifying application node (API)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 1, + (MAX_NODES - 1) }, + + { + KEY_INTERNAL, + "ExecuteOnComputer", + "API", + "String referencing an earlier defined COMPUTER", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ARBIT_RANK, + "ArbitrationRank", + "API", + "If 0, then API is not arbitrator. Kernel selects arbitrators in order 1, 2", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 2, + 0, + 2 }, + + { + CFG_NODE_ARBIT_DELAY, + "ArbitrationDelay", + "API", + "When asked to arbitrate, arbitrator waits this long before voting (msec)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 0x7FFFFFFF }, /**************************************************************************** * MGM - ****************************************************************************/ - - {"Id", - "Id", - "MGM", - "Number identifying the management server node (MGM)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - (MAX_NODES - 1)}, + ***************************************************************************/ + { + CFG_SECTION_NODE, + "MGM", + "MGM", + "Node section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + NODE_TYPE_MGM, + 0, 0 + }, + + { + CFG_NODE_HOST, + "HostName", + "MGM", + "Name of computer for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_SYSTEM, + "System", + "MGM", + "Name of system for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ID, + "Id", + "MGM", + "Number identifying the management server node (MGM)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 1, + (MAX_NODES - 1) }, - {"Type", - "Type", - "MGM", - "Type of node (Should have value MGM)", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"ExecuteOnComputer", - "ExecuteOnComputer", - "MGM", - "String referencing an earlier defined COMPUTER", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, - - // SHOULD THIS REALLY BE DEFINABLE FOR MGM ??? - {"MaxNoOfSavedMessages", - "MaxNoOfSavedMessages", - "MGM", - "Max number of error messages in error log and max number of trace files", - ConfigInfo::DEPRICATED, - true, - ConfigInfo::INT, - 25, - 0, - 0x7FFFFFFF}, + { + CFG_LOG_DESTINATION, + "LogDestination", + "MGM", + "String describing where logmessages are sent", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + 0, + 0, + 0x7FFFFFFF }, - {"MaxNoOfSavedEvents", - "MaxNoOfSavedEvents", - "MGM", - "", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 100, - 0, - 0x7FFFFFFF}, - - {"PortNumber", - "PortNumber", - "MGM", - "Port number to give commands to/fetch configurations from management server", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 2200, - 0, - 0x7FFFFFFF}, - - {"PortNumberStats", - "PortNumberStats", - "MGM", - "Port number used to get statistical information from a management server", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 2199, - 0, - 0x7FFFFFFF}, - - {"ArbitrationRank", - "ArbitrationRank", - "MGM", - "If 0, then MGM is not arbitrator. Kernel selects arbitrators in order 1, 2", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 2, - 0, - 2}, - - {"ArbitrationDelay", - "ArbitrationDelay", - "MGM", - "", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, - - /***************************************************************************** - * SYSTEM - ****************************************************************************/ - - {"Name", - "Name", - "SYSTEM", - "Name of system (NDB Cluster)", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0}, - - {"ReplicationRole", - "ReplicationRole", - "SYSTEM", - "Role in Global Replication (None, Primary, or Standby)", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0}, - - {"LogDestination", - "LogDestination", - "MGM", - "String describing where logmessages are sent", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - 0, - 0, - 0x7FFFFFFF}, - - {"PrimaryMGMNode", - "PrimaryMGMNode", - "SYSTEM", - "Node id of Primary MGM node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, - - {"ConfigGenerationNumber", - "ConfigGenerationNumber", - "SYSTEM", - "Configuration generation number", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, - - {"Name", - "Name", - "EXTERNAL SYSTEM", - "Name of external system (another NDB Cluster)", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0}, - - /***************************************************************************** + { + KEY_INTERNAL, + "ExecuteOnComputer", + "MGM", + "String referencing an earlier defined COMPUTER", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "MaxNoOfSavedEvents", + "MGM", + "", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 100, + 0, + 0x7FFFFFFF }, + + { + CFG_MGM_PORT, + "PortNumber", + "MGM", + "Port number to give commands to/fetch configurations from management server", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 2200, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "PortNumberStats", + "MGM", + "Port number used to get statistical information from a management server", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 2199, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ARBIT_RANK, + "ArbitrationRank", + "MGM", + "If 0, then MGM is not arbitrator. Kernel selects arbitrators in order 1, 2", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 2, + 0, + 2 }, + + { + CFG_NODE_ARBIT_DELAY, + "ArbitrationDelay", + "MGM", + "", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 0x7FFFFFFF }, + + /**************************************************************************** * TCP - ****************************************************************************/ - - {"Type", - "Type", - "TCP", - "", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0x7FFFFFFF}, - - {"HostName1", - "HostName1", - "TCP", - "Name of computer on one side of the connection", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"HostName2", - "HostName2", - "TCP", - "Name of computer on one side of the connection", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"NodeId1", - "NodeId1", - "TCP", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ProcessId1", - "NodeId1", - "TCP", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"NodeId2", - "NodeId2", - "TCP", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ProcessId2", - "NodeId2", - "TCP", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"IpAddress1", - "HostName1", - "TCP", - "IP address of first node in connection.", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"IpAddress2", - "HostName2", - "TCP", - "IP address of second node in connection.", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0}, - - {"SendSignalId", - "SendSignalId", - "TCP", - "Sends id in each signal. Used in trace files.", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - {"Compression", - "Compression", - "TCP", - "If compression is enabled, then all signals between nodes are compressed", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"Checksum", - "Checksum", - "TCP", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"PortNumber", - "PortNumber", - "TCP", - "Port used for this transporter", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"SendBufferSize", - "SendBufferSize", - "TCP", - "Size of buffer for signals sent from this node (in no of signals)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 16, - 1, - 0x7FFFFFFF}, + ***************************************************************************/ + { + CFG_SECTION_CONNECTION, + "TCP", + "TCP", + "Connection section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + CONNECTION_TYPE_TCP, + 0, 0 + }, + + { + CFG_TCP_HOSTNAME_1, + "HostName1", + "TCP", + "Name/IP of computer on one side of the connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_TCP_HOSTNAME_2, + "HostName2", + "TCP", + "Name/IP of computer on one side of the connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_1, + "NodeId1", + "TCP", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId1", + "TCP", + "NodeId1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2, + "NodeId2", + "TCP", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId2", + "TCP", + "NodeId2", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "IpAddress1", + "TCP", + "HostName1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "IpAddress2", + "TCP", + "HostName2", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0 }, + + { + CFG_CONNECTION_SEND_SIGNAL_ID, + "SendSignalId", + "TCP", + "Sends id in each signal. Used in trace files.", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, + + + { + CFG_CONNECTION_CHECKSUM, + "Checksum", + "TCP", + "If checksum is enabled, all signals between nodes are checked for errors", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_TCP_SERVER_PORT, + "PortNumber", + "TCP", + "Port used for this transporter", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_TCP_SEND_BUFFER_SIZE, + "SendBufferMemory", + "TCP", + "Bytes of buffer for signals sent from this node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 16 * 16384, + 1 * 16384, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "SendBufferSize", + "TCP", + "SendBufferMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + 16, + 1, + 0x7FFFFFFF }, - {"MaxReceiveSize", - "MaxReceiveSize", - "TCP", - "Size of buffer for signals received by this node (in no of signals)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 4, - 1, - 0x7FFFFFFF}, - - {"Proxy", - "Proxy", - "TCP", - "", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0}, - - /***************************************************************************** - * SHM - ****************************************************************************/ - - {"Type", - "Type", - "SHM", - "", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0x7FFFFFFF}, + { + CFG_TCP_RECEIVE_BUFFER_SIZE, + "ReceiveBufferMemory", + "TCP", + "Bytes of buffer for signals received by this node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 4 * 16384, + 1 * 16384, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "MaxReceiveSize", + "TCP", + "ReceiveBufferMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + 4, + 1, + 0x7FFFFFFF }, + + { + CFG_TCP_PROXY, + "Proxy", + "TCP", + "", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0 }, + + { + KEY_INTERNAL, + "Compression", + "TCP", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + + { + CFG_CONNECTION_NODE_1_SYSTEM, + "NodeId1_System", + "TCP", + "System for node 1 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2_SYSTEM, + "NodeId2_System", + "TCP", + "System for node 2 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, - {"NodeId1", - "NodeId1", - "SHM", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, + + /**************************************************************************** + * SHM + ***************************************************************************/ + { + CFG_SECTION_CONNECTION, + "SHM", + "SHM", + "Connection section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + CONNECTION_TYPE_SHM, + 0, 0 + }, + + { + CFG_CONNECTION_NODE_1, + "NodeId1", + "SHM", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, - {"ProcessId1", - "NodeId1", - "SHM", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, + { + KEY_INTERNAL, + "ProcessId1", + "SHM", + "NodeId1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, - {"NodeId2", - "NodeId2", - "SHM", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, + { + CFG_CONNECTION_NODE_2, + "NodeId2", + "SHM", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, - {"ProcessId2", - "NodeId2", - "SHM", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, + { + KEY_INTERNAL, + "ProcessId2", + "SHM", + "NodeId1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, - {"SendSignalId", - "SendSignalId", - "SHM", - "Sends id in each signal. Used in trace files.", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, + { + CFG_CONNECTION_SEND_SIGNAL_ID, + "SendSignalId", + "SHM", + "Sends id in each signal. Used in trace files.", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, - {"Compression", - "Compression", - "SHM", - "If compression is enabled, then all signals between nodes are compressed", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - {"Checksum", - "Checksum", - "SHM", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, + { + CFG_CONNECTION_CHECKSUM, + "Checksum", + "SHM", + "If checksum is enabled, all signals between nodes are checked for errors", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, - {"ShmKey", - "ShmKey", - "SHM", - "A shared memory key", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF }, + { + CFG_SHM_KEY, + "ShmKey", + "SHM", + "A shared memory key", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, - {"ShmSize", - "ShmSize", - "SHM", - "Size of shared memory segment", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1048576, - 4096, - 0x7FFFFFFF}, + { + CFG_SHM_BUFFER_MEM, + "ShmSize", + "SHM", + "Size of shared memory segment", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1048576, + 4096, + 0x7FFFFFFF }, - /***************************************************************************** + { + KEY_INTERNAL, + "Compression", + "SHM", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_1_SYSTEM, + "NodeId1_System", + "SHM", + "System for node 1 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2_SYSTEM, + "NodeId2_System", + "SHM", + "System for node 2 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + /**************************************************************************** * SCI - ****************************************************************************/ - - {"NodeId1", - "NodeId1", - "SCI", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ProcessId1", - "NodeId1", - "SCI", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"NodeId2", - "NodeId2", - "SCI", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ProcessId2", - "NodeId2", - "SCI", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"SciId0", - "SciId0", - "SCI", - "Local SCI-node id for adapter 0 (a computer can have two adapters)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"SciId1", - "SciId1", - "SCI", - "Local SCI-node id for adapter 1 (a computer can have two adapters)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"SendSignalId", - "SendSignalId", - "SCI", - "Sends id in each signal. Used in trace files.", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - {"Compression", - "Compression", - "SCI", - "If compression is enabled, then all signals between nodes are compressed", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"Checksum", - "Checksum", - "SCI", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"SendLimit", - "SendLimit", - "SCI", - "Transporter send buffer contents are sent when this no of bytes is buffered", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 2048, - 512, - 0x7FFFFFFF}, - - {"SharedBufferSize", - "SharedBufferSize", - "SCI", - "Size of shared memory segment", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1048576, - 262144, - 0x7FFFFFFF}, - - {"Node1_NoOfAdapters", - "Node1_NoOfAdapters", - "SCI", - "", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"Node2_NoOfAdapters", - "Node2_NoOfAdapters", - "SCI", - "", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"Node1_Adapter", - "Node1_Adapter", - "SCI", - "", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"Node2_Adapter", - "Node2_Adapter", - "SCI", - "", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - /***************************************************************************** + ***************************************************************************/ + { + CFG_SECTION_CONNECTION, + "SCI", + "SCI", + "Connection section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + CONNECTION_TYPE_SCI, + 0, 0 + }, + + { + CFG_CONNECTION_NODE_1, + "NodeId1", + "SCI", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId1", + "SCI", + "NodeId1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2, + "NodeId2", + "SCI", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId2", + "SCI", + "NodeId2", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_SCI_ID_0, + "SciId0", + "SCI", + "Local SCI-node id for adapter 0 (a computer can have two adapters)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_SCI_ID_1, + "SciId1", + "SCI", + "Local SCI-node id for adapter 1 (a computer can have two adapters)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_SEND_SIGNAL_ID, + "SendSignalId", + "SCI", + "Sends id in each signal. Used in trace files.", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_CHECKSUM, + "Checksum", + "SCI", + "If checksum is enabled, all signals between nodes are checked for errors", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_SCI_SEND_LIMIT, + "SendLimit", + "SCI", + "Transporter send buffer contents are sent when this no of bytes is buffered", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 2048, + 512, + 0x7FFFFFFF }, + + { + CFG_SCI_BUFFER_MEM, + "SharedBufferSize", + "SCI", + "Size of shared memory segment", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1048576, + 262144, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Node1_NoOfAdapters", + "SCI", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Node2_NoOfAdapters", + "SCI", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Node1_Adapter", + "SCI", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Node2_Adapter", + "SCI", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Compression", + "SCI", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_1_SYSTEM, + "NodeId1_System", + "SCI", + "System for node 1 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2_SYSTEM, + "NodeId2_System", + "SCI", + "System for node 2 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + /**************************************************************************** * OSE - ****************************************************************************/ - - {"Type", - "Type", - "OSE", - "", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0x7FFFFFFF}, - - {"HostName1", - "HostName1", - "OSE", - "Name of computer on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"HostName2", - "HostName2", - "OSE", - "Name of computer on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"NodeId1", - "NodeId1", - "OSE", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ProcessId1", - "NodeId1", - "OSE", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"NodeId2", - "NodeId2", - "OSE", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"ProcessId2", - "NodeId2", - "OSE", - "Depricated", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"SendSignalId", - "SendSignalId", - "OSE", - "Sends id in each signal. Used in trace files.", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - {"Compression", - "Compression", - "OSE", - "If compression is enabled, then all signals between nodes are compressed", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"Checksum", - "Checksum", - "OSE", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - // Should not be part of OSE ? - {"SharedBufferSize", - "SharedBufferSize", - "OSE", - "?", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 2000, - 0x7FFFFFFF}, - - {"PrioASignalSize", - "PrioASignalSize", - "OSE", - "Size of priority A signals (in bytes)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1000, - 0, - 0x7FFFFFFF}, - - {"PrioBSignalSize", - "PrioBSignalSize", - "OSE", - "Size of priority B signals (in bytes)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1000, - 0, - 0x7FFFFFFF}, - - {"ReceiveArraySize", - "ReceiveArraySize", - "OSE", - "Number of OSE signals checked for correct ordering (in no of OSE signals)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 10, - 0, - 0x7FFFFFFF} + ***************************************************************************/ + { + CFG_SECTION_CONNECTION, + "OSE", + "OSE", + "Connection section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + CONNECTION_TYPE_OSE, + 0, 0 + }, + + { + CFG_OSE_HOSTNAME_1, + "HostName1", + "OSE", + "Name of computer on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_OSE_HOSTNAME_2, + "HostName2", + "OSE", + "Name of computer on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_1, + "NodeId1", + "OSE", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId1", + "OSE", + "NodeId1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2, + "NodeId2", + "OSE", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId2", + "OSE", + "NodeId2", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_SEND_SIGNAL_ID, + "SendSignalId", + "OSE", + "Sends id in each signal. Used in trace files.", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_CHECKSUM, + "Checksum", + "OSE", + "If checksum is enabled, all signals between nodes are checked for errors", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_OSE_PRIO_A_SIZE, + "PrioASignalSize", + "OSE", + "Size of priority A signals (in bytes)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1000, + 0, + 0x7FFFFFFF }, + + { + CFG_OSE_PRIO_B_SIZE, + "PrioBSignalSize", + "OSE", + "Size of priority B signals (in bytes)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1000, + 0, + 0x7FFFFFFF }, + + { + CFG_OSE_RECEIVE_ARRAY_SIZE, + "ReceiveArraySize", + "OSE", + "Number of OSE signals checked for correct ordering (in no of OSE signals)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 10, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Compression", + "OSE", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_1_SYSTEM, + "NodeId1_System", + "OSE", + "System for node 1 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2_SYSTEM, + "NodeId2_System", + "OSE", + "System for node 2 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, }; const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo); @@ -1908,21 +2189,21 @@ ConfigInfo::ConfigInfo() { newsection.setCaseInsensitiveNames(true); m_info.put(param._section, &newsection); } - + // Get copy of section m_info.getCopy(param._section, §ion); // Create pinfo (parameter info) entry Properties pinfo; + pinfo.put("Id", param._paramId); pinfo.put("Fname", param._fname); - pinfo.put("Pname", param._pname); pinfo.put("Description", param._description); pinfo.put("Updateable", param._updateable); pinfo.put("Type", param._type); pinfo.put("Status", param._status); - pinfo.put("Default", param._default); - pinfo.put("Min", param._min); - pinfo.put("Max", param._max); + pinfo.put64("Default", param._default); + pinfo.put64("Min", param._min); + pinfo.put64("Max", param._max); // Check that pinfo is really new if (section->get(param._fname, &oldpinfo)) { @@ -1937,8 +2218,8 @@ ConfigInfo::ConfigInfo() { // Replace section with modified section m_info.put(param._section, section, true); - - { + + if(param._type != ConfigInfo::SECTION){ Properties * p; if(!m_systemDefaults.getCopy(param._section, &p)){ p = new Properties(); @@ -1947,26 +2228,28 @@ ConfigInfo::ConfigInfo() { if(param._type != STRING && param._default != UNDEFINED && param._default != MANDATORY){ - require(p->put(param._pname, param._default)); + require(p->put(param._fname, param._default)); } require(m_systemDefaults.put(param._section, p, true)); delete p; } } - + for (int i=0; i<m_NoOfParams; i++) { if(m_ParamInfo[i]._section == NULL){ - ndbout << "Check that each pname has an fname failed." << endl; - ndbout << "Parameter \"" << m_ParamInfo[i]._pname - << "\" does not exist in section \"" - << m_ParamInfo[i]._section << "\"." << endl; + ndbout << "Check that each entry has a section failed." << endl; + ndbout << "Parameter \"" << m_ParamInfo[i]._fname << endl; ndbout << "Edit file " << __FILE__ << "." << endl; exit(-1); } + + if(m_ParamInfo[i]._type == ConfigInfo::SECTION) + continue; + const Properties * p = getInfo(m_ParamInfo[i]._section); - if (!p || !p->contains(m_ParamInfo[i]._pname)) { + if (!p || !p->contains(m_ParamInfo[i]._fname)) { ndbout << "Check that each pname has an fname failed." << endl; - ndbout << "Parameter \"" << m_ParamInfo[i]._pname + ndbout << "Parameter \"" << m_ParamInfo[i]._fname << "\" does not exist in section \"" << m_ParamInfo[i]._section << "\"." << endl; ndbout << "Edit file " << __FILE__ << "." << endl; @@ -2002,16 +2285,27 @@ ConfigInfo::getDefaults(const char * section) const { } static -Uint32 +Uint64 getInfoInt(const Properties * section, const char* fname, const char * type){ - Uint32 val; + Uint32 val32; const Properties * p; - if (section->get(fname, &p) && p->get(type, &val)) { - return val; + if (section->get(fname, &p) && p->get(type, &val32)) { + return val32; + } + + Uint64 val64; + if(p && p->get(type, &val64)){ + return val64; + } + + section->print(); + if(section->get(fname, &p)){ + p->print(); } + warning(type, fname); - return val; + return 0; } static @@ -2027,27 +2321,22 @@ getInfoString(const Properties * section, return val; } -Uint32 +Uint64 ConfigInfo::getMax(const Properties * section, const char* fname) const { return getInfoInt(section, fname, "Max"); } -Uint32 +Uint64 ConfigInfo::getMin(const Properties * section, const char* fname) const { return getInfoInt(section, fname, "Min"); } -Uint32 +Uint64 ConfigInfo::getDefault(const Properties * section, const char* fname) const { return getInfoInt(section, fname, "Default"); } const char* -ConfigInfo::getPName(const Properties * section, const char* fname) const { - return getInfoString(section, fname, "Pname"); -} - -const char* ConfigInfo::getDescription(const Properties * section, const char* fname) const { return getInfoString(section, fname, "Description"); @@ -2063,8 +2352,8 @@ ConfigInfo::isSection(const char * section) const { bool ConfigInfo::verify(const Properties * section, const char* fname, - Uint32 value) const { - Uint32 min, max; min = max + 1; + Uint64 value) const { + Uint64 min, max; min = max + 1; min = getInfoInt(section, fname, "Min"); max = getInfoInt(section, fname, "Max"); @@ -2104,7 +2393,6 @@ void ConfigInfo::print(const char* section) const { Properties::Iterator it(sec); for (const char* n = it.first(); n != NULL; n = it.next()) { // Skip entries with different F- and P-names - if (strcmp(n, getPName(sec, n))) continue; if (getStatus(sec, n) == ConfigInfo::INTERNAL) continue; if (getStatus(sec, n) == ConfigInfo::DEPRICATED) continue; if (getStatus(sec, n) == ConfigInfo::NOTIMPLEMENTED) continue; @@ -2114,7 +2402,7 @@ void ConfigInfo::print(const char* section) const { void ConfigInfo::print(const Properties * section, const char* parameter) const { - ndbout << getPName(section, parameter); + ndbout << parameter; // ndbout << getDescription(section, parameter) << endl; switch (getType(section, parameter)) { case ConfigInfo::BOOL: @@ -2133,6 +2421,7 @@ void ConfigInfo::print(const Properties * section, break; case ConfigInfo::INT: + case ConfigInfo::INT64: ndbout << " (Non-negative Integer)" << endl; ndbout << getDescription(section, parameter) << endl; if (getDefault(section, parameter) == MANDATORY) { @@ -2189,6 +2478,37 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){ } bool +fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data){ + + const char * compId; + if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId)){ + ctx.reportError("Parameter \"ExecuteOnComputer\" missing from section " + "[%s] starting at line: %d", + ctx.fname, ctx.m_sectionLineno); + return false; + } + + const Properties * computer; + char tmp[255]; + snprintf(tmp, sizeof(tmp), "Computer_%s", compId); + if(!ctx.m_config->get(tmp, &computer)){ + ctx.reportError("Computer \"%s\" not declared" + "- [%s] starting at line: %d", + compId, ctx.fname, ctx.m_sectionLineno); + } + + const char * hostname; + if(!computer->get("HostName", &hostname)){ + ctx.reportError("HostName missing in [COMPUTER] Id: %s" + "- [%s] starting at line: %d", + compId, ctx.fname, ctx.m_sectionLineno); + } + + require(ctx.m_currentSection->put("HostName", hostname)); + return true; +} + +bool transformExtNode(InitConfigFileParser::Context & ctx, const char * data){ Uint32 id; @@ -2301,6 +2621,7 @@ applyDefaultValues(InitConfigFileParser::Context & ctx, Properties::Iterator it(defaults); for(const char * name = it.first(); name != NULL; name = it.next()){ + ConfigInfo::Status st = ctx.m_info->getStatus(ctx.m_currentInfo, name); if(!ctx.m_currentSection->contains(name)){ switch (ctx.m_info->getType(ctx.m_currentInfo, name)){ case ConfigInfo::INT: @@ -2310,6 +2631,12 @@ applyDefaultValues(InitConfigFileParser::Context & ctx, ctx.m_currentSection->put(name, val); break; } + case ConfigInfo::INT64:{ + Uint64 val = 0; + ::require(defaults->get(name, &val)); + ctx.m_currentSection->put64(name, val); + break; + } case ConfigInfo::STRING:{ const char * val; ::require(defaults->get(name, &val)); @@ -2325,9 +2652,13 @@ applyDefaultValues(InitConfigFileParser::Context & ctx, bool applyDefaultValues(InitConfigFileParser::Context & ctx, const char * data){ - applyDefaultValues(ctx, ctx.m_userDefaults); - applyDefaultValues(ctx, ctx.m_systemDefaults); - + if(strcmp(data, "user") == 0) + applyDefaultValues(ctx, ctx.m_userDefaults); + else if (strcmp(data, "system") == 0) + applyDefaultValues(ctx, ctx.m_systemDefaults); + else + return false; + return true; } @@ -2343,11 +2674,9 @@ checkMandatory(InitConfigFileParser::Context & ctx, const char * data){ ::require(ctx.m_currentInfo->get(name, &info)); Uint32 val; if(info->get("Default", &val) && val == MANDATORY){ - const char * pname; const char * fname; - ::require(info->get("Pname", &pname)); ::require(info->get("Fname", &fname)); - if(!ctx.m_currentSection->contains(pname)){ + if(!ctx.m_currentSection->contains(fname)){ ctx.reportError("Mandatory parameter %s missing from section " "[%s] starting at line: %d", fname, ctx.fname, ctx.m_sectionLineno); @@ -2493,20 +2822,12 @@ fixHostname(InitConfigFileParser::Context & ctx, const char * data){ if(!ctx.m_currentSection->contains(data)){ Uint32 id = 0; require(ctx.m_currentSection->get(buf, &id)); - + const Properties * node; require(ctx.m_config->get("Node", id, &node)); - const char * compId; - require(node->get("ExecuteOnComputer", &compId)); - - const Properties * computer; - char tmp[255]; - snprintf(tmp, sizeof(tmp), "Computer_%s", compId); - require(ctx.m_config->get(tmp, &computer)); - const char * hostname; - require(computer->get("HostName", &hostname)); + require(node->get("HostName", &hostname)); require(ctx.m_currentSection->put(data, hostname)); } return true; @@ -2627,3 +2948,180 @@ checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){ } return true; } + +static +bool +transform(InitConfigFileParser::Context & ctx, + Properties & dst, + const char * oldName, + const char * newName, + double add, double mul){ + + if(ctx.m_currentSection->contains(newName)){ + ctx.reportError("Both %s and %s specified" + " - [%s] starting at line: %d", + oldName, newName, + ctx.fname, ctx.m_sectionLineno); + return false; + } + + PropertiesType oldType; + require(ctx.m_currentSection->getTypeOf(oldName, &oldType)); + ConfigInfo::Type newType = ctx.m_info->getType(ctx.m_currentInfo, newName); + if(!((oldType == PropertiesType_Uint32 || oldType == PropertiesType_Uint64) + && (newType == ConfigInfo::INT || newType == ConfigInfo::INT64))){ + ctx.reportError("Unable to handle type conversion w.r.t deprication %s %s" + "- [%s] starting at line: %d", + oldName, newName, + ctx.fname, ctx.m_sectionLineno); + return false; + } + Uint64 oldVal; + require(ctx.m_currentSection->get(oldName, &oldVal)); + + Uint64 newVal = (Uint64)(oldVal * mul + add); + if(!ctx.m_info->verify(ctx.m_currentInfo, newName, newVal)){ + ctx.reportError("Unable to handle deprication, new value not within bounds" + "%s %s - [%s] starting at line: %d", + oldName, newName, + ctx.fname, ctx.m_sectionLineno); + return false; + } + + if(newType == ConfigInfo::INT){ + require(dst.put(newName, (Uint32)newVal)); + } else { + require(dst.put64(newName, newVal)); + } + return true; +} + +bool +fixDepricated(InitConfigFileParser::Context & ctx, const char * data){ + /** + * Transform old values to new values + * Transform new values to old values (backward compatible) + */ + Properties tmp; + Properties::Iterator it(ctx.m_currentSection); + for (const char* name = it.first(); name != NULL; name = it.next()) { + const DepricationTransform * p = &f_deprication[0]; + while(p->m_section != 0){ + if(strcmp(p->m_section, ctx.fname) == 0){ + double mul = p->m_mul; + double add = p->m_add; + if(strcmp(name, p->m_oldName) == 0){ + if(!transform(ctx, tmp, name, p->m_newName, add, mul)){ + return false; + } + } else if(strcmp(name, p->m_newName) == 0) { + if(!transform(ctx, tmp, name, p->m_oldName, -add/mul,1.0/mul)){ + return false; + } + } + } + p++; + } + } + + Properties::Iterator it2(&tmp); + for (const char* name = it2.first(); name != NULL; name = it2.next()) { + PropertiesType type; + require(tmp.getTypeOf(name, &type)); + switch(type){ + case PropertiesType_Uint32:{ + Uint32 val; + require(tmp.get(name, &val)); + ::require(ctx.m_currentSection->put(name, val)); + break; + } + case PropertiesType_char:{ + const char * val; + require(tmp.get(name, &val)); + ::require(ctx.m_currentSection->put(name, val)); + break; + } + case PropertiesType_Uint64:{ + Uint64 val; + require(tmp.get(name, &val)); + ::require(ctx.m_currentSection->put64(name, val)); + break; + } + case PropertiesType_Properties: + default: + abort(); + } + } + return true; +} + +bool +saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ + const Properties * sec; + if(!ctx.m_currentInfo->get(ctx.fname, &sec)){ + abort(); + return false; + } + + do { + const char *secName; + Uint32 id, status, typeVal; + require(sec->get("Fname", &secName)); + require(sec->get("Id", &id)); + require(sec->get("Status", &status)); + require(sec->get("Default", &typeVal)); + + if(id == KEY_INTERNAL || status == ConfigInfo::INTERNAL){ + ndbout_c("skipping section %s", ctx.fname); + break; + } + + Uint32 no = 0; + ctx.m_userProperties.get("$Section", id, &no); + ctx.m_userProperties.put("$Section", id, no+1, true); + + ctx.m_configValues.openSection(id, no); + ctx.m_configValues.put(CFG_TYPE_OF_SECTION, typeVal); + + Properties::Iterator it(ctx.m_currentSection); + for (const char* n = it.first(); n != NULL; n = it.next()) { + const Properties * info; + if(!ctx.m_currentInfo->get(n, &info)) + continue; + + Uint32 id = 0; + info->get("Id", &id); + + if(id == KEY_INTERNAL) + continue; + + bool ok = true; + PropertiesType type; + require(ctx.m_currentSection->getTypeOf(n, &type)); + switch(type){ + case PropertiesType_Uint32:{ + Uint32 val; + require(ctx.m_currentSection->get(n, &val)); + ok = ctx.m_configValues.put(id, val); + break; + } + case PropertiesType_Uint64:{ + Uint64 val; + require(ctx.m_currentSection->get(n, &val)); + ok = ctx.m_configValues.put64(id, val); + break; + } + case PropertiesType_char:{ + const char * val; + require(ctx.m_currentSection->get(n, &val)); + ok = ctx.m_configValues.put(id, val); + break; + } + default: + abort(); + } + } + ctx.m_configValues.closeSection(); + } while(0); + return true; +} diff --git a/ndb/src/common/mgmcommon/ConfigInfo.hpp b/ndb/src/common/mgmcommon/ConfigInfo.hpp index 43041a3f772..b5e011ed398 100644 --- a/ndb/src/common/mgmcommon/ConfigInfo.hpp +++ b/ndb/src/common/mgmcommon/ConfigInfo.hpp @@ -27,8 +27,8 @@ * A MANDATORY parameters must be specified in the config file * An UNDEFINED parameter may or may not be specified in the config file */ -static const Uint32 MANDATORY = ~0; // Default value for mandatory params. -static const Uint32 UNDEFINED = (~0)-1; // Default value for undefined params. +static const Uint64 MANDATORY = ~0; // Default value for mandatory params. +static const Uint64 UNDEFINED = (~0)-1; // Default value for undefined params. /** * @class ConfigInfo @@ -38,27 +38,27 @@ static const Uint32 UNDEFINED = (~0)-1; // Default value for undefined params. */ class ConfigInfo { public: - enum Type {BOOL, INT, STRING}; - enum Status {USED, ///< Active - DEPRICATED, ///< Can be, but should not be used anymore - NOTIMPLEMENTED, ///< Can not be used currently. Is ignored. - INTERNAL ///< Not configurable by the user + enum Type { BOOL, INT, INT64, STRING, SECTION }; + enum Status { USED, ///< Active + DEPRICATED, ///< Can be, but shouldn't + NOTIMPLEMENTED, ///< Is ignored. + INTERNAL ///< Not configurable by the user }; /** * Entry for one configuration parameter */ struct ParamInfo { + Uint32 _paramId; const char* _fname; - const char* _pname; const char* _section; const char* _description; Status _status; bool _updateable; Type _type; - Uint32 _default; - Uint32 _min; - Uint32 _max; + Uint64 _default; + Uint64 _min; + Uint64 _max; }; /** @@ -84,16 +84,15 @@ public: * * @note Result is not defined if section/name are wrong! */ - bool verify(const Properties* section, const char* fname, Uint32 value) const; + bool verify(const Properties* secti, const char* fname, Uint64 value) const; bool isSection(const char*) const; - const char* getPName(const Properties * section, const char* fname) const; - const char* getDescription(const Properties * section, const char* fname) const; + const char* getDescription(const Properties * sec, const char* fname) const; Type getType(const Properties * section, const char* fname) const; Status getStatus(const Properties* section, const char* fname) const; - Uint32 getMin(const Properties * section, const char* fname) const; - Uint32 getMax(const Properties * section, const char* fname) const; - Uint32 getDefault(const Properties * section, const char* fname) const; + Uint64 getMin(const Properties * section, const char* fname) const; + Uint64 getMax(const Properties * section, const char* fname) const; + Uint64 getDefault(const Properties * section, const char* fname) const; const Properties * getInfo(const char * section) const; const Properties * getDefaults(const char * section) const; diff --git a/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/ndb/src/common/mgmcommon/ConfigRetriever.cpp index 04dc5466bbc..d2c622593de 100644 --- a/ndb/src/common/mgmcommon/ConfigRetriever.cpp +++ b/ndb/src/common/mgmcommon/ConfigRetriever.cpp @@ -33,6 +33,12 @@ #include <socket_io.h> #include <NdbConfig.h> +#include <NdbAutoPtr.hpp> + +#include <mgmapi.h> +#include <mgmapi_config_parameters.h> +#include <ConfigValues.hpp> +#include <NdbHost.h> //**************************************************************************** //**************************************************************************** @@ -83,41 +89,10 @@ ConfigRetriever::init(bool onlyNodeId) { //**************************************************************************** //**************************************************************************** - -Properties * -ConfigRetriever::getConfig(const char * nodeType, int versionId) { - Properties * p = getConfig(versionId); - - if (p == 0) { - char err_buf[255]; - snprintf(err_buf, sizeof(err_buf), - "No configuration retrieved for this %s node ", nodeType); - setError(CR_ERROR, err_buf); - return 0; - } - - const Uint32 nodeId = _ownNodeId; - - if (strcmp(nodeType, "DB") == 0) { - if (!verifyProperties("DB", p, nodeId, versionId)) return 0; - } else if (strcmp(nodeType, "API") == 0) { - if (!verifyProperties("API", p, nodeId, versionId)) return 0; - } else if (strcmp(nodeType, "REP") == 0) { - if (!verifyProperties("REP", p, nodeId, versionId)) return 0; - } else if (strcmp(nodeType, "MGM") == 0) { - if (!verifyProperties("MGM", p, nodeId, versionId)) return 0; - } else { - return 0; - } - - return p; -} - - //**************************************************************************** //**************************************************************************** -Properties * -ConfigRetriever::getConfig(int verId) { +struct ndb_mgm_configuration* +ConfigRetriever::getConfig(int verId, int nodeType) { int res = init(); if (res == -1) { @@ -125,7 +100,7 @@ ConfigRetriever::getConfig(int verId) { } if (_localConfig->items == 0){ - setError(CR_ERROR, "No Management Servers configured in local config file"); + setError(CR_ERROR,"No Management Servers configured in local config file"); return 0; } @@ -136,14 +111,13 @@ ConfigRetriever::getConfig(int verId) { Uint32 type = CR_ERROR; for (int i = 0; i<_localConfig->items; i++){ MgmtSrvrId * m = _localConfig->ids[i]; - Properties * p = 0; - const Uint32 nodeId = _ownNodeId; + struct ndb_mgm_configuration * p = 0; switch(m->type){ case MgmId_TCP: - p = getConfig(m->data.tcp.remoteHost, m->data.tcp.port, nodeId, verId); + p = getConfig(m->data.tcp.remoteHost, m->data.tcp.port, verId); break; case MgmId_File: - p = getConfig(m->data.file.filename, nodeId, verId); + p = getConfig(m->data.file.filename, verId); break; default: setError(CR_ERROR, "Unknown error type"); @@ -151,6 +125,10 @@ ConfigRetriever::getConfig(int verId) { } if (p != 0) { + if(!verifyConfig(p, nodeType)){ + free(p); + return 0; + } return p; } if(latestErrorType == CR_RETRY) @@ -161,110 +139,49 @@ ConfigRetriever::getConfig(int verId) { 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; + << "Trying again in "<< retry_interval <<" seconds..." + << endl << endl; NdbSleep_SecSleep(retry_interval); } else { break; } retry++; - + } while (retry <= retry_max); return 0; } -int global_ndb_check = 0; // set to one in ndb main; -Properties * +ndb_mgm_configuration * ConfigRetriever::getConfig(const char * mgmhost, - unsigned int port, - Uint32 nodeId, + short port, int versionId){ - const int socketTimeout = 10000; - int result; - const NDB_SOCKET_TYPE sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd == NDB_INVALID_SOCKET) { - setError(CR_RETRY, "Could not create socket to Management Server"); + + NdbMgmHandle h; + h = ndb_mgm_create_handle(); + if (h == NULL) { + setError(CR_ERROR, "Unable to allocate mgm handle"); return 0; } - char err_buf[255]; - struct sockaddr_in servaddr; - memset(&servaddr, 0, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_port = htons(port); - // Convert ip address presentation format to numeric format - result = Ndb_getInAddr(&servaddr.sin_addr, mgmhost); - if (result != 0) { - snprintf(err_buf, sizeof(err_buf), - "Name lookup failed: host \"%s\"", mgmhost); - setError(CR_ERROR, err_buf); + BaseString tmp; + tmp.assfmt("%s:%d", mgmhost, port); + if (ndb_mgm_connect(h, tmp.c_str()) != 0) { + setError(CR_RETRY, ndb_mgm_get_latest_error_desc(h)); + ndb_mgm_destroy_handle(&h); return 0; } - result = connect(sockfd, (struct sockaddr*) &servaddr, sizeof(servaddr)); - if (result == -1) { - snprintf(err_buf, sizeof(err_buf), - "Failed to connect to \"%s:%d\"", mgmhost, port); - setError(CR_RETRY, err_buf); - NDB_CLOSE_SOCKET(sockfd); - return 0; + ndb_mgm_configuration * conf = ndb_mgm_get_configuration(h, versionId); + if(conf == 0){ + setError(CR_ERROR, ndb_mgm_get_latest_error_desc(h)); } - - if(println_socket(sockfd, 1000, "GET CONFIG %d %d" , - versionId, nodeId) != 0){ - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, "IO error, write"); - return 0; - } - - char buf[255]; - { - const int tmp = readln_socket(sockfd, socketTimeout, buf, 255); - if(tmp == -1){ - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, "IO error, read"); - return 0; - } - if(tmp == 0){ - snprintf(err_buf, 256, - "IO error, failed request: " - "GET CONFIG %d %d", versionId, nodeId); - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, err_buf); - return 0; - } - } + ndb_mgm_disconnect(h); + ndb_mgm_destroy_handle(&h); - int status, version, node, bytes, bytesUU; - if(sscanf(buf, "GET CONFIG %d %d %d %d %d", - &status, &version, &node, &bytes, &bytesUU) != 5){ - NDB_CLOSE_SOCKET(sockfd); - snprintf(err_buf, sizeof(err_buf), - "Invalid response: %s", buf); - setError(CR_ERROR, err_buf); - return 0; - } - - if(status != 0){ - NDB_CLOSE_SOCKET(sockfd); - if (status == 1){ - snprintf(err_buf, sizeof(err_buf), - "Management Server: Requested version id is invalid"); - } else if (status == 2){ - snprintf(err_buf, sizeof(err_buf), - "Management Server: Node with id %d has not been specified", - nodeId); - } else if (status == 3){ - snprintf(err_buf, sizeof(err_buf), "Management Server: Internal error"); - } else { - snprintf(err_buf, sizeof(err_buf), - "Management Server returned unknown error: %d", status); - } - setError(CR_ERROR, err_buf); - return 0; - } - + return conf; +#if 0 bool compatible; if (global_ndb_check) compatible = ndbCompatible_ndb_mgmt(versionId, version); @@ -278,90 +195,11 @@ ConfigRetriever::getConfig(const char * mgmhost, setError(CR_ERROR, err_buf); return 0; } - - if(node != (int)nodeId){ - NDB_CLOSE_SOCKET(sockfd); - snprintf(err_buf, sizeof(err_buf), "Management Server: Invalid node id. " - "Node id from server: %d Own node id: %d", node, nodeId); - setError(CR_ERROR, err_buf); - return 0; - } - - if(readln_socket(sockfd, socketTimeout, buf, 255) == -1){ - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, "IO error, read"); - return 0; - } - - if(strncmp("begin", buf, strlen("begin")) != 0){ - NDB_CLOSE_SOCKET(sockfd); - snprintf(err_buf, sizeof(err_buf), - "Invalid response: %s", buf); - setError(CR_ERROR, err_buf); - return 0; - } - - char* bufUU = new char[bytesUU]; - int read = 0; - int start = 0; - do { - if((read = read_socket(sockfd, socketTimeout, &bufUU[start], bytesUU-start)) == -1){ - delete[] bufUU; - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, "IO error, read(bufUU)"); - return 0; - } - start += read; - } while(start < bytesUU); - - Uint32 * buf2 = new Uint32[bytes/4+1]; // Properties byte size - char * dst = (char *)buf2; - int sz = 0; - start = 0; - - for (int i = 0; i < bytesUU; i++) { - if (bufUU[i] == '\n') { - bufUU[i] = 0; - if (bufUU[i-1] == '\r') { - bufUU[i-1] = 0; - } - sz = uudecode_mem(dst, bytes, &bufUU[start]); - dst += sz; - start = i + 1; // Next row - } - } - - delete[] bufUU; - - if(sz < 0){ - delete []buf2; - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, "IO error, sz < 0"); - return 0; - } - - Properties * p = new Properties(); - if(!p->unpack(buf2, bytes+4)){ - snprintf(buf, sizeof(buf), "Error while unpacking %d,%d", - p->getPropertiesErrno(), - p->getOSErrno()); - setError(CR_ERROR, buf); - delete []buf2; - delete p; - return 0; - } - delete []buf2; - - NDB_CLOSE_SOCKET(sockfd); - - return p; - +#endif } -Properties * -ConfigRetriever::getConfig(const char * filename, - Uint32 nodeId, - int versionId){ +ndb_mgm_configuration * +ConfigRetriever::getConfig(const char * filename, int versionId){ struct stat sbuf; const int res = stat(filename, &sbuf); @@ -389,74 +227,19 @@ ConfigRetriever::getConfig(const char * filename, return 0; } - Properties * p = new Properties(); - if(!p->unpack(buf2, bytes+4)){ + ConfigValuesFactory cvf; + if(!cvf.unpack(buf2, bytes)){ char buf[255]; - snprintf(buf, sizeof(buf), "Error while unpacking %d,%d", - p->getPropertiesErrno(), - p->getOSErrno()); + snprintf(buf, sizeof(buf), "Error while unpacking"); setError(CR_ERROR, buf); delete []buf2; - delete p; return 0; } delete [] buf2; - return p; + return (ndb_mgm_configuration*)cvf.m_cfg; } -bool -ConfigRetriever::verifyProperties(const char* nodeType, Properties * p, - Uint32 nodeId, int versionId){ - - Uint32 t = 0; - const Properties *tmp; - const char *type; - - if (p == 0) return false; - - bool compatible = false; - if (p->get("Version", &t)) - if (global_ndb_check) - compatible = ndbCompatible_ndb_mgmt(versionId, t); - else - compatible = ndbCompatible_api_mgmt(versionId, t); - - if(!compatible){ // if(!p->get("Version", &t) || versionId != (int)t){ - setError(CR_ERROR, "Invalid configuration version"); - delete p; - return false; - } - - if(!p->get("LocalNodeId", &t) || nodeId != t){ - setError(CR_ERROR, "Invalid node identity in configuration"); - delete p; - return false; - } - - if(!p->get("Node", nodeId, &tmp)){ - setError(CR_ERROR, "Internal error while processing configuration"); - ndbout_c("nodeId = %d", nodeId); - p->print(); - delete p; - return false; - } - - if(!tmp->get("Type", &type) || strcmp(type, nodeType)) { - if (!(!strcmp(type, "REP") && !strcmp(nodeType, "API"))) { - char buf[1024]; - snprintf(buf, sizeof(buf), - "Configuration error: Node with id %d is not of type %s.\n" - "Check local config file: %s", nodeId, nodeType, - _localConfigFileName); - setError(CR_ERROR, buf); - return false; - } - } - - return true; -} - void ConfigRetriever::setError(ErrorType et, const char * s){ if(errorString != 0){ @@ -509,3 +292,82 @@ ConfigRetriever::setDefaultConnectString(const char * defaultConnectString) { m_defaultConnectString = 0; } } + +bool +ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, + int type){ + char buf[255]; + ndb_mgm_configuration_iterator * it; + it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf, CFG_SECTION_NODE); + + if(it == 0){ + snprintf(buf, 255, "Unable to create config iterator"); + setError(CR_ERROR, buf); + return false; + + } + NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it); + + if(ndb_mgm_find(it, CFG_NODE_ID, getOwnNodeId()) != 0){ + snprintf(buf, 255, "Unable to find node with id: %d", getOwnNodeId()); + setError(CR_ERROR, buf); + return false; + } + + const char * hostname; + if(ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &hostname)){ + snprintf(buf, 255, "Unable to get hostname(%d) from config",CFG_NODE_HOST); + setError(CR_ERROR, buf); + return false; + } + + char localhost[MAXHOSTNAMELEN]; + if(NdbHost_GetHostName(localhost) != 0){ + snprintf(buf, 255, "Unable to own hostname"); + setError(CR_ERROR, buf); + return false; + } + + do { + if(strcasecmp(hostname, localhost) == 0) + break; + + if(strcasecmp(hostname, "localhost") == 0) + break; + + struct in_addr local, config; + bool b1 = false, b2 = false, b3 = false; + b1 = Ndb_getInAddr(&local, localhost) == 0; + b2 = Ndb_getInAddr(&config, hostname) == 0; + b3 = memcmp(&local, &config, sizeof(local)) == 0; + + if(b1 && b2 && b3) + break; + + b1 = Ndb_getInAddr(&local, "localhost") == 0; + b3 = memcmp(&local, &config, sizeof(local)) == 0; + if(b1 && b2 && b3) + break; + + snprintf(buf, 255, "Local hostname(%s) and config hostname(%s) dont match", + localhost, hostname); + setError(CR_ERROR, buf); + return false; + } while(false); + + unsigned int _type; + if(ndb_mgm_get_int_parameter(it, CFG_TYPE_OF_SECTION, &_type)){ + snprintf(buf, 255, "Unable to get type of node(%d) from config", + CFG_TYPE_OF_SECTION); + setError(CR_ERROR, buf); + return false; + } + + if(_type != type){ + snprintf(buf, 255, "Supplied node type(%d) and config node type(%d) " + " don't match", type, _type); + setError(CR_ERROR, buf); + return false; + } + return true; +} diff --git a/ndb/src/common/mgmcommon/IPCConfig.cpp b/ndb/src/common/mgmcommon/IPCConfig.cpp index f75cf806cc0..ba5fe7ace80 100644 --- a/ndb/src/common/mgmcommon/IPCConfig.cpp +++ b/ndb/src/common/mgmcommon/IPCConfig.cpp @@ -17,10 +17,14 @@ #include "IPCConfig.hpp" #include <NdbOut.hpp> #include <NdbHost.h> + #include <TransporterDefinitions.hpp> #include <TransporterRegistry.hpp> #include <Properties.hpp> +#include <mgmapi_configuration.hpp> +#include <mgmapi_config_parameters.h> + #if defined DEBUG_TRANSPORTER #define DEBUG(t) ndbout << __FILE__ << ":" << __LINE__ << ":" << t << endl; #else @@ -334,3 +338,158 @@ IPCConfig::getNodeType(NodeId id) const { return out; } + +Uint32 +IPCConfig::configureTransporters(Uint32 nodeId, + const class ndb_mgm_configuration & config, + class TransporterRegistry & tr){ + + Uint32 noOfTransportersCreated = 0; + ndb_mgm_configuration_iterator iter(config, CFG_SECTION_CONNECTION); + + for(iter.first(); iter.valid(); iter.next()){ + + Uint32 nodeId1, nodeId2, remoteNodeId; + if(iter.get(CFG_CONNECTION_NODE_1, &nodeId1)) continue; + if(iter.get(CFG_CONNECTION_NODE_2, &nodeId2)) continue; + + if(nodeId1 != nodeId && nodeId2 != nodeId) continue; + remoteNodeId = (nodeId == nodeId1 ? nodeId2 : nodeId1); + + Uint32 sendSignalId = 1; + Uint32 checksum = 1; + if(iter.get(CFG_CONNECTION_SEND_SIGNAL_ID, &sendSignalId)) continue; + if(iter.get(CFG_CONNECTION_CHECKSUM, &checksum)) continue; + + Uint32 type = ~0; + if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue; + + switch(type){ + case CONNECTION_TYPE_SHM:{ + SHM_TransporterConfiguration conf; + conf.localNodeId = nodeId; + conf.remoteNodeId = remoteNodeId; + conf.byteOrder = 0; + conf.compression = 0; + conf.checksum = checksum; + conf.signalId = sendSignalId; + + if(iter.get(CFG_SHM_KEY, &conf.shmKey)) break; + if(iter.get(CFG_SHM_BUFFER_MEM, &conf.shmSize)) break; + + if(!tr.createTransporter(&conf)){ + ndbout << "Failed to create SHM Transporter from: " + << conf.localNodeId << " to: " << conf.remoteNodeId << endl; + } else { + noOfTransportersCreated++; + } + break; + } + case CONNECTION_TYPE_SCI:{ + SCI_TransporterConfiguration conf; + conf.localNodeId = nodeId; + conf.remoteNodeId = remoteNodeId; + conf.byteOrder = 0; + conf.compression = 0; + conf.checksum = checksum; + conf.signalId = sendSignalId; + + if(iter.get(CFG_SCI_SEND_LIMIT, &conf.sendLimit)) break; + if(iter.get(CFG_SCI_BUFFER_MEM, &conf.bufferSize)) break; + + if(nodeId == nodeId1){ + if(iter.get(CFG_SCI_NODE1_ADAPTERS, &conf.nLocalAdapters)) break; + if(iter.get(CFG_SCI_NODE2_ADAPTERS, &conf.nRemoteAdapters)) break; + if(iter.get(CFG_SCI_NODE2_ADAPTER0, &conf.remoteSciNodeId0)) break; + if(conf.nRemoteAdapters > 1){ + if(iter.get(CFG_SCI_NODE2_ADAPTER1, &conf.remoteSciNodeId1)) break; + } + } else { + if(iter.get(CFG_SCI_NODE2_ADAPTERS, &conf.nLocalAdapters)) break; + if(iter.get(CFG_SCI_NODE1_ADAPTERS, &conf.nRemoteAdapters)) break; + if(iter.get(CFG_SCI_NODE1_ADAPTER0, &conf.remoteSciNodeId0)) break; + if(conf.nRemoteAdapters > 1){ + if(iter.get(CFG_SCI_NODE1_ADAPTER1, &conf.remoteSciNodeId1)) break; + } + } + + if(!tr.createTransporter(&conf)){ + ndbout << "Failed to create SCI Transporter from: " + << conf.localNodeId << " to: " << conf.remoteNodeId << endl; + } else { + noOfTransportersCreated++; + continue; + } + } + case CONNECTION_TYPE_TCP:{ + TCP_TransporterConfiguration conf; + + const char * host1, * host2; + if(iter.get(CFG_TCP_HOSTNAME_1, &host1)) break; + if(iter.get(CFG_TCP_HOSTNAME_2, &host2)) break; + + if(iter.get(CFG_TCP_SERVER_PORT, &conf.port)) break; + if(iter.get(CFG_TCP_SEND_BUFFER_SIZE, &conf.sendBufferSize)) break; + if(iter.get(CFG_TCP_RECEIVE_BUFFER_SIZE, &conf.maxReceiveSize)) break; + + const char * proxy; + if (!iter.get(CFG_TCP_PROXY, &proxy)) { + if (strlen(proxy) > 0 && nodeId2 == nodeId) { + // TODO handle host:port + conf.port = atoi(proxy); + } + } + + conf.localNodeId = nodeId; + conf.remoteNodeId = remoteNodeId; + conf.localHostName = (nodeId == nodeId1 ? host1 : host2); + conf.remoteHostName = (nodeId == nodeId1 ? host2 : host1); + conf.byteOrder = 0; + conf.compression = 0; + conf.checksum = checksum; + conf.signalId = sendSignalId; + + if(!tr.createTransporter(&conf)){ + ndbout << "Failed to create TCP Transporter from: " + << nodeId << " to: " << remoteNodeId << endl; + } else { + noOfTransportersCreated++; + } + case CONNECTION_TYPE_OSE:{ + OSE_TransporterConfiguration conf; + + const char * host1, * host2; + if(iter.get(CFG_OSE_HOSTNAME_1, &host1)) break; + if(iter.get(CFG_OSE_HOSTNAME_2, &host2)) break; + + if(iter.get(CFG_OSE_PRIO_A_SIZE, &conf.prioASignalSize)) break; + if(iter.get(CFG_OSE_PRIO_B_SIZE, &conf.prioBSignalSize)) break; + if(iter.get(CFG_OSE_RECEIVE_ARRAY_SIZE, &conf.receiveBufferSize)) break; + + conf.localNodeId = nodeId; + conf.remoteNodeId = remoteNodeId; + conf.localHostName = (nodeId == nodeId1 ? host1 : host2); + conf.remoteHostName = (nodeId == nodeId1 ? host2 : host1); + conf.byteOrder = 0; + conf.compression = 0; + conf.checksum = checksum; + conf.signalId = sendSignalId; + + if(!tr.createTransporter(&conf)){ + ndbout << "Failed to create OSE Transporter from: " + << nodeId << " to: " << remoteNodeId << endl; + } else { + noOfTransportersCreated++; + } + } + default: + ndbout << "Unknown transporter type from: " << nodeId << + " to: " << remoteNodeId << endl; + break; + } + } + } + + return noOfTransportersCreated; +} + diff --git a/ndb/src/common/mgmcommon/InitConfigFileParser.cpp b/ndb/src/common/mgmcommon/InitConfigFileParser.cpp index 62c4bd28857..d01b8189545 100644 --- a/ndb/src/common/mgmcommon/InitConfigFileParser.cpp +++ b/ndb/src/common/mgmcommon/InitConfigFileParser.cpp @@ -30,51 +30,66 @@ static void require(bool v) { if(!v) abort();} //**************************************************************************** // Ctor / Dtor //**************************************************************************** -InitConfigFileParser::InitConfigFileParser(const char* initialConfigFileName){ - - m_initConfigStream = fopen(initialConfigFileName, "r"); +InitConfigFileParser::InitConfigFileParser(){ m_info = new ConfigInfo(); - m_config = new Config(); - m_defaults = new Properties(); - m_defaults->setCaseInsensitiveNames(true); } InitConfigFileParser::~InitConfigFileParser() { - if (m_initConfigStream != NULL) fclose(m_initConfigStream); - delete m_info; - delete m_config; - delete m_defaults; } //**************************************************************************** // Read Config File //**************************************************************************** -bool InitConfigFileParser::readConfigFile() { +InitConfigFileParser::Context::Context(const ConfigInfo * info) + : m_configValues(1000, 20) { + + m_config = new Properties(); + m_defaults = new Properties(); +} + +InitConfigFileParser::Context::~Context(){ + if(m_config != 0) + delete m_config; + + if(m_defaults != 0) + delete m_defaults; +} + +Config * +InitConfigFileParser::parseConfig(const char * filename) { + FILE * file = fopen(filename, "r"); + if(file == 0){ + ndbout << "Error opening file: " << filename << endl; + return 0; + } + + Config * ret = parseConfig(file); + fclose(file); + return ret; +} + +Config * +InitConfigFileParser::parseConfig(FILE * file) { char line[MAX_LINE_LENGTH]; - Context ctx; + Context ctx(m_info); ctx.m_lineno = 0; ctx.m_currentSection = 0; - ctx.m_info = m_info; - ctx.m_config = m_config; - ctx.m_defaults = m_defaults; - /************* * Open file * *************/ - if (m_initConfigStream == NULL) { - ctx.reportError("Could not open file."); - return false; + if (file == NULL) { + return 0; } /*********************** * While lines to read * ***********************/ - while (fgets(line, MAX_LINE_LENGTH, m_initConfigStream)) { + while (fgets(line, MAX_LINE_LENGTH, file)) { ctx.m_lineno++; trim(line); @@ -94,7 +109,7 @@ bool InitConfigFileParser::readConfigFile() { free(section); ctx.reportError("Could not store previous default section " "of configuration file."); - return false; + return 0; } snprintf(ctx.fname, sizeof(ctx.fname), section); free(section); @@ -115,7 +130,7 @@ bool InitConfigFileParser::readConfigFile() { free(section); ctx.reportError("Could not store previous section " "of configuration file."); - return false; + return 0; } snprintf(ctx.fname, sizeof(ctx.fname), section); @@ -123,7 +138,7 @@ bool InitConfigFileParser::readConfigFile() { ctx.type = InitConfigFileParser::Section; ctx.m_sectionLineno = ctx.m_lineno; ctx.m_currentSection = new Properties(); - ctx.m_userDefaults = getSection(ctx.fname, m_defaults); + ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults); ctx.m_currentInfo = m_info->getInfo(ctx.fname); ctx.m_systemDefaults = m_info->getDefaults(ctx.fname); continue; @@ -134,13 +149,18 @@ bool InitConfigFileParser::readConfigFile() { ****************************/ if (!parseNameValuePair(ctx, line)) { ctx.reportError("Could not parse name-value pair in config file."); - return false; + return 0; } } + if (ferror(file)){ + ctx.reportError("Failure in reading"); + return 0; + } + if(!storeSection(ctx)) { ctx.reportError("Could not store section of configuration file."); - return false; + return 0; } Uint32 nConnections = 0; @@ -153,21 +173,20 @@ bool InitConfigFileParser::readConfigFile() { ctx.m_userProperties.get("NoOfNodes", &nNodes); ctx.m_userProperties.get("ExtNoOfConnections", &nExtConnections); ctx.m_userProperties.get("ExtSystem", &system); - m_config->put("NoOfConnections", nConnections); - m_config->put("NoOfComputers", nComputers); - m_config->put("NoOfNodes", nNodes); + ctx.m_config->put("NoOfConnections", nConnections); + ctx.m_config->put("NoOfComputers", nComputers); + ctx.m_config->put("NoOfNodes", nNodes); char tmpLine[MAX_LINE_LENGTH]; snprintf(tmpLine, MAX_LINE_LENGTH, "EXTERNAL SYSTEM_"); strncat(tmpLine, system, MAX_LINE_LENGTH); strncat(tmpLine, ":NoOfConnections", MAX_LINE_LENGTH); - m_config->put(tmpLine, nExtConnections); + ctx.m_config->put(tmpLine, nExtConnections); - if (ferror(m_initConfigStream)) { - ctx.reportError("Failure in reading"); - return false; - } - return true; + Config * ret = new Config(); + ret->m_configValues = (struct ndb_mgm_configuration*)ctx.m_configValues.getConfigValues(); + ret->m_oldConfig = ctx.m_config; ctx.m_config = 0; + return ret; } //**************************************************************************** @@ -216,7 +235,13 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { ctx.reportWarning("[%s] %s not yet implemented", ctx.fname, fname); } if (status == ConfigInfo::DEPRICATED) { - ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname); + const char * desc = m_info->getDescription(ctx.m_currentInfo, fname); + if(desc){ + ctx.reportWarning("[%s] %s is depricated, use %s instead", + ctx.fname, fname, desc); + } else { + ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname); + } } // ****************************************** @@ -249,7 +274,7 @@ InitConfigFileParser::storeNameValuePair(Context& ctx, const char* fname, const char* value) { - const char * pname = m_info->getPName(ctx.m_currentInfo, fname); + const char * pname = fname; if (ctx.m_currentSection->contains(pname)) { ctx.reportError("[%s] Parameter %s specified twice", ctx.fname, fname); @@ -260,7 +285,8 @@ InitConfigFileParser::storeNameValuePair(Context& ctx, // Store name-value pair // *********************** - switch(m_info->getType(ctx.m_currentInfo, fname)){ + const ConfigInfo::Type type = m_info->getType(ctx.m_currentInfo, fname); + switch(type){ case ConfigInfo::BOOL: { bool value_bool; if (!convertStringToBool(value, value_bool)) { @@ -270,9 +296,10 @@ InitConfigFileParser::storeNameValuePair(Context& ctx, MGM_REQUIRE(ctx.m_currentSection->put(pname, value_bool)); break; } - case ConfigInfo::INT:{ - Uint32 value_int; - if (!convertStringToUint32(value, value_int)) { + case ConfigInfo::INT: + case ConfigInfo::INT64:{ + Uint64 value_int; + if (!convertStringToUint64(value, value_int)) { ctx.reportError("Illegal integer value for parameter %s", fname); return false; } @@ -283,7 +310,11 @@ InitConfigFileParser::storeNameValuePair(Context& ctx, m_info->getMax(ctx.m_currentInfo, fname)); return false; } - MGM_REQUIRE(ctx.m_currentSection->put(pname, value_int)); + if(type == ConfigInfo::INT){ + MGM_REQUIRE(ctx.m_currentSection->put(pname, (Uint32)value_int)); + } else { + MGM_REQUIRE(ctx.m_currentSection->put64(pname, value_int)); + } break; } case ConfigInfo::STRING: @@ -313,8 +344,8 @@ bool InitConfigFileParser::isEmptyLine(const char* line) const { //**************************************************************************** // Convert String to Int //**************************************************************************** -bool InitConfigFileParser::convertStringToUint32(const char* s, - Uint32& val, +bool InitConfigFileParser::convertStringToUint64(const char* s, + Uint64& val, Uint32 log10base) { if (s == NULL) return false; @@ -323,7 +354,7 @@ bool InitConfigFileParser::convertStringToUint32(const char* s, errno = 0; char* p; - long v = strtol(s, &p, 10); + long long v = strtoll(s, &p, 10); if (errno != 0) return false; @@ -359,14 +390,16 @@ bool InitConfigFileParser::convertStringToBool(const char* s, bool& val) { if (!strcmp(s, "Y") || !strcmp(s, "y") || !strcmp(s, "Yes") || !strcmp(s, "YES") || !strcmp(s, "yes") || - !strcmp(s, "True") || !strcmp(s, "TRUE") || !strcmp(s, "true")) { + !strcmp(s, "True") || !strcmp(s, "TRUE") || !strcmp(s, "true") || + !strcmp(s, "1")) { val = true; return true; } if (!strcmp(s, "N") || !strcmp(s, "n") || !strcmp(s, "No") || !strcmp(s, "NO") || !strcmp(s, "no") || - !strcmp(s, "False") || !strcmp(s, "FALSE") || !strcmp(s, "false")) { + !strcmp(s, "False") || !strcmp(s, "FALSE") || !strcmp(s, "false") || + !strcmp(s, "0")) { val = false; return true; } @@ -375,21 +408,6 @@ bool InitConfigFileParser::convertStringToBool(const char* s, bool& val) { } //**************************************************************************** -// Get Config -//**************************************************************************** -const Config* InitConfigFileParser::getConfig() { - Uint32 nConnections = 0; - Uint32 nComputers = 0; - Uint32 nNodes = 0; - m_config->get("NoOfConnections", &nConnections); - m_config->get("NoOfComputers", &nComputers); - m_config->get("NoOfNodes", &nNodes); - - return m_config; -} - - -//**************************************************************************** // Parse Section Header //**************************************************************************** static void @@ -495,19 +513,22 @@ InitConfigFileParser::storeSection(Context& ctx){ snprintf(buf, sizeof(buf), "%s DEFAULT", ctx.fname); snprintf(ctx.fname, sizeof(ctx.fname), buf); - for(int i = 0; i<m_info->m_NoOfRules; i++){ - const ConfigInfo::SectionRule & rule = m_info->m_SectionRules[i]; - if(strcmp(rule.m_section, ctx.fname) == 0) - if(!(* rule.m_sectionRule)(ctx, rule.m_ruleData)){ - return false; + if(ctx.type == InitConfigFileParser::Section){ + for(int i = 0; i<m_info->m_NoOfRules; i++){ + const ConfigInfo::SectionRule & rule = m_info->m_SectionRules[i]; + if(!strcmp(rule.m_section, "*") || !strcmp(rule.m_section, ctx.fname)){ + if(!(* rule.m_sectionRule)(ctx, rule.m_ruleData)){ + return false; + } } + } } - + if(ctx.type == InitConfigFileParser::DefaultSection) - require(m_defaults->put(ctx.pname, ctx.m_currentSection)); + require(ctx.m_defaults->put(ctx.pname, ctx.m_currentSection)); if(ctx.type == InitConfigFileParser::Section) - require(m_config->put(ctx.pname, ctx.m_currentSection)); + require(ctx.m_config->put(ctx.pname, ctx.m_currentSection)); delete ctx.m_currentSection; ctx.m_currentSection = NULL; diff --git a/ndb/src/common/mgmcommon/InitConfigFileParser.hpp b/ndb/src/common/mgmcommon/InitConfigFileParser.hpp index f4f27abb055..6b7482c12ae 100644 --- a/ndb/src/common/mgmcommon/InitConfigFileParser.hpp +++ b/ndb/src/common/mgmcommon/InitConfigFileParser.hpp @@ -20,6 +20,7 @@ #include <ndb_global.h> #include <Properties.hpp> +#include <ConfigValues.hpp> class Config; class ConfigInfo; @@ -28,18 +29,40 @@ class ConfigInfo; * @class InitConfigFileParser * @brief Reads initial config file and returns Config object * - * This class contains one public method InitConfigFileParser::getConfig, + * This class contains one public method InitConfigFileParser::parseConfig, * which reads an initial configuration file and returns a Config * object if the config file has correct syntax and semantic. */ class InitConfigFileParser { public: + /** + * Constructor + */ + InitConfigFileParser(); + ~InitConfigFileParser(); + + /** + * Reads the initial configuration file, checks syntax and semantic + * and stores internally the values of all parameters. + * + * @returns Config or NULL on failure + * @note must be freed by caller + */ + Config * parseConfig(FILE * file); + Config * parseConfig(const char * filename); + + /** + * Parser context struct + */ enum ContextSectionType { Undefined, Section, DefaultSection }; /** * Context = Which section in init config file we are currently parsing */ struct Context { + Context(const ConfigInfo *); + ~Context(); + ContextSectionType type; ///< Section type (e.g. default section,section) char fname[256]; ///< Section name occuring in init config file char pname[256]; ///< Section name stored in properties object @@ -47,8 +70,8 @@ public: Uint32 m_sectionLineno; ///< Where did current section start const ConfigInfo * m_info; // The config info - const Properties * m_config; // The config object - const Properties * m_defaults; // The user defaults + Properties * m_config; // The config object + Properties * m_defaults; // The user defaults Properties * m_currentSection; // The current section I'm in const Properties * m_userDefaults; // The defaults of this section @@ -56,36 +79,13 @@ public: const Properties * m_currentInfo; // The "info" for this section Properties m_userProperties; // User properties (temporary values) + ConfigValuesFactory m_configValues; // public: void reportError(const char * msg, ...); void reportWarning(const char * msg, ...); }; - - /** - * Constructor - * @param initialConfigFileName: Name of the initial configuration file - */ - InitConfigFileParser(const char* initialConfigFileName); - ~InitConfigFileParser(); - - /** - * Reads the initial configuration file, checks syntax and semantic - * and stores internally the values of all parameters. - * - * @returns true if succeeded, o/w false (e.g. incorrect config file) - */ - bool readConfigFile(); - - /** - * Get config. Must execute InitConfigFileParser::readConfigFile first. - * - * @returns Config if succeeded, o/w NULL - */ - const Config* getConfig(); - - private: /** * Check if line only contains space/comments @@ -111,33 +111,16 @@ private: bool parseNameValuePair(Context&, const char* line); bool storeNameValuePair(Context&, const char* fname, const char* value); - bool convertStringToUint32(const char* s, Uint32& val, Uint32 log10base = 0); + bool convertStringToUint64(const char* s, Uint64& val, Uint32 log10base = 0); bool convertStringToBool(const char* s, bool& val); + bool storeSection(Context&); const Properties* getSection(const char * name, const Properties* src); - /*************************************************************************** - * VARIABLES - ***************************************************************************/ - FILE* m_initConfigStream; - /** * Information about parameters (min, max values etc) */ - const ConfigInfo* m_info; - - /** - * Configuration from initial configuration file - * (returned by InitConfigFileParser::readConfigFile) - */ - Config* m_config; - - /** - * Default values specified in default sections - */ - Properties* m_defaults; - - bool storeSection(Context&); + ConfigInfo* m_info; }; #endif // InitConfigFileParser_H diff --git a/ndb/src/common/mgmcommon/Makefile_old b/ndb/src/common/mgmcommon/Makefile_old index 2db7be01d60..c7bfda7e3bf 100644 --- a/ndb/src/common/mgmcommon/Makefile_old +++ b/ndb/src/common/mgmcommon/Makefile_old @@ -5,6 +5,7 @@ TYPE := ndbapi mgmapiclient PIC_ARCHIVE := Y ARCHIVE_TARGET := mgmsrvcommon +# Removed temporary DIRS := printConfig SOURCES = \ @@ -17,6 +18,8 @@ SOURCES = \ SOURCES.c = NdbConfig.c +CFLAGS_IPCConfig.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) + include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/mgmcommon/printConfig/Makefile b/ndb/src/common/mgmcommon/printConfig/Makefile index 9194316da87..77e8943e2c6 100644 --- a/ndb/src/common/mgmcommon/printConfig/Makefile +++ b/ndb/src/common/mgmcommon/printConfig/Makefile @@ -7,8 +7,10 @@ BIN_TARGET_ARCHIVES := general portlib CCFLAGS_LOC += -I.. -SOURCES := printConfig.cpp +SOURCES := printConfig.cpp ../ConfigRetriever.cpp -SOURCES.c := ../ConfigRetriever.c ../NdbConfig.c ../LocalConfig.c +SOURCES.c := ../NdbConfig.c ../LocalConfig.c + +CFLAGS_printConfig.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/mgmcommon/printConfig/printConfig.cpp b/ndb/src/common/mgmcommon/printConfig/printConfig.cpp index daa287cc44d..7cedbb451e2 100644 --- a/ndb/src/common/mgmcommon/printConfig/printConfig.cpp +++ b/ndb/src/common/mgmcommon/printConfig/printConfig.cpp @@ -18,6 +18,7 @@ #include <ndb_global.h> #include <NdbMain.h> +#include <mgmapi.h> #include <ConfigRetriever.hpp> #include <Properties.hpp> #include <NdbOut.hpp> @@ -50,9 +51,9 @@ NDB_COMMAND(printConfig, return 0; } - Properties * p = 0; ConfigRetriever c; - + struct ndb_mgm_configuration * p = 0; + if(strcmp("host", argv[1]) == 0){ int verId = 0; if(argc > 5) @@ -64,7 +65,6 @@ NDB_COMMAND(printConfig, p = c.getConfig(argv[2], atoi(argv[3]), - atoi(argv[4]), verId); } else if (strcmp("file", argv[1]) == 0){ int verId = 0; @@ -79,12 +79,11 @@ NDB_COMMAND(printConfig, } if(p != 0){ - p->print(stdout); + // + free(p); } else { ndbout << "Configuration not found: " << c.getErrorString() << endl; } - delete p; - return 0; } diff --git a/ndb/src/common/util/Base64.cpp b/ndb/src/common/util/Base64.cpp index 482d0b10ad2..f7a490d427d 100644 --- a/ndb/src/common/util/Base64.cpp +++ b/ndb/src/common/util/Base64.cpp @@ -22,89 +22,186 @@ static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789+/"; int -base64_encode(UtilBuffer &src, BaseString &dst) { - char *s = (char *)src.get_data(); - int i = 0; +base64_encode(const UtilBuffer &src, BaseString &dst) { + const unsigned char *s = (const unsigned char *)src.get_data(); + size_t i = 0; + size_t len = 0; + size_t src_len = src.length(); + while(i < src_len) { + if(len == 76){ + len = 0; + dst.append('\n'); + } - while(i < src.length()) { - int c; + unsigned c; c = s[i++]; c <<= 8; - if(i < src.length()) + if(i < src_len) c += s[i]; c <<= 8; i++; - if(i < src.length()) + if(i < src_len) c += s[i]; i++; - + dst.append(base64_table[(c >> 18) & 0x3f]); dst.append(base64_table[(c >> 12) & 0x3f]); - if(i > (src.length() + 1)) + if(i > (src_len + 1)) dst.append('='); else dst.append(base64_table[(c >> 6) & 0x3f]); - if(i > src.length()) + if(i > src_len) dst.append('='); else dst.append(base64_table[(c >> 0) & 0x3f]); + + len += 4; } return 0; } -static inline int -pos(char c) { +static inline unsigned +pos(unsigned char c) { return strchr(base64_table, c) - base64_table; } int -base64_decode(BaseString &src, UtilBuffer &dst) { - size_t size; - size = (src.length() * 3) / 4; +base64_decode(const BaseString &src, UtilBuffer &dst) { + return base64_decode(src.c_str(), src.length(), dst); +} + +#define SKIP_SPACE(src, i, size){ \ + while(i < size && isspace(* src)){ \ + i++; \ + src++; \ + } \ + if(i == size){ \ + i = size + 1; \ + break; \ + } \ +} + +int +base64_decode(const char * src, size_t size, UtilBuffer &dst) { size_t i = 0; - const char *s = src.c_str(); - while(i < size) { - int c = 0; + while(i < size){ + unsigned c = 0; int mark = 0; - c += pos(*s++); + + SKIP_SPACE(src, i, size); + + c += pos(*src++); c <<= 6; i++; - c += pos(*s++); + SKIP_SPACE(src, i, size); + + c += pos(*src++); c <<= 6; i++; - if(*s != '=') - c += pos(*s++); + SKIP_SPACE(src, i, size); + + if(* src != '=') + c += pos(*src++); else { - size--; - mark++; + i = size; + mark = 2; + c <<= 6; + goto end; } c <<= 6; i++; - if(*s != '=') - c += pos(*s++); + SKIP_SPACE(src, i, size); + + if(*src != '=') + c += pos(*src++); else { - size--; - mark++; + i = size; + mark = 1; + goto end; } - /* c <<= 6; */ i++; + end: char b[3]; - - b[0] = (c >> 16) & 0xff; b[1] = (c >> 8) & 0xff; b[2] = (c >> 0) & 0xff; - + dst.append((void *)b, 3-mark); } + + if(i != size){ + abort(); + return -1; + } return 0; } + +#ifdef __TEST__B64 +/** + * USER_FLAGS="-D__TEST__B64" make Base64.o && g++ Base64.o BaseString.o + */ +inline +void +require(bool b){ + if(!b) + abort(); +} + +int +main(void){ + for(int i = 0; i < 500; i++){ + const size_t len = rand() % 10000 + 1; + UtilBuffer src; + for(size_t j = 0; j<len; j++){ + char c = rand(); + src.append(&c, 1); + } + require(src.length() == len); + + BaseString str; + require(base64_encode(src, str) == 0); + + if(str.length() == 3850){ + printf(">%s<\n", str.c_str()); + } + + UtilBuffer dst; + require(base64_decode(str, dst) == 0); + require(dst.length() == src.length()); + + const char * c_src = (char*)src.get_data(); + const char * c_dst = (char*)dst.get_data(); + if(memcmp(src.get_data(), dst.get_data(), src.length()) != 0){ + printf("-- src --\n"); + for(int i2 = 0; i2<len; i2++){ + unsigned char c = c_src[i2]; + printf("%.2x ", (unsigned)c); + if((i2 % 8) == 7) + printf("\n"); + } + printf("\n"); + + printf("-- dst --\n"); + for(int i2 = 0; i2<len; i2++){ + unsigned char c = c_dst[i2]; + printf("%.2x ", (unsigned)c); + if((i2 % 8) == 7) + printf("\n"); + } + printf("\n"); + abort(); + } + } + return 0; +} + +#endif diff --git a/ndb/src/common/util/ConfigValues.cpp b/ndb/src/common/util/ConfigValues.cpp new file mode 100644 index 00000000000..6c07f25931d --- /dev/null +++ b/ndb/src/common/util/ConfigValues.cpp @@ -0,0 +1,743 @@ +#include <ConfigValues.hpp> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <new> +#include <NdbOut.hpp> +#include <NdbTCP.h> + +static Uint32 hash(Uint32 key, Uint32 size); +static Uint32 nextHash(Uint32 key, Uint32 size, Uint32 pos, Uint32 count); +static bool findKey(const Uint32 * vals, Uint32 sz, Uint32 key, Uint32 * pos); + +/** + * Key + * + * t = Type - 4 bits 0-15 + * s = Section - 14 bits 0-16383 + * k = Key value - 14 bits 0-16383 + * + * 1111111111222222222233 + * 01234567890123456789012345678901 + * kkkkkkkkkkkkkkssssssssssssssoooo + */ +#define KP_TYPE_MASK (15) +#define KP_TYPE_SHIFT (28) +#define KP_SECTION_MASK (0x3FFF) +#define KP_SECTION_SHIFT (14) +#define KP_KEYVAL_MASK (0x3FFF) +#define KP_KEYVAL_SHIFT (0) +#define KP_MASK (0x0FFFFFFF) + +static const Uint32 CFV_KEY_PARENT = (KP_KEYVAL_MASK - 1); +static const Uint32 CFV_KEY_FREE = ~0; + +static const char Magic[] = { 'N', 'D', 'B', 'C', 'O', 'N', 'F', 'V' }; + +//#define DEBUG_CV +#ifdef DEBUG_CV +#define DEBUG +#else +#define DEBUG if(0) +#endif + +inline +ConfigValues::ValueType +getTypeOf(Uint32 k) { + return (ConfigValues::ValueType)((k >> KP_TYPE_SHIFT) & KP_TYPE_MASK); +} + +ConfigValues::ConfigValues(Uint32 sz, Uint32 dsz){ + m_size = sz; + m_dataSize = dsz; + m_stringCount = 0; + m_int64Count = 0; + for(Uint32 i = 0; i<m_size; i++){ + m_values[i << 1] = CFV_KEY_FREE; + } +} + +ConfigValues::~ConfigValues(){ + for(Uint32 i = 0; i<m_stringCount; i++){ + free(getString(i)); + } +} + +bool +ConfigValues::ConstIterator::get(Uint32 key, Entry * result) const { + Uint32 pos; + if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){ + return false; + } + + result->m_key = key; + return m_cfg.getByPos(pos, result); +} + +bool +ConfigValues::getByPos(Uint32 pos, Entry * result) const { + assert(pos < (2 * m_size)); + Uint32 keypart = m_values[pos]; + Uint32 val = m_values[pos+1]; + + switch(::getTypeOf(keypart)){ + case IntType: + case SectionType: + result->m_int = val; + break; + case StringType: + result->m_string = getString(val); + break; + case Int64Type: + result->m_int64 = get64(val); + break; + case InvalidType: + default: + return false; + } + + result->m_type = ::getTypeOf(keypart); + + return true; +} + +Uint64 & +ConfigValues::get64(Uint32 index) const { + assert(index < m_int64Count); + Uint64 * ptr = (Uint64*)(&m_values[m_size << 1]); + return ptr[index]; +} + +char * & +ConfigValues::getString(Uint32 index) const { + assert(index < m_stringCount); + char ** ptr = (char**)(((char *)&(m_values[m_size << 1])) + m_dataSize); + return ptr[-index]; +} + +bool +ConfigValues::ConstIterator::openSection(Uint32 key, Uint32 no){ + Uint32 curr = m_currentSection; + + Entry tmp; + if(get(key, &tmp) && tmp.m_type == SectionType){ + m_currentSection = tmp.m_int; + if(get(no, &tmp) && tmp.m_type == IntType){ + m_currentSection = tmp.m_int; + /** + * Validate + */ + if(get(CFV_KEY_PARENT, &tmp)){ + return true; + } + } + } + + m_currentSection = curr; + return false; +} + +bool +ConfigValues::ConstIterator::closeSection() { + + Entry tmp; + if(get(CFV_KEY_PARENT, &tmp) && tmp.m_type == IntType){ + m_currentSection = tmp.m_int; + return true; + } + + return false; +} + +bool +ConfigValues::Iterator::set(Uint32 key, Uint32 value){ + Uint32 pos; + if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){ + return false; + } + + if(::getTypeOf(m_cfg.m_values[pos]) != IntType){ + return false; + } + + m_cfg.m_values[pos+1] = value; + return true; +} + +bool +ConfigValues::Iterator::set(Uint32 key, Uint64 value){ + Uint32 pos; + if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){ + return false; + } + + if(::getTypeOf(m_cfg.m_values[pos]) != Int64Type){ + return false; + } + + m_cfg.get64(m_cfg.m_values[pos+1]) = value; + return true; +} + +bool +ConfigValues::Iterator::set(Uint32 key, const char * value){ + Uint32 pos; + if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){ + return false; + } + + if(::getTypeOf(m_cfg.m_values[pos]) != StringType){ + return false; + } + + char * & str = m_cfg.getString(m_cfg.m_values[pos+1]); + free(str); + str = strdup(value); + return true; +} + +static +bool +findKey(const Uint32 * values, Uint32 sz, Uint32 key, Uint32 * _pos){ + Uint32 pos = hash(key, sz); + Uint32 count = 0; + while((values[pos] & KP_MASK) != key && count < sz){ + pos = nextHash(key, sz, pos, ++count); + } + + if((values[pos] & KP_MASK)== key){ + *_pos = pos; + return true; + } + return false; +} + +static +Uint32 +hash(Uint32 key, Uint32 size){ + Uint32 tmp = (key >> 16) ^ (key & 0xFFFF); + return (((tmp << 16) | tmp) % size) << 1; +} + +static +Uint32 +nextHash(Uint32 key, Uint32 size, Uint32 pos, Uint32 count){ + Uint32 p = (pos >> 1); + if((key % size) != 0) + p += key; + else + p += 1; + return (p % size) << 1; +} + +static +Uint32 +directory(Uint32 sz){ + const Uint32 _input = sz; + if((sz & 1) == 0) + sz ++; + + bool prime = false; + while(!prime){ + prime = true; + for(Uint32 n = 3; n*n <= sz; n += 2){ + if((sz % n) == 0){ + prime = false; + sz += 2; + break; + } + } + } + DEBUG printf("directory %d -> %d\n", _input, sz); + return sz; +} + +ConfigValuesFactory::ConfigValuesFactory(Uint32 keys, Uint32 data){ + m_sectionCounter = (1 << KP_SECTION_SHIFT); + m_freeKeys = directory(keys); + m_freeData = data; + m_currentSection = 0; + m_cfg = create(m_freeKeys, data); +} + +ConfigValuesFactory::ConfigValuesFactory(ConfigValues * cfg){ + m_cfg = cfg; + m_freeKeys = 0; + m_freeData = m_cfg->m_dataSize; + m_sectionCounter = (1 << KP_SECTION_SHIFT); + m_currentSection = 0; + const Uint32 sz = 2 * m_cfg->m_size; + for(Uint32 i = 0; i<sz; i += 2){ + const Uint32 key = m_cfg->m_values[i]; + if(key == CFV_KEY_FREE){ + m_freeKeys++; + } else { + switch(::getTypeOf(key)){ + case ConfigValues::IntType: + case ConfigValues::SectionType: + break; + case ConfigValues::Int64Type: + m_freeData -= sizeof(Uint64); + break; + case ConfigValues::StringType: + m_freeData -= sizeof(char *); + break; + case ConfigValues::InvalidType: + abort(); + } + Uint32 sec = key & (KP_SECTION_MASK << KP_SECTION_SHIFT); + m_sectionCounter = (sec > m_sectionCounter ? sec : m_sectionCounter); + } + } +} + +ConfigValues * +ConfigValuesFactory::create(Uint32 keys, Uint32 data){ + Uint32 sz = sizeof(ConfigValues); + sz += (2 * keys * sizeof(Uint32)); + sz += data; + + void * tmp = malloc(sz); + return new (tmp) ConfigValues(keys, data); +} + +void +ConfigValuesFactory::expand(Uint32 fk, Uint32 fs){ + if(m_freeKeys >= fk && m_freeData >= fs){ + return ; + } + + m_freeKeys = (m_freeKeys >= fk ? m_cfg->m_size : fk + m_cfg->m_size); + m_freeData = (m_freeData >= fs ? m_cfg->m_dataSize : fs + m_cfg->m_dataSize); + m_freeKeys = directory(m_freeKeys); + + ConfigValues * m_tmp = m_cfg; + m_cfg = create(m_freeKeys, m_freeData); + put(* m_tmp); + m_tmp->~ConfigValues(); + free(m_tmp); +} + +void +ConfigValuesFactory::shrink(){ + if(m_freeKeys == 0 && m_freeData == 0){ + return ; + } + + m_freeKeys = m_cfg->m_size - m_freeKeys; + m_freeData = m_cfg->m_dataSize - m_freeData; + m_freeKeys = directory(m_freeKeys); + + ConfigValues * m_tmp = m_cfg; + m_cfg = create(m_freeKeys, m_freeData); + put(* m_tmp); + m_tmp->~ConfigValues(); + free(m_tmp); +} + +bool +ConfigValuesFactory::openSection(Uint32 key, Uint32 no){ + ConfigValues::Entry tmp; + const Uint32 parent = m_currentSection; + + ConfigValues::ConstIterator iter(* m_cfg); + iter.m_currentSection = m_currentSection; + if(!iter.get(key, &tmp)){ + + tmp.m_key = key; + tmp.m_type = ConfigValues::SectionType; + tmp.m_int = m_sectionCounter; + m_sectionCounter += (1 << KP_SECTION_SHIFT); + + if(!put(tmp)){ + return false; + } + } + + if(tmp.m_type != ConfigValues::SectionType){ + return false; + } + + m_currentSection = tmp.m_int; + + tmp.m_key = no; + tmp.m_type = ConfigValues::IntType; + tmp.m_int = m_sectionCounter; + if(!put(tmp)){ + m_currentSection = parent; + return false; + } + m_sectionCounter += (1 << KP_SECTION_SHIFT); + + m_currentSection = tmp.m_int; + tmp.m_type = ConfigValues::IntType; + tmp.m_key = CFV_KEY_PARENT; + tmp.m_int = parent; + if(!put(tmp)){ + m_currentSection = parent; + return false; + } + + return true; +} + +bool +ConfigValuesFactory::closeSection(){ + ConfigValues::ConstIterator iter(* m_cfg); + iter.m_currentSection = m_currentSection; + const bool b = iter.closeSection(); + m_currentSection = iter.m_currentSection; + return b; +} + +bool +ConfigValuesFactory::put(const ConfigValues::Entry & entry){ + + if(m_freeKeys == 0 || + (entry.m_type == ConfigValues::StringType && m_freeData < sizeof(char *)) + || (entry.m_type == ConfigValues::Int64Type && m_freeData < 8 )){ + + DEBUG ndbout_c("m_freeKeys = %d, m_freeData = %d -> expand", + m_freeKeys, m_freeData); + + expand(31, 20); + } + + const Uint32 tmp = entry.m_key | m_currentSection; + const Uint32 sz = m_cfg->m_size; + Uint32 pos = hash(tmp, sz); + Uint32 count = 0; + Uint32 val = m_cfg->m_values[pos]; + + while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){ + pos = nextHash(tmp, sz, pos, ++count); + val = m_cfg->m_values[pos]; + } + + if((val & KP_MASK) == tmp){ + DEBUG ndbout_c("key %x already found at pos: %d", tmp, pos); + return false; + } + + if(count >= sz){ + pos = hash(tmp, sz); + count = 0; + Uint32 val = m_cfg->m_values[pos]; + + printf("key: %d, (key %% size): %d\n", entry.m_key, (entry.m_key % sz)); + printf("pos: %d", pos); + while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){ + pos = nextHash(tmp, sz, pos, ++count); + val = m_cfg->m_values[pos]; + printf(" %d", pos); + } + printf("\n"); + + abort(); + printf("Full\n"); + return false; + } + + assert(pos < (sz << 1)); + + Uint32 key = tmp; + key |= (entry.m_type << KP_TYPE_SHIFT); + m_cfg->m_values[pos] = key; + switch(entry.m_type){ + case ConfigValues::IntType: + case ConfigValues::SectionType: + m_cfg->m_values[pos+1] = entry.m_int; + m_freeKeys--; + DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value: %d\n", + pos, sz, count, + (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK, + entry.m_int); + return true; + case ConfigValues::StringType:{ + Uint32 index = m_cfg->m_stringCount++; + m_cfg->m_values[pos+1] = index; + m_cfg->getString(index) = strdup(entry.m_string); + m_freeKeys--; + m_freeData -= sizeof(char *); + DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value(%d): %s\n", + pos, sz, count, + (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK, + index, + entry.m_string); + return true; + } + case ConfigValues::Int64Type:{ + Uint32 index = m_cfg->m_int64Count++; + m_cfg->m_values[pos+1] = index; + m_cfg->get64(index) = entry.m_int64; + m_freeKeys--; + m_freeData -= 8; + DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value64(%d): %lld\n", + pos, sz, count, + (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK, + index, + entry.m_int64); + return true; + } + case ConfigValues::InvalidType: + default: + return false; + } + return false; +} + +void +ConfigValuesFactory::put(const ConfigValues & cfg){ + + Uint32 curr = m_currentSection; + m_currentSection = 0; + + ConfigValues::Entry tmp; + for(Uint32 i = 0; i < 2 * cfg.m_size; i += 2){ + if(cfg.m_values[i] != CFV_KEY_FREE){ + tmp.m_key = cfg.m_values[i]; + cfg.getByPos(i, &tmp); + put(tmp); + } + } + + m_currentSection = curr; +} + +ConfigValues * +ConfigValuesFactory::extractCurrentSection(const ConfigValues::ConstIterator & cfg){ + ConfigValuesFactory * fac = new ConfigValuesFactory(20, 20); + Uint32 curr = cfg.m_currentSection; + + ConfigValues::Entry tmp; + for(Uint32 i = 0; i < 2 * cfg.m_cfg.m_size; i += 2){ + Uint32 keypart = cfg.m_cfg.m_values[i]; + const Uint32 sec = keypart & (KP_SECTION_MASK << KP_SECTION_SHIFT); + const Uint32 key = keypart & KP_KEYVAL_MASK; + if(sec == curr && key != CFV_KEY_PARENT){ + tmp.m_key = cfg.m_cfg.m_values[i]; + cfg.m_cfg.getByPos(i, &tmp); + tmp.m_key = key; + fac->put(tmp); + } + } + + ConfigValues * ret = fac->m_cfg; + delete fac; + return ret; +} + +ConfigValues * +ConfigValuesFactory::getConfigValues(){ + ConfigValues * ret = m_cfg; + m_cfg = create(10, 10); + return ret; +} + +static int +mod4(unsigned int i){ + int res = i + (4 - (i % 4)); + return res; +} + +Uint32 +ConfigValues::getPackedSize() const { + + Uint32 size = 0; + for(Uint32 i = 0; i < 2 * m_size; i += 2){ + Uint32 key = m_values[i]; + if(key != CFV_KEY_FREE){ + switch(::getTypeOf(key)){ + case IntType: + case SectionType: + size += 8; + break; + case Int64Type: + size += 12; + break; + case StringType: + size += 8; // key + len + size += mod4(strlen(getString(m_values[i+1])) + 1); + break; + case InvalidType: + default: + abort(); + } + } + } + + return size + sizeof(Magic) + 4; // checksum also +} + +Uint32 +ConfigValues::pack(void * _dst, Uint32 _len) const { + + char * dst = (char*)_dst; + memcpy(dst, Magic, sizeof(Magic)); dst += sizeof(Magic); + + for(Uint32 i = 0; i < 2 * m_size; i += 2){ + Uint32 key = m_values[i]; + Uint32 val = m_values[i+1]; + if(key != CFV_KEY_FREE){ + switch(::getTypeOf(key)){ + case IntType: + case SectionType: + * (Uint32*)dst = htonl(key); dst += 4; + * (Uint32*)dst = htonl(val); dst += 4; + break; + case Int64Type:{ + Uint64 i64 = get64(val); + Uint32 hi = (i64 >> 32); + Uint32 lo = (i64 & 0xFFFFFFFF); + * (Uint32*)dst = htonl(key); dst += 4; + * (Uint32*)dst = htonl(hi); dst += 4; + * (Uint32*)dst = htonl(lo); dst += 4; + } + break; + case StringType:{ + const char * str = getString(val); + Uint32 len = strlen(str) + 1; + * (Uint32*)dst = htonl(key); dst += 4; + * (Uint32*)dst = htonl(len); dst += 4; + memcpy(dst, str, len); + memset(dst+len, 0, mod4(len) - len); + dst += mod4(len); + } + break; + case InvalidType: + default: + abort(); + } + } + } + + const Uint32 * sum = (Uint32*)_dst; + const Uint32 len = ((Uint32*)dst) - sum; + Uint32 chk = 0; + for(Uint32 i = 0; i<len; i++){ + chk ^= htonl(sum[i]); + } + + * (Uint32*)dst = htonl(chk); dst += 4; + return 4 * (len + 1); +} + +bool +ConfigValuesFactory::unpack(const void * _src, Uint32 len){ + + if(len < sizeof(Magic) + 4){ + DEBUG abort(); + return false; + } + + if(memcmp(_src, Magic, sizeof(Magic)) != 0){ + DEBUG abort(); + return false; + } + + const char * src = (const char *)_src; + + { + Uint32 len32 = (len >> 2); + const Uint32 * tmp = (const Uint32*)_src; + Uint32 chk = 0; + for(Uint32 i = 0; (i+1)<len32; i++){ + chk ^= ntohl(tmp[i]); + } + + if(chk != ntohl(tmp[len32-1])){ + DEBUG abort(); + return false; + } + } + + const char * end = src + len - 4; + src += sizeof(Magic); + + ConfigValues::Entry entry; + while(end - src > 4){ + Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4; + entry.m_key = tmp & KP_MASK; + entry.m_type = ::getTypeOf(tmp); + switch(entry.m_type){ + case ConfigValues::IntType: + case ConfigValues::SectionType: + entry.m_int = ntohl(* (const Uint32 *)src); src += 4; + break; + case ConfigValues::Int64Type:{ + Uint64 hi = ntohl(* (const Uint32 *)src); src += 4; + Uint64 lo = ntohl(* (const Uint32 *)src); src += 4; + entry.m_int64 = (hi <<32) | lo; + } + break; + case ConfigValues::StringType:{ + Uint32 s_len = ntohl(* (const Uint32 *)src); src += 4; + size_t s_len2 = strnlen((const char*)src, s_len); + if(s_len2 + 1 != s_len){ + DEBUG abort(); + return false; + } + + entry.m_string = (const char*)src; src+= mod4(s_len); + } + break; + case ConfigValues::InvalidType: + default: + DEBUG abort(); + return false; + } + if(!put(entry)){ + DEBUG abort(); + return false; + } + } + if(src != end){ + DEBUG abort(); + return false; + } + return true; +} + +#ifdef __TEST_CV_HASH_HPP + +int +main(void){ + srand(time(0)); + for(int t = 0; t<100; t++){ + const size_t len = directory(rand() % 1000); + + printf("size = %d\n", len); + unsigned * buf = new unsigned[len]; + for(size_t key = 0; key<len; key++){ + Uint32 p = hash(key, len); + for(size_t j = 0; j<len; j++){ + buf[j] = p; + p = nextHash(key, len, p, j+1); + } + + for(size_t j = 0; j<len; j++){ + Uint32 pos = buf[j]; + int unique = 0; + for(size_t k = j + 1; k<len; k++){ + if(pos == buf[k]){ + if(unique > 0) + printf("size=%d key=%d pos(%d)=%d buf[%d]=%d\n", len, key, j, pos, k, buf[k]); + unique ++; + } + } + if(unique > 1){ + printf("key = %d size = %d not uniqe!!\n", key, len); + for(size_t k = 0; k<len; k++){ + printf("%d ", buf[k]); + } + printf("\n"); + } + } + } + delete[] buf; + } + return 0; +} + +#endif diff --git a/ndb/src/common/util/Makefile_old b/ndb/src/common/util/Makefile_old index e8ca2b87c20..65093396246 100644 --- a/ndb/src/common/util/Makefile_old +++ b/ndb/src/common/util/Makefile_old @@ -8,7 +8,7 @@ ARCHIVE_TARGET := general SOURCES = File.cpp md5_hash.cpp Properties.cpp socket_io.cpp \ SimpleProperties.cpp Parser.cpp InputStream.cpp SocketServer.cpp \ OutputStream.cpp NdbOut.cpp BaseString.cpp Base64.cpp \ - NdbSqlUtil.cpp new.cpp + NdbSqlUtil.cpp ConfigValues.cpp new.cpp SOURCES.c = uucode.c random.c getarg.c version.c @@ -20,7 +20,7 @@ ifeq ($(NDB_OS), OSE) endif SOURCES.c += strdup.c strlcat.c strlcpy.c -DIRS := testSimpleProperties +DIRS := testSimpleProperties testProperties testConfigValues include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/util/Properties.cpp b/ndb/src/common/util/Properties.cpp index 2ab008142ba..3e41056ac18 100644 --- a/ndb/src/common/util/Properties.cpp +++ b/ndb/src/common/util/Properties.cpp @@ -21,6 +21,12 @@ #include <NdbTCP.h> #include <NdbOut.hpp> +static +char * f_strdup(const char * s){ + if(!s) return 0; + return strdup(s); +} + /** * Note has to be a multiple of 4 bytes */ @@ -36,6 +42,7 @@ struct PropertyImpl{ ~PropertyImpl(); PropertyImpl(const char * name, Uint32 value); + PropertyImpl(const char * name, Uint64 value); PropertyImpl(const char * name, const char * value); PropertyImpl(const char * name, const Properties * value); @@ -167,6 +174,11 @@ Properties::put(const char * name, Uint32 value, bool replace){ return ::put(impl, name, value, replace); } +bool +Properties::put64(const char * name, Uint64 value, bool replace){ + return ::put(impl, name, value, replace); +} + bool Properties::put(const char * name, const char * value, bool replace){ return ::put(impl, name, value, replace); @@ -208,6 +220,40 @@ Properties::get(const char * name, Uint32 * value) const { setErrno(E_PROPERTIES_OK); return true; } + + if(nvp->valueType == PropertiesType_Uint64){ + Uint64 tmp = * (Uint64 *)nvp->value; + Uint64 max = 1; max <<= 32; + if(tmp < max){ + * value = (Uint32)tmp; + setErrno(E_PROPERTIES_OK); + return true; + } + } + setErrno(E_PROPERTIES_INVALID_TYPE); + return false; +} + +bool +Properties::get(const char * name, Uint64 * value) const { + PropertyImpl * nvp = impl->get(name); + if(nvp == 0){ + setErrno(E_PROPERTIES_NO_SUCH_ELEMENT); + return false; + } + + if(nvp->valueType == PropertiesType_Uint32){ + Uint32 tmp = * (Uint32 *)nvp->value; + * value = (Uint64)tmp; + setErrno(E_PROPERTIES_OK); + return true; + } + + if(nvp->valueType == PropertiesType_Uint64){ + * value = * (Uint64 *)nvp->value; + setErrno(E_PROPERTIES_OK); + return true; + } setErrno(E_PROPERTIES_INVALID_TYPE); return false; } @@ -263,7 +309,7 @@ Properties::getCopy(const char * name, char ** value) const { } if(nvp->valueType == PropertiesType_char){ - * value = strdup((const char *)nvp->value); + * value = f_strdup((const char *)nvp->value); setErrno(E_PROPERTIES_OK); return true; } @@ -313,6 +359,10 @@ Properties::print(FILE * out, const char * prefix) const{ fprintf(out, "%s%s = (Uint32) %d\n", buf, impl->content[i]->name, *(Uint32 *)impl->content[i]->value); break; + case PropertiesType_Uint64: + fprintf(out, "%s%s = (Uint64) %lld\n", buf, impl->content[i]->name, + *(Uint64 *)impl->content[i]->value); + break; case PropertiesType_char: fprintf(out, "%s%s = (char*) \"%s\"\n", buf, impl->content[i]->name, (char *)impl->content[i]->value); @@ -598,11 +648,18 @@ PropertiesImpl::getPackedSize(Uint32 pLen) const { sz += 4; // Name Len sz += 4; // Value Len sz += mod4(pLen + strlen(content[i]->name)); // Name - if(content[i]->valueType == PropertiesType_char){ + switch(content[i]->valueType){ + case PropertiesType_char: sz += mod4(strlen((char *)content[i]->value)); - } else if(content[i]->valueType == PropertiesType_Uint32){ + break; + case PropertiesType_Uint32: sz += mod4(4); - } else { + break; + case PropertiesType_Uint64: + sz += mod4(8); + break; + case PropertiesType_Properties: + default: assert(0); } } @@ -700,6 +757,9 @@ PropertiesImpl::pack(Uint32 *& buf, const char * prefix, Uint32 pLen) const { case PropertiesType_Uint32: valLenData = 4; break; + case PropertiesType_Uint64: + valLenData = 8; + break; case PropertiesType_char: valLenData = strlen((char *)content[i]->value); break; @@ -722,6 +782,14 @@ PropertiesImpl::pack(Uint32 *& buf, const char * prefix, Uint32 pLen) const { case PropertiesType_Uint32: * (Uint32 *)valBuf = htonl(* (Uint32 *)content[i]->value); break; + case PropertiesType_Uint64:{ + Uint64 val = * (Uint64 *)content[i]->value; + Uint32 hi = (val >> 32); + Uint32 lo = (val & 0xFFFFFFFF); + * (Uint32 *)valBuf = htonl(hi); + * (Uint32 *)(valBuf + 4) = htonl(lo); + } + break; case PropertiesType_char: memcpy(valBuf, content[i]->value, strlen((char*)content[i]->value)); break; @@ -788,6 +856,12 @@ PropertiesImpl::unpack(const Uint32 * buf, Uint32 &bufLen, Properties * top, case PropertiesType_Uint32: res3 = top->put(nameBuf, ntohl(* (Uint32 *)valBuf), true); break; + case PropertiesType_Uint64:{ + Uint64 hi = ntohl(* (Uint32 *)valBuf); + Uint64 lo = ntohl(* (Uint32 *)(valBuf + 4)); + res3 = top->put64(nameBuf, (hi << 32) + lo, true); + } + break; case PropertiesType_char: res3 = top->put(nameBuf, valBuf, true); break; @@ -808,6 +882,9 @@ PropertyImpl::~PropertyImpl(){ case PropertiesType_Uint32: delete (Uint32 *)value; break; + case PropertiesType_Uint64: + delete (Uint64 *)value; + break; case PropertiesType_char: free((char *)value); break; @@ -822,6 +899,8 @@ PropertyImpl::copyPropertyImpl(const PropertyImpl & org){ switch(org.valueType){ case PropertiesType_Uint32: return new PropertyImpl(org.name, * (Uint32 *)org.value); + case PropertiesType_Uint64: + return new PropertyImpl(org.name, * (Uint64 *)org.value); break; case PropertiesType_char: return new PropertyImpl(org.name, (char *)org.value); @@ -836,21 +915,28 @@ PropertyImpl::copyPropertyImpl(const PropertyImpl & org){ } PropertyImpl::PropertyImpl(const char * _name, Uint32 _value){ - this->name = strdup(_name); + this->name = f_strdup(_name); this->value = new Uint32; * ((Uint32 *)this->value) = _value; this->valueType = PropertiesType_Uint32; } +PropertyImpl::PropertyImpl(const char * _name, Uint64 _value){ + this->name = f_strdup(_name); + this->value = new Uint64; + * ((Uint64 *)this->value) = _value; + this->valueType = PropertiesType_Uint64; +} + PropertyImpl::PropertyImpl(const char * _name, const char * _value){ - this->name = strdup(_name); - this->value = strdup(_value); + this->name = f_strdup(_name); + this->value = f_strdup(_value); this->valueType = PropertiesType_char; } PropertyImpl::PropertyImpl(const char * _name, const Properties * _value){ - this->name = strdup(_name); + this->name = f_strdup(_name); this->value = new Properties(* _value); this->valueType = PropertiesType_Properties; } @@ -902,6 +988,16 @@ Properties::put(const char * name, Uint32 no, Uint32 val, bool replace){ return res; } +bool +Properties::put64(const char * name, Uint32 no, Uint64 val, bool replace){ + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = put(tmp, val, replace); + free(tmp); + return res; +} + bool Properties::put(const char * name, Uint32 no, const char * val, bool replace){ @@ -957,6 +1053,16 @@ Properties::get(const char * name, Uint32 no, Uint32 * value) const{ return res; } +bool +Properties::get(const char * name, Uint32 no, Uint64 * value) const{ + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = get(tmp, value); + free(tmp); + return res; +} + bool Properties::get(const char * name, Uint32 no, const char ** value) const { diff --git a/ndb/src/common/util/socket_io.cpp b/ndb/src/common/util/socket_io.cpp index 8def7ebe91b..97bb4863a67 100644 --- a/ndb/src/common/util/socket_io.cpp +++ b/ndb/src/common/util/socket_io.cpp @@ -202,13 +202,13 @@ vprintln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, size_t size = sizeof(buf); if (fmt != 0) { - size = vsnprintf(buf, sizeof(buf)-1, fmt, ap); + size = vsnprintf(buf, sizeof(buf), fmt, ap); /* Check if the output was truncated */ - if(size >= sizeof(buf)) { + if(size >= sizeof(buf)-1) { buf2 = (char *)malloc(size+2); if(buf2 == NULL) return -1; - vsnprintf(buf2, size, fmt, ap); + vsnprintf(buf2, size+1, fmt, ap); } else size = sizeof(buf); } else diff --git a/ndb/src/common/util/testConfigValues/Makefile b/ndb/src/common/util/testConfigValues/Makefile new file mode 100644 index 00000000000..5b7400f5ee3 --- /dev/null +++ b/ndb/src/common/util/testConfigValues/Makefile @@ -0,0 +1,12 @@ +include .defs.mk + +TYPE := util + +BIN_TARGET := testConfigValues +BIN_TARGET_ARCHIVES := portlib general + +SOURCES := testConfigValues.cpp + +CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/util) + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/util/testConfigValues/testConfigValues.cpp b/ndb/src/common/util/testConfigValues/testConfigValues.cpp new file mode 100644 index 00000000000..362deb1ddad --- /dev/null +++ b/ndb/src/common/util/testConfigValues/testConfigValues.cpp @@ -0,0 +1,122 @@ +#include <ConfigValues.hpp> +#include <NdbOut.hpp> +#include <stdlib.h> +#include <string.h> + +#define CF_NODES 1 +#define CF_LOG_PAGES 2 +#define CF_MEM_PAGES 3 +#define CF_START_TO 4 +#define CF_STOP_TO 5 + +void print(Uint32 i, ConfigValues::ConstIterator & cf){ + ndbout_c("---"); + for(Uint32 j = 2; j<=7; j++){ + switch(cf.getTypeOf(j)){ + case ConfigValues::IntType: + ndbout_c("Node %d : CFG(%d) : %d", + i, j, cf.get(j, 999)); + break; + case ConfigValues::Int64Type: + ndbout_c("Node %d : CFG(%d) : %lld (64)", + i, j, cf.get64(j, 999)); + break; + case ConfigValues::StringType: + ndbout_c("Node %d : CFG(%d) : %s", + i, j, cf.get(j, "<NOT FOUND>")); + break; + default: + ndbout_c("Node %d : CFG(%d) : TYPE: %d", + i, j, cf.getTypeOf(j)); + } + } +} + +void print(Uint32 i, ConfigValues & _cf){ + ConfigValues::ConstIterator cf(_cf); + print(i, cf); +} + +void +print(ConfigValues & _cf){ + ConfigValues::ConstIterator cf(_cf); + Uint32 i = 0; + while(cf.openSection(CF_NODES, i)){ + print(i, cf); + cf.closeSection(); + i++; + } +} + +inline +void +require(bool b){ + if(!b) + abort(); +} + +int +main(void){ + + { + ConfigValuesFactory cvf(10, 20); + cvf.openSection(1, 0); + cvf.put(2, 12); + cvf.put64(3, 13); + cvf.put(4, 14); + cvf.put64(5, 15); + cvf.put(6, "Keso"); + cvf.put(7, "Kent"); + cvf.closeSection(); + + cvf.openSection(1, 1); + cvf.put(2, 22); + cvf.put64(3, 23); + cvf.put(4, 24); + cvf.put64(5, 25); + cvf.put(6, "Kalle"); + cvf.put(7, "Anka"); + cvf.closeSection(); + + ndbout_c("-- print --"); + print(* cvf.m_cfg); + + cvf.shrink(); + ndbout_c("shrink\n-- print --"); + print(* cvf.m_cfg); + cvf.expand(10, 10); + ndbout_c("expand\n-- print --"); + print(* cvf.m_cfg); + + ndbout_c("packed size: %d", cvf.m_cfg->getPackedSize()); + + ConfigValues::ConstIterator iter(* cvf.m_cfg); + iter.openSection(CF_NODES, 0); + ConfigValues * cfg2 = ConfigValuesFactory::extractCurrentSection(iter); + print(99, * cfg2); + + cvf.shrink(); + ndbout_c("packed size: %d", cfg2->getPackedSize()); + + UtilBuffer buf; + Uint32 l1 = cvf.m_cfg->pack(buf); + Uint32 l2 = cvf.m_cfg->getPackedSize(); + require(l1 == l2); + + ConfigValuesFactory cvf2; + require(cvf2.unpack(buf)); + UtilBuffer buf2; + cvf2.shrink(); + Uint32 l3 = cvf2.m_cfg->pack(buf2); + require(l1 == l3); + + ndbout_c("unpack\n-- print --"); + print(* cvf2.m_cfg); + + cfg2->~ConfigValues();; + cvf.m_cfg->~ConfigValues(); + free(cfg2); + free(cvf.m_cfg); + } + return 0; +} diff --git a/ndb/src/common/util/testProperties/Makefile b/ndb/src/common/util/testProperties/Makefile index 00b4465b69d..343c07a49e7 100644 --- a/ndb/src/common/util/testProperties/Makefile +++ b/ndb/src/common/util/testProperties/Makefile @@ -1,12 +1,9 @@ include .defs.mk -TYPE := +TYPE := util BIN_TARGET := keso -BIN_TARGET_ARCHIVES := portlib general SOURCES := testProperties.cpp -CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/util) - include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/util/testProperties/testProperties.cpp b/ndb/src/common/util/testProperties/testProperties.cpp index 3aa2af92c5b..e445f7ca3e4 100644 --- a/ndb/src/common/util/testProperties/testProperties.cpp +++ b/ndb/src/common/util/testProperties/testProperties.cpp @@ -63,12 +63,6 @@ readFromFile(Properties & p, const char *fname, bool uu = true){ return res; } -Property defs[] = { - Property("Rolf", 123) - ,Property("Keso", "Kent") -}; - - void putALot(Properties & tmp){ int i = 123; tmp.put("LockPagesInMainMemory", i++); @@ -124,7 +118,6 @@ main(void){ p.put("Ank4", "anka"); putALot(p); - //p.put(defs, 2); Properties tmp; tmp.put("Type", "TCP"); tmp.put("OwnNodeId", 1); @@ -136,8 +129,8 @@ main(void){ tmp.put("Compression", (Uint32)false); tmp.put("Checksum", 1); - tmp.put("SendBufferSize", 2000); - tmp.put("MaxReceiveSize", 1000); + tmp.put64("SendBufferSize", 2000); + tmp.put64("MaxReceiveSize", 1000); tmp.put("PortNumber", 1233); putALot(tmp); diff --git a/ndb/src/kernel/Makefile_old b/ndb/src/kernel/Makefile_old index 11261c047a6..d1f1741aca4 100644 --- a/ndb/src/kernel/Makefile_old +++ b/ndb/src/kernel/Makefile_old @@ -1,5 +1,5 @@ include .defs.mk -DIRS := error blocks vm ndb-main +DIRS := error vm ndb-main blocks include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt index 331333c101e..92dbfd067f7 100644 --- a/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/ndb/src/kernel/blocks/ERROR_codes.txt @@ -4,7 +4,7 @@ Next NDBFS 2000 Next DBACC 3001 Next DBTUP 4007 Next DBLQH 5036 -Next DBDICT 6003 +Next DBDICT 6006 Next DBDIH 7173 Next DBTC 8035 Next CMVMI 9000 @@ -12,7 +12,6 @@ Next BACKUP 10022 Next DBUTIL 11002 Next DBTUX 12001 Next SUMA 13001 -Next DBDICT 14003 TESTING NODE FAILURE, ARBITRATION --------------------------------- @@ -425,6 +424,6 @@ Ordered index: Dbdict: ------- -14000 Crash in participant @ CreateTabReq::Prepare -14001 Crash in participant @ CreateTabReq::Commit -14002 Crash in participant @ CreateTabReq::CreateDrop +6003 Crash in participant @ CreateTabReq::Prepare +6004 Crash in participant @ CreateTabReq::Commit +6005 Crash in participant @ CreateTabReq::CreateDrop diff --git a/ndb/src/kernel/blocks/Start.txt b/ndb/src/kernel/blocks/Start.txt index 545296d44f1..3e805ebab55 100644 --- a/ndb/src/kernel/blocks/Start.txt +++ b/ndb/src/kernel/blocks/Start.txt @@ -60,8 +60,8 @@ Cluster participant - including info in DIH_RESTART_REF/CONF 4) Wait until - -a) Receiving CNTR_MASTER_CONF -> continue -b) Receiving CNTR_MASTER_REF -> P = node specified in REF, goto 3 +b) Receiving CNTR_START_CONF -> continue +b) Receiving CNTR_START_REF -> P = node specified in REF, goto 3 c) TimeToWaitAlive has passed -> Failure to start 4) Run ndb-startphase 1 @@ -70,18 +70,23 @@ c) TimeToWaitAlive has passed -> Failure to start Initial start/System restart NdbCntr (on qmgr president node) 1) Wait until - -a) Receiving all CNTR_MASTER_REQ (all = those in READ_NODES_CONF) -b) TimeToWaitAlive has passed -> Failure to start +a) Receiving CNTR_START_REQ with GCI > than own GCI + send CNTR_START_REF to all waiting nodes +b) Receiving all CNTR_START_REQ (for all defined nodes) +c) TimeToWait has passed and partition win +d) TimeToWait has passed and partitioning + and configuration "start with partition" = true -2) Wait until - -a) Enough nodes (at least 1 in each node group and 1 full node group) - has sent me CNTR_MASTER_REQ -b) TimeToWaitAlive has passed -> Failure to start +2) Send CNTR_START_CONF to all nodes "with filesystem" + +3) Wait until - + Receiving CNTR_START_REP for all starting nodes -3) Decide what kind of start to perform (initial / system restart) - Decide who should be the master (the one with greatest GCI) - Send CNTR_MASTER_CONF(initial/system restart) to all nodes included in start +4) Start waiting nodes (if any) +NOTE: +1c) Partition win = 1 node in each node group and 1 full node group +1d) Pattitioning = at least 1 node in each node group -- Running NdbCntr @@ -90,8 +95,3 @@ When receiving CNTR_MASTER_REQ 2) If I'm master Coordinate parallell node restarts send CNTR_MASTER_CONF (node restart) - -NOTE: -2a Specified with a command line/config parameter the system could - start using only one node in each node group (if possible w.r.t LCP/GCP) - diff --git a/ndb/src/kernel/blocks/backup/BackupInit.cpp b/ndb/src/kernel/blocks/backup/BackupInit.cpp index 1997e560bb9..36ce1857144 100644 --- a/ndb/src/kernel/blocks/backup/BackupInit.cpp +++ b/ndb/src/kernel/blocks/backup/BackupInit.cpp @@ -38,14 +38,14 @@ Backup::Backup(const Configuration & conf) : c_nodePool.setSize(MAX_NDB_NODES); c_masterNodeId = getOwnNodeId(); - const Properties * p = conf.getOwnProperties(); + const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator(); ndbrequire(p != 0); Uint32 noBackups = 0, noTables = 0, noAttribs = 0; - p->get("ParallelBackups", &noBackups); - ndbrequire(p->get("MaxNoOfTables", &noTables)); - ndbrequire(p->get("MaxNoOfAttributes", &noAttribs)); - + 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_ATTRIBUTES, &noAttribs)); + // To allow for user tables AND SYSTAB // See ClusterConfig //TODO get this infor from NdbCntr @@ -65,7 +65,7 @@ Backup::Backup(const Configuration & conf) : c_fragmentPool.setSize(noBackups * 2 * NO_OF_FRAG_PER_NODE * noTables); Uint32 szMem = 0; - p->get("BackupMemory", &szMem); + ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_MEM, &szMem); Uint32 noPages = (szMem + sizeof(Page32) - 1) / sizeof(Page32); // We need to allocate an additional of 2 pages. 1 page because of a bug in // ArrayPool and another one for DICTTAINFO. @@ -74,9 +74,9 @@ Backup::Backup(const Configuration & conf) : Uint32 szDataBuf = (2 * 1024 * 1024); Uint32 szLogBuf = (2 * 1024 * 1024); Uint32 szWrite = 32768; - p->get("BackupDataBufferSize", &szDataBuf); - p->get("BackupLogBufferSize", &szLogBuf); - p->get("BackupWriteSize", &szWrite); + ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_DATA_BUFFER_MEM, &szDataBuf); + ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_LOG_BUFFER_MEM, &szLogBuf); + ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_WRITE_SIZE, &szWrite); c_defaults.m_logBufferSize = szLogBuf; c_defaults.m_dataBufferSize = szDataBuf; diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index cd6198eff23..6cac2f00542 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -16,7 +16,6 @@ #include "Cmvmi.hpp" -#include <ClusterConfiguration.hpp> #include <Configuration.hpp> #include <kernel_types.h> #include <TransporterRegistry.hpp> @@ -31,15 +30,11 @@ #include <signaldata/TestOrd.hpp> #include <signaldata/EventReport.hpp> #include <signaldata/TamperOrd.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/StartOrd.hpp> -#include <signaldata/CmvmiCfgConf.hpp> -#include <signaldata/CmInit.hpp> #include <signaldata/CloseComReqConf.hpp> #include <signaldata/SetLogLevelOrd.hpp> #include <signaldata/EventSubscribeReq.hpp> #include <signaldata/DumpStateOrd.hpp> -#include <signaldata/ArbitSignalData.hpp> #include <signaldata/DisconnectRep.hpp> #include <EventLogger.hpp> @@ -55,8 +50,7 @@ EventLogger g_eventLogger; Cmvmi::Cmvmi(const Configuration & conf) : SimulatedBlock(CMVMI, conf) ,theConfig((Configuration&)conf) - ,theCConfig(conf.clusterConfiguration()), - subscribers(subscriberPool) + ,subscribers(subscriberPool) { BLOCK_CONSTRUCTOR(Cmvmi); @@ -67,14 +61,10 @@ Cmvmi::Cmvmi(const Configuration & conf) : addRecSignal(GSN_NDB_TAMPER, &Cmvmi::execNDB_TAMPER, true); addRecSignal(GSN_SET_LOGLEVELORD, &Cmvmi::execSET_LOGLEVELORD); addRecSignal(GSN_EVENT_REP, &Cmvmi::execEVENT_REP); - addRecSignal(GSN_STTOR, &Cmvmi::execSTTOR_Local); - addRecSignal(GSN_CM_RUN, &Cmvmi::execCM_RUN); - addRecSignal(GSN_CM_INFOREQ, &Cmvmi::execCM_INFOREQ); - addRecSignal(GSN_CMVMI_CFGREQ, &Cmvmi::execCMVMI_CFGREQ); + addRecSignal(GSN_STTOR, &Cmvmi::execSTTOR); addRecSignal(GSN_CLOSE_COMREQ, &Cmvmi::execCLOSE_COMREQ); addRecSignal(GSN_ENABLE_COMORD, &Cmvmi::execENABLE_COMORD); addRecSignal(GSN_OPEN_COMREQ, &Cmvmi::execOPEN_COMREQ); - addRecSignal(GSN_SIZEALT_ACK, &Cmvmi::execSIZEALT_ACK); addRecSignal(GSN_TEST_ORD, &Cmvmi::execTEST_ORD); addRecSignal(GSN_STATISTICS_REQ, &Cmvmi::execSTATISTICS_REQ); @@ -93,16 +83,28 @@ Cmvmi::Cmvmi(const Configuration & conf) : subscriberPool.setSize(5); - const ClusterConfiguration::ClusterData & clData = - theConfig.clusterConfigurationData() ; + const ndb_mgm_configuration_iterator * db = theConfig.getOwnConfigIterator(); + for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){ + Uint32 logLevel; + if(!ndb_mgm_get_int_parameter(db, LogLevel::MIN_LOGLEVEL_ID+j, &logLevel)){ + clogLevel.setLogLevel((LogLevel::EventCategory)j, + logLevel); + } + } - clogLevel = clData.SizeAltData.logLevel; - - for(Uint32 i= 0; i< clData.SizeAltData.noOfNodes; i++ ){ + ndb_mgm_configuration_iterator * iter = theConfig.getClusterConfigIterator(); + for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)){ jam(); - const Uint32 nodeId = clData.nodeData[i].nodeId; - switch(clData.nodeData[i].nodeType){ + Uint32 nodeId; + Uint32 nodeType; + + ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_NODE_ID, &nodeId)); + ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_TYPE_OF_SECTION,&nodeType)); + + switch(nodeType){ case NodeInfo::DB: + c_dbNodes.set(nodeId); + break; case NodeInfo::API: case NodeInfo::MGM: case NodeInfo::REP: @@ -110,8 +112,10 @@ Cmvmi::Cmvmi(const Configuration & conf) : default: ndbrequire(false); } - setNodeInfo(nodeId).m_type = clData.nodeData[i].nodeType; + setNodeInfo(nodeId).m_type = nodeType; } + + setNodeInfo(getOwnNodeId()).m_connected = true; } Cmvmi::~Cmvmi() @@ -278,121 +282,42 @@ Cmvmi::cancelSubscription(NodeId nodeId){ void Cmvmi::sendSTTORRY(Signal* signal) { - if( theStartPhase == 1 ) { - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData() ; - const int myNodeId = globalData.ownId; - int MyNodeFound = 0; - - jam(); - - CmInit * const cmInit = (CmInit *)&signal->theData[0]; - - cmInit->heartbeatDbDb = clusterConf.ispValues[0][2]; - cmInit->heartbeatDbApi = clusterConf.ispValues[0][3]; - cmInit->arbitTimeout = clusterConf.ispValues[0][5]; - - NodeBitmask::clear(cmInit->allNdbNodes); - for(unsigned int i = 0; i < clusterConf.SizeAltData.noOfNodes; i++ ) { - jam(); - if (clusterConf.nodeData[i].nodeType == NodeInfo::DB){ - jam(); - const NodeId nodeId = clusterConf.nodeData[i].nodeId; - if (nodeId == myNodeId) { - jam(); - MyNodeFound = 1; - }//if - NodeBitmask::set(cmInit->allNdbNodes, nodeId); - }//if - }//for - - if (MyNodeFound == 0) { - ERROR_SET(fatal, ERR_NODE_NOT_IN_CONFIG, "", ""); - }//if - - sendSignal(QMGR_REF, GSN_CM_INIT, signal, CmInit::SignalLength, JBB); - - // these do not fit into CM_INIT - ArbitSignalData* const sd = (ArbitSignalData*)&signal->theData[0]; - for (unsigned rank = 1; rank <= 2; rank++) { - sd->sender = myNodeId; - sd->code = rank; - sd->node = 0; - sd->ticket.clear(); - sd->mask.clear(); - for (int i = 0; i < MAX_NODES; i++) { - if (clusterConf.nodeData[i].arbitRank == rank) - sd->mask.set(clusterConf.nodeData[i].nodeId); - } - sendSignal(QMGR_REF, GSN_ARBIT_CFG, signal, - ArbitSignalData::SignalLength, JBB); - } - } else { - jam(); - signal->theData[0] = theSignalKey; - signal->theData[3] = 1; - signal->theData[4] = 3; - signal->theData[5] = 255; - sendSignal(NDBCNTR_REF, GSN_STTORRY, signal,6, JBB); - } + jam(); + signal->theData[3] = 1; + signal->theData[4] = 3; + signal->theData[5] = 8; + signal->theData[6] = 255; + sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 7, JBB); }//Cmvmi::sendSTTORRY -// Received a restart signal. -// Answer it like any other block -// PR0 : StartCase -// DR0 : StartPhase -// DR1 : ? -// DR2 : ? -// DR3 : ? -// DR4 : ? -// DR5 : SignalKey - -void Cmvmi::execSTTOR_Local(Signal* signal) +void Cmvmi::execSTTOR(Signal* signal) { - theStartPhase = signal->theData[1]; - theSignalKey = signal->theData[6]; + Uint32 theStartPhase = signal->theData[1]; - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); jamEntry(); - if (theStartPhase == 1 && clusterConf.SizeAltData.exist == true){ + if (theStartPhase == 1){ jam(); - signalCount = 0; - execSIZEALT_ACK(signal); + sendSTTORRY(signal); return; } else if (theStartPhase == 3) { jam(); globalData.activateSendPacked = 1; sendSTTORRY(signal); - } else { - jam(); + } else if (theStartPhase == 8){ + /*---------------------------------------------------*/ + /* Open com to API + REP nodes */ + /*---------------------------------------------------*/ + signal->theData[0] = 0; // no answer + signal->theData[1] = 0; // no id + signal->theData[2] = NodeInfo::API; + execOPEN_COMREQ(signal); + signal->theData[0] = 0; // no answer + signal->theData[1] = 0; // no id + signal->theData[2] = NodeInfo::REP; + execOPEN_COMREQ(signal); + globalData.theStartLevel = NodeState::SL_STARTED; sendSTTORRY(signal); - } -} - -void Cmvmi::execSIZEALT_ACK(Signal* signal) -{ - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); - jamEntry(); - - if (signalCount < NDB_SIZEALT_OFF){ - jam(); - BlockNumber blockNo = clusterConf.SizeAltData.blockNo[signalCount]; - signal->theData[0] = CMVMI_REF; - - /** - * This send SizeAlt(s) to blocks - * Definition of data content can be found in SignalData/XXXSizeAltReq.H - */ - const unsigned int noOfWords = 20; - for(unsigned int i = 1; i<noOfWords; i++){ - signal->theData[i] = clusterConf.SizeAltData.varSize[signalCount][i].nrr; - } - - signalCount++; - sendSignal(numberToRef(blockNo, 0), GSN_SIZEALT_REP, signal,21, JBB); } else { jam(); @@ -408,90 +333,6 @@ void Cmvmi::execSIZEALT_ACK(Signal* signal) } } -void Cmvmi::execCM_INFOREQ(Signal* signal) -{ - int id = signal->theData[1]; - const BlockReference userRef = signal->theData[0]; - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); - const int myNodeId = globalData.ownId; - - jamEntry(); - signal->theData[0] = id; - - for(unsigned int i= 0; i< clusterConf.SizeAltData.noOfNodes; i++ ) { - jam(); - if (clusterConf.nodeData[i].nodeType == NodeInfo::DB){ - NodeId nodeId = clusterConf.nodeData[i].nodeId; - if (nodeId != myNodeId) { - jam(); - globalTransporterRegistry.setPerformState(nodeId, PerformConnect); - } - } - } - - sendSignal(userRef, GSN_CM_INFOCONF, signal, 1, JBB); -} - -void Cmvmi::execCM_RUN(Signal* signal) -{ - jamEntry(); - if (signal->theData[0] == 0) { - jam(); - signal->theData[0] = theSignalKey; - signal->theData[3] = 1; - signal->theData[4] = 3; - signal->theData[5] = 255; - sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB); - } else { - globalData.theStartLevel = NodeState::SL_STARTED; - - // Connect to all application nodes. - // Enable communication with all NDB blocks. - - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); - jam(); - for(unsigned int i= 0; i< clusterConf.SizeAltData.noOfNodes; i++ ) { - NodeId nodeId = clusterConf.nodeData[i].nodeId; - jam(); - if (clusterConf.nodeData[i].nodeType != NodeInfo::DB && - clusterConf.nodeData[i].nodeType != NodeInfo::MGM){ - - jam(); - globalTransporterRegistry.setPerformState(nodeId, PerformConnect); - globalTransporterRegistry.setIOState(nodeId, HaltIO); - //----------------------------------------------------- - // Report that the connection to the node is opened - //----------------------------------------------------- - signal->theData[0] = EventReport::CommunicationOpened; - signal->theData[1] = clusterConf.nodeData[i].nodeId; - sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); - //----------------------------------------------------- - } - } - } -} - -void Cmvmi::execCMVMI_CFGREQ(Signal* signal) -{ - const BlockReference userRef = signal->theData[0]; - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); - - int theStart_phase = signal->theData[1]; - - jamEntry(); - - CmvmiCfgConf * const cfgConf = (CmvmiCfgConf *)&signal->theData[0]; - - cfgConf->startPhase = theStart_phase; - for(unsigned int i = 0; i<CmvmiCfgConf::NO_OF_WORDS; i++) - cfgConf->theData[i] = clusterConf.ispValues[theStart_phase][i]; - - sendSignal(userRef, GSN_CMVMI_CFGCONF, signal, CmvmiCfgConf::LENGTH,JBB ); -} - void Cmvmi::execCLOSE_COMREQ(Signal* signal) { // Close communication with the node and halt input/output from @@ -540,21 +381,42 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal) const BlockReference userRef = signal->theData[0]; Uint32 tStartingNode = signal->theData[1]; - + Uint32 tData2 = signal->theData[2]; jamEntry(); + + const Uint32 len = signal->getLength(); + if(len == 2){ + globalTransporterRegistry.setPerformState(tStartingNode, PerformConnect); + globalTransporterRegistry.setIOState(tStartingNode, HaltIO); + + //----------------------------------------------------- + // Report that the connection to the node is opened + //----------------------------------------------------- + signal->theData[0] = EventReport::CommunicationOpened; + signal->theData[1] = tStartingNode; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + //----------------------------------------------------- + } else { + for(unsigned int i = 1; i < MAX_NODES; i++ ) { + jam(); + if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2){ + jam(); + globalTransporterRegistry.setPerformState(i, PerformConnect); + globalTransporterRegistry.setIOState(i, HaltIO); + + signal->theData[0] = EventReport::CommunicationOpened; + signal->theData[1] = i; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + } + } + } + if (userRef != 0) { jam(); - signal->theData[0] = signal->theData[1]; - sendSignal(userRef, GSN_OPEN_COMCONF, signal, 2,JBA); + signal->theData[0] = tStartingNode; + signal->theData[1] = tData2; + sendSignal(userRef, GSN_OPEN_COMCONF, signal, len - 1,JBA); } - globalTransporterRegistry.setPerformState(tStartingNode, PerformConnect); - //----------------------------------------------------- - // Report that the connection to the node is opened - //----------------------------------------------------- - signal->theData[0] = EventReport::CommunicationOpened; - signal->theData[1] = tStartingNode; - sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); - //----------------------------------------------------- } void Cmvmi::execENABLE_COMORD(Signal* signal) @@ -888,18 +750,11 @@ Cmvmi::execSTART_ORD(Signal* signal) { /** * Open connections to management servers */ - - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData() ; - - for(unsigned int i= 0; i < clusterConf.SizeAltData.noOfNodes; i++ ){ - NodeId nodeId = clusterConf.nodeData[i].nodeId; - - if (clusterConf.nodeData[i].nodeType == NodeInfo::MGM){ - - if(globalTransporterRegistry.performState(nodeId) != PerformIO){ - globalTransporterRegistry.setPerformState(nodeId, PerformConnect); - globalTransporterRegistry.setIOState(nodeId, NoHalt); + for(unsigned int i = 1; i < MAX_NODES; i++ ){ + if (getNodeInfo(i).m_type == NodeInfo::MGM){ + if(globalTransporterRegistry.performState(i) != PerformIO){ + globalTransporterRegistry.setPerformState(i, PerformConnect); + globalTransporterRegistry.setIOState(i, NoHalt); } } } @@ -922,17 +777,10 @@ Cmvmi::execSTART_ORD(Signal* signal) { // Disconnect all nodes as part of the system restart. // We need to ensure that we are starting up // without any connected nodes. - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData() ; - const int myNodeId = globalData.ownId; - - for(unsigned int i= 0; i < clusterConf.SizeAltData.noOfNodes; i++ ){ - NodeId nodeId = clusterConf.nodeData[i].nodeId; - if (myNodeId != nodeId && - clusterConf.nodeData[i].nodeType != NodeInfo::MGM){ - - globalTransporterRegistry.setPerformState(nodeId, PerformDisconnect); - globalTransporterRegistry.setIOState(nodeId, HaltIO); + for(unsigned int i = 1; i < MAX_NODES; i++ ){ + if (i != getOwnNodeId() && getNodeInfo(i).m_type != NodeInfo::MGM){ + globalTransporterRegistry.setPerformState(i, PerformDisconnect); + globalTransporterRegistry.setIOState(i, HaltIO); } } @@ -963,6 +811,7 @@ void Cmvmi::execTAMPER_ORD(Signal* signal) void Cmvmi::execSET_VAR_REQ(Signal* signal) { +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); @@ -1047,7 +896,7 @@ void Cmvmi::execSET_VAR_REQ(Signal* signal) sendSignal(mgmtSrvr, GSN_SET_VAR_REF, signal, 0, JBB); } // switch - +#endif }//execSET_VAR_REQ() @@ -1068,7 +917,7 @@ void Cmvmi::execSET_VAR_REF(Signal* signal) void Cmvmi::handleSET_VAR_REQ(Signal* signal) { - +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); int val = setVarReq->value(); @@ -1109,7 +958,7 @@ void Cmvmi::handleSET_VAR_REQ(Signal* signal) { sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); return; } // switch - +#endif } #ifdef VM_TRACE @@ -1184,14 +1033,9 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0]; if (dumpState->args[0] == DumpStateOrd::CmvmiDumpConnections){ - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData() ; - - for(unsigned int i= 0; i < clusterConf.SizeAltData.noOfNodes; i++ ){ - NodeId nodeId = clusterConf.nodeData[i].nodeId; - + for(unsigned int i = 1; i < MAX_NODES; i++ ){ const char* nodeTypeStr = ""; - switch(clusterConf.nodeData[i].nodeType){ + switch(getNodeInfo(i).m_type){ case NodeInfo::DB: nodeTypeStr = "DB"; break; @@ -1204,12 +1048,18 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) case NodeInfo::REP: nodeTypeStr = "REP"; break; + case NodeInfo::INVALID: + nodeTypeStr = 0; + break; default: nodeTypeStr = "<UNKNOWN>"; } + if(nodeTypeStr == 0) + continue; + const char* actionStr = ""; - switch (globalTransporterRegistry.performState(nodeId)){ + switch (globalTransporterRegistry.performState(i)){ case PerformNothing: actionStr = "does nothing"; break; @@ -1228,18 +1078,18 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) } infoEvent("Connection to %d (%s) %s", - nodeId, + i, nodeTypeStr, actionStr); } } - + if (dumpState->args[0] == DumpStateOrd::CmvmiDumpLongSignalMemory){ infoEvent("Cmvmi: g_sectionSegmentPool size: %d free: %d", g_sectionSegmentPool.getSize(), g_sectionSegmentPool.getNoOfFree()); } - + if (dumpState->args[0] == DumpStateOrd::CmvmiSetRestartOnErrorInsert){ if(signal->getLength() == 1) theConfig.setRestartOnErrorInsert((int)NRT_NoStart_Restart); @@ -1372,15 +1222,7 @@ Cmvmi::execTESTSIG(Signal* signal){ return; } - NodeReceiverGroup rg; rg.m_block = CMVMI; - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData() ; - for(unsigned int i = 0; i < clusterConf.SizeAltData.noOfNodes; i++ ){ - NodeId nodeId = clusterConf.nodeData[i].nodeId; - if (clusterConf.nodeData[i].nodeType == NodeInfo::DB){ - rg.m_nodes.set(nodeId); - } - } + NodeReceiverGroup rg(CMVMI, c_dbNodes); if(signal->getSendersBlockRef() == ref){ /** @@ -1550,6 +1392,26 @@ Cmvmi::execTESTSIG(Signal* signal){ } break; } + case 13:{ + ndbrequire(signal->getNoOfSections() == 0); + Uint32 loop = signal->theData[9]; + if(loop > 0){ + signal->theData[9] --; + sendSignal(CMVMI_REF, GSN_TESTSIG, signal, signal->length(), JBB); + return; + } + sendSignal(ref, GSN_TESTSIG, signal, signal->length(), JBB); + return; + } + case 14:{ + Uint32 count = signal->theData[8]; + signal->theData[10] = count * rg.m_nodes.count(); + for(Uint32 i = 0; i<count; i++){ + sendSignal(rg, GSN_TESTSIG, signal, signal->length(), JBB); + } + return; + } + default: ndbrequire(false); } diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp index 4f42c2efc93..1c91f564749 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp @@ -48,10 +48,7 @@ private: void execNDB_TAMPER(Signal* signal); void execSET_LOGLEVELORD(Signal* signal); void execEVENT_REP(Signal* signal); - void execSTTOR_Local(Signal* signal); - void execCM_RUN(Signal* signal); - void execCM_INFOREQ(Signal* signal); - void execCMVMI_CFGREQ(Signal* signal); + void execSTTOR(Signal* signal); void execCLOSE_COMREQ(Signal* signal); void execENABLE_COMORD(Signal* signal); void execOPEN_COMREQ(Signal* signal); @@ -75,17 +72,13 @@ private: void execTESTSIG(Signal* signal); - int signalCount; - int theSignalKey; - int theStartPhase; - int theNumberOfNodes; - char theErrorMessage[256]; void sendSTTORRY(Signal* signal); LogLevel clogLevel; + NdbNodeBitmask c_dbNodes; + class Configuration & theConfig; - const class ClusterConfiguration & theCConfig; /** * This struct defines the data needed for a EVENT_REP subscriber diff --git a/ndb/src/kernel/blocks/dbacc/Dbacc.hpp b/ndb/src/kernel/blocks/dbacc/Dbacc.hpp index fef41be88c4..6ba2d083e58 100644 --- a/ndb/src/kernel/blocks/dbacc/Dbacc.hpp +++ b/ndb/src/kernel/blocks/dbacc/Dbacc.hpp @@ -958,7 +958,7 @@ private: void execDROP_TAB_REQ(Signal* signal); void execFSREMOVECONF(Signal* signal); void execFSREMOVEREF(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); void execSET_VAR_REQ(Signal* signal); void execDUMP_STATE_ORD(Signal* signal); @@ -1000,7 +1000,6 @@ private: void initScanFragmentPart(Signal* signal); Uint32 checkScanExpand(Signal* signal); Uint32 checkScanShrink(Signal* signal); - void sendInitialiseRecords(Signal* signal); void initialiseDirRec(Signal* signal); void initialiseDirRangeRec(Signal* signal); void initialiseFragRec(Signal* signal); @@ -1174,7 +1173,7 @@ private: void srReadPagesLab(Signal* signal); void srDoUndoLab(Signal* signal); void ndbrestart1Lab(Signal* signal); - void initialiseRecordsLab(Signal* signal); + void initialiseRecordsLab(Signal* signal, Uint32 returnRef, Uint32 retData); void srReadPagesAllocLab(Signal* signal); void checkNextBucketLab(Signal* signal); void endsavepageLab(Signal* signal); diff --git a/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp b/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp index 107420c7148..90e914987c3 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp @@ -179,7 +179,7 @@ Dbacc::Dbacc(const class Configuration & conf): addRecSignal(GSN_DROP_TAB_REQ, &Dbacc::execDROP_TAB_REQ); addRecSignal(GSN_FSREMOVECONF, &Dbacc::execFSREMOVECONF); addRecSignal(GSN_FSREMOVEREF, &Dbacc::execFSREMOVEREF); - addRecSignal(GSN_SIZEALT_REP, &Dbacc::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbacc::execREAD_CONFIG_REQ, true); addRecSignal(GSN_SET_VAR_REQ, &Dbacc::execSET_VAR_REQ); initData(); diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp index ea8d808458b..02474f6bee0 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp @@ -20,13 +20,11 @@ #include <signaldata/AccFrag.hpp> #include <signaldata/AccScan.hpp> #include <signaldata/AccLock.hpp> -#include <signaldata/AccSizeAltReq.hpp> #include <signaldata/EventReport.hpp> #include <signaldata/FsConf.hpp> #include <signaldata/FsRef.hpp> #include <signaldata/FsRemoveReq.hpp> #include <signaldata/DropTab.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/DumpStateOrd.hpp> // TO_DO_RONM is a label for comments on what needs to be improved in future versions @@ -127,7 +125,7 @@ void Dbacc::execCONTINUEB(Signal* signal) break; case ZINITIALISE_RECORDS: jam(); - initialiseRecordsLab(signal); + initialiseRecordsLab(signal, signal->theData[3], signal->theData[4]); return; break; case ZSR_READ_PAGES_ALLOC: @@ -496,9 +494,6 @@ void Dbacc::execFSWRITEREF(Signal* signal) void Dbacc::execNDB_STTOR(Signal* signal) { Uint32 tstartphase; - Uint32 tconfig1; - Uint32 tconfig2; - Uint32 tlqhConfig1; Uint32 tStartType; jamEntry(); @@ -506,9 +501,6 @@ void Dbacc::execNDB_STTOR(Signal* signal) cmynodeid = signal->theData[1]; tstartphase = signal->theData[2]; tStartType = signal->theData[3]; - tlqhConfig1 = signal->theData[10]; /* DBLQH */ - tconfig1 = signal->theData[16]; /* DBACC */ - tconfig2 = signal->theData[17]; /* DBACC */ switch (tstartphase) { case ZSPH1: jam(); @@ -534,21 +526,7 @@ void Dbacc::execNDB_STTOR(Signal* signal) //--------------------------------------------- csystemRestart = ZFALSE; }//if - if (tconfig1 > 0) { - jam(); - clblPagesPerTick = tconfig1; - } else { - jam(); - clblPagesPerTick = 1; - }//if - clblPageCounter = clblPagesPerTick; - if (tconfig2 > 0) { - jam(); - clblPagesPerTickAfterSr = tconfig2; - } else { - jam(); - clblPagesPerTickAfterSr = 1; - }//if + signal->theData[0] = ZLOAD_BAL_LCP_TIMER; sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 1); break; @@ -606,98 +584,86 @@ void Dbacc::ndbrestart1Lab(Signal* signal) for (Uint32 tmp = 0; tmp < ZMAX_UNDO_VERSION; tmp++) { csrVersList[tmp] = RNIL; }//for - tdata0 = 0; - initialiseRecordsLab(signal); return; }//Dbacc::ndbrestart1Lab() -void Dbacc::initialiseRecordsLab(Signal* signal) +void Dbacc::initialiseRecordsLab(Signal* signal, Uint32 ref, Uint32 data) { switch (tdata0) { case 0: jam(); initialiseTableRec(signal); - sendInitialiseRecords(signal); break; case 1: jam(); initialiseFsConnectionRec(signal); - sendInitialiseRecords(signal); break; case 2: jam(); initialiseFsOpRec(signal); - sendInitialiseRecords(signal); break; case 3: jam(); initialiseLcpConnectionRec(signal); - sendInitialiseRecords(signal); break; case 4: jam(); initialiseDirRec(signal); - sendInitialiseRecords(signal); break; case 5: jam(); initialiseDirRangeRec(signal); - sendInitialiseRecords(signal); break; case 6: jam(); initialiseFragRec(signal); - sendInitialiseRecords(signal); break; case 7: jam(); initialiseOverflowRec(signal); - sendInitialiseRecords(signal); break; case 8: jam(); initialiseOperationRec(signal); - sendInitialiseRecords(signal); break; case 9: jam(); initialisePageRec(signal); - sendInitialiseRecords(signal); break; case 10: jam(); initialiseRootfragRec(signal); - sendInitialiseRecords(signal); break; case 11: jam(); initialiseScanRec(signal); - sendInitialiseRecords(signal); break; case 12: jam(); initialiseSrVerRec(signal); - signal->theData[0] = cownBlockref; - sendSignal(CMVMI_REF, GSN_SIZEALT_ACK, signal, 1, JBB); + + { + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = data; + sendSignal(ref, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); + } return; break; default: ndbrequire(false); break; }//switch - return; -}//Dbacc::initialiseRecordsLab() -/* --------------------------------------------------------------------------------- */ -/* SEND REAL-TIME BREAK DURING INITIALISATION OF VARIABLES DURING SYSTEM RESTART.*/ -/* --------------------------------------------------------------------------------- */ -void Dbacc::sendInitialiseRecords(Signal* signal) -{ signal->theData[0] = ZINITIALISE_RECORDS; signal->theData[1] = tdata0 + 1; signal->theData[2] = 0; - sendSignal(cownBlockref, GSN_CONTINUEB, signal, 3, JBB); -}//Dbacc::sendInitialiseRecords() + signal->theData[3] = ref; + signal->theData[4] = data; + sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB); + return; +}//Dbacc::initialiseRecordsLab() /* *********************************<< */ /* NDB_STTORRY */ @@ -712,23 +678,41 @@ void Dbacc::ndbsttorryLab(Signal* signal) /* *********************************<< */ /* SIZEALT_REP SIZE ALTERATION */ /* *********************************<< */ -void Dbacc::execSIZEALT_REP(Signal* signal) +void Dbacc::execREAD_CONFIG_REQ(Signal* signal) { - Uint32 tsizealtBlockRef; - + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + jamEntry(); - tsizealtBlockRef = signal->theData[AccSizeAltReq::IND_BLOCK_REF]; - cdirrangesize = signal->theData[AccSizeAltReq::IND_DIR_RANGE]; - cdirarraysize = signal->theData[AccSizeAltReq::IND_DIR_ARRAY]; - cfragmentsize = signal->theData[AccSizeAltReq::IND_FRAGMENT]; - coprecsize = signal->theData[AccSizeAltReq::IND_OP_RECS]; - coverflowrecsize = signal->theData[AccSizeAltReq::IND_OVERFLOW_RECS]; - cpagesize = signal->theData[AccSizeAltReq::IND_PAGE8]; - crootfragmentsize = signal->theData[AccSizeAltReq::IND_ROOT_FRAG]; - ctablesize = signal->theData[AccSizeAltReq::IND_TABLE]; - cscanRecSize = signal->theData[AccSizeAltReq::IND_SCAN]; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_DIR_RANGE, &cdirrangesize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_DIR_ARRAY, &cdirarraysize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_FRAGMENT, &cfragmentsize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_OP_RECS, &coprecsize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_OVERFLOW_RECS, + &coverflowrecsize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_PAGE8, &cpagesize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_ROOT_FRAG, + &crootfragmentsize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_TABLE, &ctablesize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_SCAN, &cscanRecSize)); initRecords(); ndbrestart1Lab(signal); + + clblPagesPerTick = 50; + //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTick); + + clblPagesPerTickAfterSr = 50; + //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTickAfterSr); + + tdata0 = 0; + initialiseRecordsLab(signal, ref, senderData); return; }//Dbacc::execSIZEALT_REP() @@ -13260,6 +13244,7 @@ Dbacc::execDUMP_STATE_ORD(Signal* signal) void Dbacc::execSET_VAR_REQ(Signal* signal) { +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); int val = setVarReq->value(); @@ -13280,6 +13265,6 @@ void Dbacc::execSET_VAR_REQ(Signal* signal) default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); } // switch - +#endif }//execSET_VAR_REQ() diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 8cf15b6bef2..a11205047e5 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -27,7 +27,6 @@ #include <SimpleProperties.hpp> #include <AttributeHeader.hpp> #include <signaldata/DictSchemaInfo.hpp> -#include <signaldata/DictSizeAltReq.hpp> #include <signaldata/DictTabInfo.hpp> #include <signaldata/DropTabFile.hpp> @@ -76,7 +75,6 @@ #include <signaldata/AlterTab.hpp> #include <signaldata/CreateFragmentation.hpp> #include <signaldata/CreateTab.hpp> -#include "../dbtc/Dbtc.hpp" #include <NdbSleep.h> #define ZNOT_FOUND 626 @@ -255,6 +253,7 @@ Dbdict::packTableIntoPagesImpl(SimpleProperties::Writer & w, w.add(DictTabInfo::FragmentTypeVal, tablePtr.p->fragmentType); w.add(DictTabInfo::FragmentKeyTypeVal, tablePtr.p->fragmentKeyType); w.add(DictTabInfo::TableTypeVal, tablePtr.p->tableType); + w.add(DictTabInfo::FragmentCount, tablePtr.p->fragmentCount); if (tablePtr.p->primaryTableId != RNIL){ TableRecordPtr primTab; @@ -1042,10 +1041,10 @@ Dbdict::Dbdict(const class Configuration & conf): { BLOCK_CONSTRUCTOR(Dbdict); - const Properties * p = conf.getOwnProperties(); + const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator(); ndbrequire(p != 0); - p->get("MaxNoOfTriggers", &c_maxNoOfTriggers); + ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS, &c_maxNoOfTriggers); // Transit signals addRecSignal(GSN_DUMP_STATE_ORD, &Dbdict::execDUMP_STATE_ORD); addRecSignal(GSN_GET_TABINFOREQ, &Dbdict::execGET_TABINFOREQ); @@ -1161,7 +1160,7 @@ Dbdict::Dbdict(const class Configuration & conf): addRecSignal(GSN_LQHADDATTREF, &Dbdict::execLQHADDATTREF); addRecSignal(GSN_LQHFRAGREF, &Dbdict::execLQHFRAGREF); addRecSignal(GSN_NDB_STTOR, &Dbdict::execNDB_STTOR); - addRecSignal(GSN_SIZEALT_REP, &Dbdict::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbdict::execREAD_CONFIG_REQ, true); addRecSignal(GSN_STTOR, &Dbdict::execSTTOR); addRecSignal(GSN_TC_SCHVERCONF, &Dbdict::execTC_SCHVERCONF); addRecSignal(GSN_NODE_FAILREP, &Dbdict::execNODE_FAILREP); @@ -1524,7 +1523,6 @@ void Dbdict::execSTTOR(Signal* signal) c_startPhase = signal->theData[1]; switch (c_startPhase) { case 1: - initCommonData(); break; case 3: c_restartType = signal->theData[7]; /* valid if 3 */ @@ -1551,14 +1549,22 @@ void Dbdict::sendSTTORRY(Signal* signal) /* ---------------------------------------------------------------- */ // We receive information about sizes of records. /* ---------------------------------------------------------------- */ -void Dbdict::execSIZEALT_REP(Signal* signal) +void Dbdict::execREAD_CONFIG_REQ(Signal* signal) { + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + jamEntry(); - BlockReference tblockref; - tblockref = signal->theData[DictSizeAltReq::IND_BLOCK_REF]; - Uint32 attributesize = signal->theData[DictSizeAltReq::IND_ATTRIBUTE]; -// Uint32 connectsize = signal->theData[DictSizeAltReq::IND_CONNECT]; - Uint32 tablerecSize = signal->theData[DictSizeAltReq::IND_TABLE]; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + Uint32 attributesize, tablerecSize; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_ATTRIBUTE,&attributesize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &tablerecSize)); c_attributeRecordPool.setSize(attributesize); c_attributeRecordHash.setSize(64); @@ -1594,9 +1600,14 @@ void Dbdict::execSIZEALT_REP(Signal* signal) bat[1].bits.q = ZLOG_SIZE_OF_PAGES_IN_WORDS; // 2**13 = 8192 elements bat[1].bits.v = 5; // 32 bits per element + initCommonData(); initRecords(); - signal->theData[0] = DBDICT_REF; - sendSignal(tblockref, GSN_SIZEALT_ACK, signal, 2, JBB); + + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = senderData; + sendSignal(ref, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); }//execSIZEALT_REP() /* ---------------------------------------------------------------- */ @@ -2390,7 +2401,7 @@ Dbdict::execGET_TABINFO_CONF(Signal* signal){ SegmentedSectionPtr tabInfoPtr; signal->getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO); - + CreateTableRecordPtr createTabPtr; ndbrequire(c_opCreateTable.find(createTabPtr, senderData)); ndbrequire(!createTabPtr.isNull()); @@ -2412,7 +2423,10 @@ Dbdict::execGET_TABINFO_CONF(Signal* signal){ callback.m_callbackFunction = safe_cast(&Dbdict::restartCreateTab_writeTableConf); + signal->header.m_noOfSections = 0; writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback); + signal->setSection(tabInfoPtr, 0); + releaseSections(signal); } void @@ -3585,30 +3599,37 @@ Dbdict::execCREATE_FRAGMENTATION_CONF(Signal* signal){ SegmentedSectionPtr fragDataPtr; signal->getSection(fragDataPtr, CreateFragmentationConf::FRAGMENTS); - signal->header.m_noOfSections = 0; /** - * Correct table + * Get table */ TableRecordPtr tabPtr; c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); + /** + * Save fragment count + */ + tabPtr.p->fragmentCount = conf->noOfFragments; + + /** + * Update table version + */ PageRecordPtr pagePtr; c_pageRecordArray.getPtr(pagePtr, c_schemaRecord.schemaPage); SchemaFile::TableEntry * tabEntry = getTableEntry(pagePtr.p, tabPtr.i); + tabPtr.p->tableVersion = tabEntry->m_tableVersion + 1; + /** - * Update table version + * Pack */ - tabPtr.p->tableVersion = tabEntry->m_tableVersion + 1; - SimplePropertiesSectionWriter w(getSectionSegmentPool()); packTableIntoPagesImpl(w, tabPtr); SegmentedSectionPtr spDataPtr; w.getPtr(spDataPtr); - + signal->setSection(spDataPtr, CreateTabReq::DICT_TAB_INFO); signal->setSection(fragDataPtr, CreateTabReq::FRAGMENTATION); @@ -3820,15 +3841,15 @@ Dbdict::execCREATE_TAB_REQ(Signal* signal){ CreateTabReq::RequestType rt = (CreateTabReq::RequestType)req->requestType; switch(rt){ case CreateTabReq::CreateTablePrepare: - CRASH_INSERTION2(14000, getOwnNodeId() != c_masterNodeId); + CRASH_INSERTION2(6003, getOwnNodeId() != c_masterNodeId); createTab_prepare(signal, req); return; case CreateTabReq::CreateTableCommit: - CRASH_INSERTION2(14001, getOwnNodeId() != c_masterNodeId); + CRASH_INSERTION2(6004, getOwnNodeId() != c_masterNodeId); createTab_commit(signal, req); return; case CreateTabReq::CreateTableDrop: - CRASH_INSERTION2(14002, getOwnNodeId() != c_masterNodeId); + CRASH_INSERTION2(6005, getOwnNodeId() != c_masterNodeId); createTab_drop(signal, req); return; } @@ -3928,9 +3949,9 @@ Dbdict::createTab_writeSchemaConf1(Signal* signal, SegmentedSectionPtr tabInfoPtr; getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI); - writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback); + createTabPtr.p->m_tabInfoPtrI = RNIL; signal->setSection(tabInfoPtr, 0); releaseSections(signal); } @@ -4238,7 +4259,9 @@ Dbdict::execDIADDTABCONF(Signal* signal){ /** * No local fragment (i.e. no LQHFRAGREQ) */ - sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB); + execute(signal, createTabPtr.p->m_callback, 0); + return; + //sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB); } } @@ -4623,6 +4646,7 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, tablePtr.p->fragmentKeyType = (DictTabInfo::FragmentKeyType)tableDesc.FragmentKeyType; tablePtr.p->tableType = (DictTabInfo::TableType)tableDesc.TableType; tablePtr.p->kValue = tableDesc.TableKValue; + tablePtr.p->fragmentCount = tableDesc.FragmentCount; tablePtr.p->frmLen = tableDesc.FrmLen; memcpy(tablePtr.p->frmData, tableDesc.FrmData, tableDesc.FrmLen); @@ -5066,8 +5090,20 @@ Dbdict::execPREP_DROP_TAB_REF(Signal* signal){ Uint32 nodeId = refToNode(prep->senderRef); dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId); - - dropTabPtr.p->setErrorCode((Uint32)prep->errorCode); + + Uint32 block = refToBlock(prep->senderRef); + if((prep->errorCode == PrepDropTabRef::NoSuchTable && block == DBLQH) || + (prep->errorCode == PrepDropTabRef::NF_FakeErrorREF)){ + jam(); + /** + * Ignore errors: + * 1) no such table and LQH, it might not exists in different LQH's + * 2) node failure... + */ + } else { + dropTabPtr.p->setErrorCode((Uint32)prep->errorCode); + } + if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){ jam(); return; @@ -5098,6 +5134,19 @@ void Dbdict::execDROP_TAB_REF(Signal* signal){ jamEntry(); + DropTabRef * const req = (DropTabRef*)signal->getDataPtr(); + + Uint32 block = refToBlock(req->senderRef); + ndbrequire(req->errorCode == DropTabRef::NF_FakeErrorREF || + (req->errorCode == DropTabRef::NoSuchTable && + (block == DBTUP || block == DBACC || block == DBLQH))); + + if(block != DBDICT){ + jam(); + ndbrequire(refToNode(req->senderRef) == getOwnNodeId()); + dropTab_localDROP_TAB_CONF(signal); + return; + } ndbrequire(false); } @@ -11498,7 +11547,7 @@ Dbdict::initSchemaFile(SchemaFile * sf, Uint32 fileSz){ ndbrequire(noEntries > MAX_TABLES); sf->NoOfTableEntries = noEntries; - memset(sf->TableEntries, 0, sizeof(noEntries*sizeof(SchemaFile::TableEntry))); + memset(sf->TableEntries, 0, noEntries*sizeof(SchemaFile::TableEntry)); memset(&(sf->TableEntries[noEntries]), 0, slack); computeChecksum(sf); } diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp index 44086b19efd..de1d9757b2a 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp @@ -230,7 +230,7 @@ public: Uint32 frmLen; char frmData[MAX_FRM_DATA_SIZE]; - + Uint32 fragmentCount; }; typedef Ptr<TableRecord> TableRecordPtr; @@ -467,7 +467,7 @@ private: void execFSWRITECONF(Signal* signal); void execFSWRITEREF(Signal* signal); void execNDB_STTOR(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); void execSTTOR(Signal* signal); void execTC_SCHVERCONF(Signal* signal); void execNODE_FAILREP(Signal* signal); diff --git a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp index 4ec699cebec..e029af70574 100644 --- a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp +++ b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp @@ -312,7 +312,6 @@ public: Bitmask<1> m_nodefailSteps; Uint32 activeTabptr; Uint32 nextNode; - Uint32 ndbversion; Uint32 nodeGroup; SignalCounter m_NF_COMPLETE_REP; @@ -663,7 +662,7 @@ private: void execSTOP_ME_REF(Signal *); void execSTOP_ME_CONF(Signal *); - void execSIZEALT_REP(Signal *); + void execREAD_CONFIG_REQ(Signal *); void execUNBLO_DICTCONF(Signal *); void execCOPY_ACTIVECONF(Signal *); void execTAB_COMMITREQ(Signal *); @@ -685,7 +684,6 @@ private: void execNDB_STARTREQ(Signal *); void execGETGCIREQ(Signal *); void execDIH_RESTARTREQ(Signal *); - void execCNTR_CHANGEREP(Signal *); void execSTART_RECCONF(Signal *); void execSTART_FRAGCONF(Signal *); void execADD_FRAGCONF(Signal *); @@ -798,6 +796,7 @@ private: void closeFileDelete(Signal *, FileRecordPtr regFilePtr); void createFileRw(Signal *, FileRecordPtr regFilePtr); void openFileRw(Signal *, FileRecordPtr regFilePtr); + void openFileRo(Signal *, FileRecordPtr regFilePtr); void seizeFile(FileRecordPtr& regFilePtr); void releaseFile(Uint32 fileIndex); @@ -969,7 +968,7 @@ private: void checkCopyTab(NodeRecordPtr failedNodePtr); void initCommonData(); - void initialiseRecordsLab(Signal *, Uint32 stepNo); + void initialiseRecordsLab(Signal *, Uint32 stepNo, Uint32, Uint32); void findReplica(ReplicaRecordPtr& regReplicaPtr, Fragmentstore* fragPtrP, Uint32 nodeId); @@ -1409,7 +1408,6 @@ private: Uint32 startNode; Uint32 wait; Uint32 failNr; - Uint32 ndbVersion; bool activeState; bool blockLcp; bool blockGcp; diff --git a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp index b115cc0297a..f996a1fe689 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp @@ -179,7 +179,7 @@ Dbdih::Dbdih(const class Configuration & config): addRecSignal(GSN_START_LCP_REQ, &Dbdih::execSTART_LCP_REQ); addRecSignal(GSN_START_LCP_CONF, &Dbdih::execSTART_LCP_CONF); - addRecSignal(GSN_SIZEALT_REP, &Dbdih::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbdih::execREAD_CONFIG_REQ, true); addRecSignal(GSN_UNBLO_DICTCONF, &Dbdih::execUNBLO_DICTCONF); addRecSignal(GSN_COPY_ACTIVECONF, &Dbdih::execCOPY_ACTIVECONF); addRecSignal(GSN_TAB_COMMITREQ, &Dbdih::execTAB_COMMITREQ); @@ -201,7 +201,6 @@ Dbdih::Dbdih(const class Configuration & config): addRecSignal(GSN_NDB_STARTREQ, &Dbdih::execNDB_STARTREQ); addRecSignal(GSN_GETGCIREQ, &Dbdih::execGETGCIREQ); addRecSignal(GSN_DIH_RESTARTREQ, &Dbdih::execDIH_RESTARTREQ); - addRecSignal(GSN_CNTR_CHANGEREP, &Dbdih::execCNTR_CHANGEREP); addRecSignal(GSN_START_RECCONF, &Dbdih::execSTART_RECCONF); addRecSignal(GSN_START_FRAGCONF, &Dbdih::execSTART_FRAGCONF); addRecSignal(GSN_ADD_FRAGCONF, &Dbdih::execADD_FRAGCONF); @@ -255,6 +254,7 @@ Dbdih::Dbdih(const class Configuration & config): addRecSignal(GSN_UPDATE_TOCONF, &Dbdih::execUPDATE_TOCONF); addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dbdih::execPREP_DROP_TAB_REQ); + addRecSignal(GSN_WAIT_DROP_TAB_REF, &Dbdih::execWAIT_DROP_TAB_REF); addRecSignal(GSN_WAIT_DROP_TAB_CONF, &Dbdih::execWAIT_DROP_TAB_CONF); addRecSignal(GSN_DROP_TAB_REQ, &Dbdih::execDROP_TAB_REQ); diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index cefbb3e66a3..059f1301ba2 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -32,7 +32,6 @@ #include <signaldata/DictStart.hpp> #include <signaldata/DiGetNodes.hpp> #include <signaldata/DihContinueB.hpp> -#include <signaldata/DihSizeAltReq.hpp> #include <signaldata/DihSwitchReplica.hpp> #include <signaldata/DumpStateOrd.hpp> #include <signaldata/EmptyLcp.hpp> @@ -45,7 +44,6 @@ #include <signaldata/NFCompleteRep.hpp> #include <signaldata/NodeFailRep.hpp> #include <signaldata/ReadNodesConf.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/StartFragReq.hpp> #include <signaldata/StartInfo.hpp> #include <signaldata/StartMe.hpp> @@ -68,7 +66,7 @@ #include <signaldata/DictTabInfo.hpp> #include <signaldata/CreateFragmentation.hpp> #include <signaldata/LqhFrag.hpp> - +#include <signaldata/FsOpenReq.hpp> #include <DebuggerNames.hpp> #define SYSFILE ((Sysfile *)&sysfileData[0]) @@ -212,7 +210,7 @@ void Dbdih::sendINCL_NODEREQ(Signal* signal, Uint32 nodeId) signal->theData[0] = reference(); signal->theData[1] = c_nodeStartMaster.startNode; signal->theData[2] = c_nodeStartMaster.failNr; - signal->theData[3] = c_nodeStartMaster.ndbVersion; + signal->theData[3] = 0; signal->theData[4] = currentgcp; sendSignal(nodeDihRef, GSN_INCL_NODEREQ, signal, 5, JBB); }//Dbdih::sendINCL_NODEREQ() @@ -291,13 +289,6 @@ void Dbdih::sendUPDATE_TOREQ(Signal* signal, Uint32 nodeId) sendSignal(ref, GSN_UPDATE_TOREQ, signal, UpdateToReq::SignalLength, JBB); }//sendUPDATE_TOREQ() -void Dbdih::execCNTR_CHANGEREP(Signal* signal) -{ - (void)signal; // Don't want compiler warning - jamEntry(); - return; -}//Dbdih::execCNTR_CHANGEREP() - void Dbdih::execCONTINUEB(Signal* signal) { jamEntry(); @@ -542,7 +533,10 @@ void Dbdih::execCONTINUEB(Signal* signal) } case DihContinueB::ZINITIALISE_RECORDS: jam(); - initialiseRecordsLab(signal, signal->theData[1]); + initialiseRecordsLab(signal, + signal->theData[1], + signal->theData[2], + signal->theData[3]); return; break; case DihContinueB::ZSTART_PERMREQ_AGAIN: @@ -1023,17 +1017,30 @@ void Dbdih::execGETGCIREQ(Signal* signal) sendSignal(userRef, GSN_GETGCICONF, signal, 2, JBB); }//Dbdih::execGETGCIREQ() -void Dbdih::execSIZEALT_REP(Signal* signal) +void Dbdih::execREAD_CONFIG_REQ(Signal* signal) { + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + jamEntry(); - capiConnectFileSize = signal->theData[DihSizeAltReq::IND_API_CONNECT]; - cconnectFileSize = signal->theData[DihSizeAltReq::IND_CONNECT]; - cfragstoreFileSize = signal->theData[DihSizeAltReq::IND_FRAG_CONNECT]; - creplicaFileSize = signal->theData[DihSizeAltReq::IND_REPLICAS]; - ctabFileSize = signal->theData[DihSizeAltReq::IND_TABLE]; - cfileFileSize = (2 * ctabFileSize) + 2; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_API_CONNECT, + &capiConnectFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_CONNECT,&cconnectFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT, + &cfragstoreFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_REPLICAS, + &creplicaFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_TABLE, &ctabFileSize)) + cfileFileSize = (2 * ctabFileSize) + 2; initRecords(); - initialiseRecordsLab(signal, 0); + initialiseRecordsLab(signal, 0, ref, senderData); return; }//Dbdih::execSIZEALT_REP() @@ -1158,11 +1165,8 @@ void Dbdih::execNDB_STTOR(Signal* signal) Uint32 ownNodeId = signal->theData[1]; /* OWN PROCESSOR ID*/ Uint32 phase = signal->theData[2]; /* INTERNAL START PHASE*/ Uint32 typestart = signal->theData[3]; - const Uint32 tconfig1 = signal->theData[8]; - const Uint32 tconfig2 = signal->theData[9]; cstarttype = typestart; - cstartPhase = phase; switch (phase){ @@ -1171,10 +1175,6 @@ void Dbdih::execNDB_STTOR(Signal* signal) /*----------------------------------------------------------------------*/ /* Set the delay between local checkpoints in ndb startphase 1. */ /*----------------------------------------------------------------------*/ - c_lcpState.clcpDelay = tconfig1 > 31 ? 31 : tconfig1; - - cminHotSpareNodes = tconfig2 > 2 ? 2 : tconfig2; - cownNodeId = ownNodeId; /*-----------------------------------------------------------------------*/ // Compute all static block references in this node as part of @@ -1193,8 +1193,6 @@ void Dbdih::execNDB_STTOR(Signal* signal) // Set the number of replicas, maximum is 4 replicas. // Read the ndb nodes from the configuration. /*-----------------------------------------------------------------------*/ - cnoReplicas = tconfig1 > 4 ? 4 : tconfig1; - cgcpDelay = tconfig2 > 60000 ? 60000 : (tconfig2 < 10 ? 10 : tconfig2); /*-----------------------------------------------------------------------*/ // For node restarts we will also add a request for permission @@ -1261,7 +1259,7 @@ void Dbdih::execNDB_STTOR(Signal* signal) */ StartMeReq * req = (StartMeReq*)&signal->theData[0]; req->startingRef = reference(); - req->startingVersion = NDB_VERSION; + req->startingVersion = 0; // Obsolete sendSignal(cmasterdihref, GSN_START_MEREQ, signal, StartMeReq::SignalLength, JBB); return; @@ -1623,7 +1621,8 @@ void Dbdih::execSTART_PERMREQ(Signal* signal) c_nodeStartMaster.startInfoErrorCode = 0; c_nodeStartMaster.startNode = nodeId; c_nodeStartMaster.activeState = true; - + c_nodeStartMaster.m_outstandingGsn = GSN_START_INFOREQ; + setNodeStatus(nodeId, NodeRecord::STARTING); /** * But if it's a NodeState::ST_INITIAL_NODE_RESTART @@ -1704,13 +1703,11 @@ void Dbdih::execSTART_MEREQ(Signal* signal) jamEntry(); const BlockReference Tblockref = req->startingRef; const Uint32 Tnodeid = refToNode(Tblockref); - const Uint32 TndbVersion = req->startingVersion; ndbrequire(isMaster()); ndbrequire(c_nodeStartMaster.startNode == Tnodeid); ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING); - c_nodeStartMaster.ndbVersion = TndbVersion; sendSTART_RECREQ(signal, Tnodeid); }//Dbdih::execSTART_MEREQ() @@ -2011,7 +2008,6 @@ void Dbdih::execINCL_NODEREQ(Signal* signal) Uint32 retRef = signal->theData[0]; Uint32 nodeId = signal->theData[1]; Uint32 tnodeStartFailNr = signal->theData[2]; - Uint32 TndbVersion = signal->theData[3]; currentgcp = signal->theData[4]; CRASH_INSERTION(7127); cnewgcp = currentgcp; @@ -2063,7 +2059,6 @@ void Dbdih::execINCL_NODEREQ(Signal* signal) nodePtr.p->nodeStatus = NodeRecord::ALIVE; nodePtr.p->useInTransactions = true; nodePtr.p->m_inclDihLcp = true; - nodePtr.p->ndbversion = TndbVersion; removeDeadNode(nodePtr); insertAlive(nodePtr); @@ -3391,7 +3386,8 @@ void Dbdih::readGciFileLab(Signal* signal) filePtr.i = crestartInfoFile[0]; ptrCheckGuard(filePtr, cfileFileSize, fileRecord); filePtr.p->reqStatus = FileRecord::OPENING_GCP; - openFileRw(signal, filePtr); + + openFileRo(signal, filePtr); }//Dbdih::readGciFileLab() void Dbdih::openingGcpLab(Signal* signal, FileRecordPtr filePtr) @@ -3455,6 +3451,7 @@ void Dbdih::selectMasterCandidateAndSend(Signal* signal) signal->theData[0] = masterCandidateId; signal->theData[1] = gci; sendSignal(cntrlblockref, GSN_DIH_RESTARTCONF, signal, 2, JBB); + setNodeGroups(); }//Dbdih::selectMasterCandidate() /* ------------------------------------------------------------------------- */ @@ -3472,7 +3469,7 @@ void Dbdih::openingGcpErrorLab(Signal* signal, FileRecordPtr filePtr) /* --------------------------------------------------------------------- */ filePtr.i = crestartInfoFile[1]; ptrCheckGuard(filePtr, cfileFileSize, fileRecord); - openFileRw(signal, filePtr); + openFileRo(signal, filePtr); filePtr.p->reqStatus = FileRecord::OPENING_GCP; } else { jam(); @@ -3762,6 +3759,7 @@ void Dbdih::checkCopyTab(NodeRecordPtr failedNodePtr) c_COPY_TABREQ_Counter.clearWaitingFor(failedNodePtr.i); c_nodeStartMaster.wait = ZFALSE; break; + case GSN_START_INFOREQ: case GSN_START_PERMCONF: case GSN_DICTSTARTREQ: case GSN_START_MECONF: @@ -10863,6 +10861,26 @@ void Dbdih::initCommonData() c_nodeStartMaster.wait = ZFALSE; memset(&sysfileData[0], 0, sizeof(sysfileData)); + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + c_lcpState.clcpDelay = 20; + ndb_mgm_get_int_parameter(p, CFG_DB_LCP_INTERVAL, &c_lcpState.clcpDelay); + c_lcpState.clcpDelay = c_lcpState.clcpDelay > 31 ? 31 : c_lcpState.clcpDelay; + + cminHotSpareNodes = 0; + //ndb_mgm_get_int_parameter(p, CFG_DB_MIN_HOT_SPARES, &cminHotSpareNodes); + cminHotSpareNodes = cminHotSpareNodes > 2 ? 2 : cminHotSpareNodes; + + cnoReplicas = 1; + ndb_mgm_get_int_parameter(p, CFG_DB_NO_REPLICAS, &cnoReplicas); + cnoReplicas = cnoReplicas > 4 ? 4 : cnoReplicas; + + cgcpDelay = 2000; + ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay); + cgcpDelay = cgcpDelay > 60000 ? 60000 : (cgcpDelay < 10 ? 10 : cgcpDelay); }//Dbdih::initCommonData() void Dbdih::initFragstore(FragmentstorePtr fragPtr) @@ -10901,7 +10919,6 @@ void Dbdih::initNodeState(NodeRecordPtr nodePtr) nodePtr.p->nodeStatus = NodeRecord::NOT_IN_CLUSTER; nodePtr.p->useInTransactions = false; nodePtr.p->copyCompleted = false; - nodePtr.p->ndbversion = 0xffff; }//Dbdih::initNodeState() /*************************************************************************/ @@ -11070,44 +11087,43 @@ void Dbdih::initTableFile(TabRecordPtr tabPtr) /* --------------------------------------------------------------------- */ }//Dbdih::initTableFile() -void Dbdih::initialiseRecordsLab(Signal* signal, Uint32 stepNo) +void Dbdih::initialiseRecordsLab(Signal* signal, + Uint32 stepNo, Uint32 retRef, Uint32 retData) { switch (stepNo) { case 0: jam(); initCommonData(); break; - case 1: - { - ApiConnectRecordPtr apiConnectptr; - jam(); - /******** INTIALIZING API CONNECT RECORDS ********/ - for (apiConnectptr.i = 0; apiConnectptr.i < capiConnectFileSize; apiConnectptr.i++) { - ptrAss(apiConnectptr, apiConnectRecord); - apiConnectptr.p->nextApi = RNIL; - }//for - jam(); - break; - } - case 2: - { - ConnectRecordPtr connectPtr; - jam(); - /****** CONNECT ******/ - for (connectPtr.i = 0; connectPtr.i < cconnectFileSize; connectPtr.i++) { - ptrAss(connectPtr, connectRecord); - connectPtr.p->userpointer = RNIL; - connectPtr.p->userblockref = ZNIL; - connectPtr.p->connectState = ConnectRecord::FREE; - connectPtr.p->table = RNIL; - connectPtr.p->nfConnect = connectPtr.i + 1; - }//for - connectPtr.i = cconnectFileSize - 1; + case 1:{ + ApiConnectRecordPtr apiConnectptr; + jam(); + /******** INTIALIZING API CONNECT RECORDS ********/ + for (apiConnectptr.i = 0; apiConnectptr.i < capiConnectFileSize; apiConnectptr.i++) { + ptrAss(apiConnectptr, apiConnectRecord); + apiConnectptr.p->nextApi = RNIL; + }//for + jam(); + break; + } + case 2:{ + ConnectRecordPtr connectPtr; + jam(); + /****** CONNECT ******/ + for (connectPtr.i = 0; connectPtr.i < cconnectFileSize; connectPtr.i++) { ptrAss(connectPtr, connectRecord); - connectPtr.p->nfConnect = RNIL; - cfirstconnect = 0; - break; - } + connectPtr.p->userpointer = RNIL; + connectPtr.p->userblockref = ZNIL; + connectPtr.p->connectState = ConnectRecord::FREE; + connectPtr.p->table = RNIL; + connectPtr.p->nfConnect = connectPtr.i + 1; + }//for + connectPtr.i = cconnectFileSize - 1; + ptrAss(connectPtr, connectRecord); + connectPtr.p->nfConnect = RNIL; + cfirstconnect = 0; + break; + } case 3: { FileRecordPtr filePtr; @@ -11208,8 +11224,12 @@ void Dbdih::initialiseRecordsLab(Signal* signal, Uint32 stepNo) initTakeOver(takeOverPtr); releaseTakeOver(takeOverPtr.i); }//for - signal->theData[0] = DBDIH_REF; - sendSignal(CMVMI_REF, GSN_SIZEALT_ACK, signal, 2, JBB); + + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = retData; + sendSignal(retRef, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); return; break; } @@ -11218,12 +11238,14 @@ void Dbdih::initialiseRecordsLab(Signal* signal, Uint32 stepNo) break; }//switch jam(); - /* ------------------------------------------------------------------------- */ - /* SEND REAL-TIME BREAK DURING INIT OF VARIABLES DURING SYSTEM RESTART. */ - /* ------------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------- */ + /* SEND REAL-TIME BREAK DURING INIT OF VARIABLES DURING SYSTEM RESTART. */ + /* ---------------------------------------------------------------------- */ signal->theData[0] = DihContinueB::ZINITIALISE_RECORDS; signal->theData[1] = stepNo + 1; - sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB); + signal->theData[2] = retRef; + signal->theData[3] = retData; + sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB); }//Dbdih::initialiseRecordsLab() /*************************************************************************/ @@ -11512,8 +11534,6 @@ void Dbdih::makePrnList(ReadNodesConf * readNodes, Uint32 nodeArray[]) nodePtr.p->nodeStatus = NodeRecord::DEAD; insertDeadNode(nodePtr); }//if - nodePtr.p->ndbversion = readNodes->getVersionId(nodePtr.i, - readNodes->theVersionIds); }//for }//Dbdih::makePrnList() @@ -11563,7 +11583,19 @@ void Dbdih::openFileRw(Signal* signal, FileRecordPtr filePtr) signal->theData[3] = filePtr.p->fileName[1]; signal->theData[4] = filePtr.p->fileName[2]; signal->theData[5] = filePtr.p->fileName[3]; - signal->theData[6] = ZOPEN_READ_WRITE; + signal->theData[6] = FsOpenReq::OM_READWRITE; + sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA); +}//Dbdih::openFileRw() + +void Dbdih::openFileRo(Signal* signal, FileRecordPtr filePtr) +{ + signal->theData[0] = reference(); + signal->theData[1] = filePtr.i; + signal->theData[2] = filePtr.p->fileName[0]; + signal->theData[3] = filePtr.p->fileName[1]; + signal->theData[4] = filePtr.p->fileName[2]; + signal->theData[5] = filePtr.p->fileName[3]; + signal->theData[6] = FsOpenReq::OM_READONLY; sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA); }//Dbdih::openFileRw() @@ -12502,7 +12534,10 @@ void Dbdih::setNodeGroups() }//for for (sngNodeptr.i = 1; sngNodeptr.i < MAX_NDB_NODES; sngNodeptr.i++) { ptrAss(sngNodeptr, nodeRecord); - switch (sngNodeptr.p->activeStatus) { + Sysfile::ActiveStatus s = + (Sysfile::ActiveStatus)Sysfile::getNodeStatus(sngNodeptr.i, + SYSFILE->nodeStatus); + switch (s){ case Sysfile::NS_Active: case Sysfile::NS_ActiveMissed_1: case Sysfile::NS_ActiveMissed_2: @@ -12911,8 +12946,7 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal) cnoHotSpare, c_nodeStartMaster.startNode, c_nodeStartMaster.wait); }//if if (signal->theData[0] == 7007) { - infoEvent("c_nodeStartMaster.failNr = %d, c_nodeStartMaster.ndbVersion = %d", - c_nodeStartMaster.failNr, c_nodeStartMaster.ndbVersion); + infoEvent("c_nodeStartMaster.failNr = %d", c_nodeStartMaster.failNr); infoEvent("c_nodeStartMaster.startInfoErrorCode = %d", c_nodeStartMaster.startInfoErrorCode); infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d", @@ -13326,6 +13360,25 @@ Dbdih::checkPrepDropTabComplete(Signal* signal, TabRecordPtr tabPtr){ } void +Dbdih::execWAIT_DROP_TAB_REF(Signal* signal){ + jamEntry(); + WaitDropTabRef * ref = (WaitDropTabRef*)signal->getDataPtr(); + + TabRecordPtr tabPtr; + tabPtr.i = ref->tableId; + ptrCheckGuard(tabPtr, ctabFileSize, tabRecord); + + ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING); + Uint32 nodeId = refToNode(ref->senderRef); + + ndbrequire(ref->errorCode == WaitDropTabRef::NoSuchTable || + ref->errorCode == WaitDropTabRef::NF_FakeErrorREF); + + tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor(nodeId); + checkPrepDropTabComplete(signal, tabPtr); +} + +void Dbdih::execWAIT_DROP_TAB_CONF(Signal* signal){ jamEntry(); WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr(); @@ -13391,7 +13444,7 @@ Dbdih::execNDB_TAMPER(Signal* signal) }//Dbdih::execNDB_TAMPER() void Dbdih::execSET_VAR_REQ(Signal* signal) { - +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); int val = setVarReq->value(); @@ -13411,6 +13464,7 @@ void Dbdih::execSET_VAR_REQ(Signal* signal) { default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); } // switch +#endif } void Dbdih::execBLOCK_COMMIT_ORD(Signal* signal){ diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index ed1c0414d18..824f74c59af 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -2109,7 +2109,7 @@ private: void execCHECK_LCP_STOP(Signal* signal); void execSEND_PACKED(Signal* signal); void execTUP_ATTRINFO(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); void execLQHFRAGREQ(Signal* signal); void execLQHADDATTREQ(Signal* signal); void execTUP_ADD_ATTCONF(Signal* signal); @@ -2328,7 +2328,6 @@ private: void initialiseLogPage(Signal* signal); void initialiseLogPart(Signal* signal); void initialisePageRef(Signal* signal); - void sendInitialiseRecords(Signal* signal, Uint32 data); void initialiseScanrec(Signal* signal); void initialiseTabrec(Signal* signal); void initialiseTcrec(Signal* signal); @@ -2462,7 +2461,6 @@ private: void closeCopyRequestLab(Signal* signal); void closeScanRequestLab(Signal* signal); void scanTcConnectLab(Signal* signal, Uint32 startTcCon, Uint32 fragId); - void returnInitialiseRecordsLab(Signal* signal); void initGcpRecLab(Signal* signal); void prepareContinueAfterBlockedLab(Signal* signal); void commitContinueAfterBlockedLab(Signal* signal); @@ -2479,7 +2477,7 @@ private: void accFragRefLab(Signal* signal); void rwConcludedLab(Signal* signal); void sendsttorryLab(Signal* signal); - void initialiseRecordsLab(Signal* signal, Uint32 data); + void initialiseRecordsLab(Signal* signal, Uint32 data, Uint32, Uint32); void startphase2Lab(Signal* signal, Uint32 config); void startphase3Lab(Signal* signal); void startphase4Lab(Signal* signal); diff --git a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp index cb1698ec8c0..d5f40ec143c 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp @@ -220,7 +220,7 @@ Dblqh::Dblqh(const class Configuration & conf): addRecSignal(GSN_CHECK_LCP_STOP, &Dblqh::execCHECK_LCP_STOP); addRecSignal(GSN_SEND_PACKED, &Dblqh::execSEND_PACKED); addRecSignal(GSN_TUP_ATTRINFO, &Dblqh::execTUP_ATTRINFO); - addRecSignal(GSN_SIZEALT_REP, &Dblqh::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dblqh::execREAD_CONFIG_REQ, true); addRecSignal(GSN_LQHFRAGREQ, &Dblqh::execLQHFRAGREQ); addRecSignal(GSN_LQHADDATTREQ, &Dblqh::execLQHADDATTREQ); addRecSignal(GSN_TUP_ADD_ATTCONF, &Dblqh::execTUP_ADD_ATTCONF); diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 6cc72d2f0ab..463a3d47354 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -32,14 +32,12 @@ #include <signaldata/GCPSave.hpp> #include <signaldata/TcKeyRef.hpp> #include <signaldata/LqhKey.hpp> -#include <signaldata/LqhSizeAltReq.hpp> #include <signaldata/NextScan.hpp> #include <signaldata/NFCompleteRep.hpp> #include <signaldata/NodeFailRep.hpp> #include <signaldata/ReadNodesConf.hpp> #include <signaldata/RelTabMem.hpp> #include <signaldata/ScanFrag.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/SrFragidConf.hpp> #include <signaldata/StartFragReq.hpp> #include <signaldata/StartRec.hpp> @@ -333,7 +331,7 @@ void Dblqh::execCONTINUEB(Signal* signal) break; case ZINITIALISE_RECORDS: jam(); - initialiseRecordsLab(signal, data0); + initialiseRecordsLab(signal, data0, data2, signal->theData[4]); return; break; case ZINIT_GCP_REC: @@ -467,7 +465,6 @@ void Dblqh::execNDB_STTOR(Signal* signal) Uint32 ownNodeId = signal->theData[1]; /* START PHASE*/ cstartPhase = signal->theData[2]; /* MY NODE ID */ cstartType = signal->theData[3]; /* START TYPE */ - Uint32 config1 = signal->theData[10]; /* CONFIG INFO LQH */ switch (cstartPhase) { case ZSTART_PHASE1: @@ -488,7 +485,7 @@ void Dblqh::execNDB_STTOR(Signal* signal) // Dont setAPIVersion LqhKeyReq::setMarkerFlag(preComputedRequestInfoMask, 1); //preComputedRequestInfoMask = 0x003d7fff; - startphase1Lab(signal, config1, ownNodeId); + startphase1Lab(signal, /* dummy */ ~0, ownNodeId); signal->theData[0] = ZOPERATION_EVENT_REP; signal->theData[1] = 1; @@ -497,7 +494,7 @@ void Dblqh::execNDB_STTOR(Signal* signal) break; case ZSTART_PHASE2: jam(); - startphase2Lab(signal, config1); + startphase2Lab(signal, /* dummy */ ~0); return; break; case ZSTART_PHASE3: @@ -539,17 +536,12 @@ void Dblqh::sttorStartphase1Lab(Signal* signal) /* */ /* INITIATE ALL RECORDS WITHIN THE BLOCK */ /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ -void Dblqh::startphase1Lab(Signal* signal, Uint32 config, Uint32 ownNodeId) +void Dblqh::startphase1Lab(Signal* signal, Uint32 _dummy, Uint32 ownNodeId) { UintR Ti; HostRecordPtr ThostPtr; /* ------- INITIATE ALL RECORDS ------- */ - if (config == 0) { - jam(); - config = 1; - }//if - cnoLogFiles = config; cownNodeid = ownNodeId; caccBlockref = calcAccBlockRef (cownNodeid); ctupBlockref = calcTupBlockRef (cownNodeid); @@ -576,15 +568,8 @@ void Dblqh::startphase1Lab(Signal* signal, Uint32 config, Uint32 ownNodeId) /* EVERY CONNECTION RECORD IN LQH IS ASSIGNED TO ONE ACC CONNECTION RECORD */ /* AND ONE TUP CONNECTION RECORD. */ /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ -void Dblqh::startphase2Lab(Signal* signal, Uint32 config) +void Dblqh::startphase2Lab(Signal* signal, Uint32 _dummy) { - if (config == 0) { - jam(); - config = 1; - } else if (config > 4) { - jam(); - config = 4; - }//if cmaxWordsAtNodeRec = MAX_NO_WORDS_OUTSTANDING_COPY_FRAGMENT; /* -- ACC AND TUP CONNECTION PROCESS -- */ tcConnectptr.i = 0; @@ -836,30 +821,38 @@ void Dblqh::execREAD_NODESREF(Signal* signal) /* *************** */ /* SIZEALT_REP > */ /* *************** */ -void Dblqh::execSIZEALT_REP(Signal* signal) +void Dblqh::execREAD_CONFIG_REQ(Signal* signal) { + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + jamEntry(); - cfragrecFileSize = signal->theData[LqhSizeAltReq::IND_FRAG]; - ctabrecFileSize = signal->theData[LqhSizeAltReq::IND_TABLE]; - ctcConnectrecFileSize = signal->theData[LqhSizeAltReq::IND_TC_CONNECT]; - clogFileFileSize = signal->theData[LqhSizeAltReq::IND_LOG_FILES]; - cscanrecFileSize = signal->theData[LqhSizeAltReq::IND_SCAN]; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + cnoLogFiles = 8; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_REDOLOG_FILES, + &cnoLogFiles)); + ndbrequire(cnoLogFiles > 0); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_FRAG, &cfragrecFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_TABLE, &ctabrecFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_TC_CONNECT, + &ctcConnectrecFileSize)); + clogFileFileSize = 4 * cnoLogFiles; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_SCAN, &cscanrecFileSize)); cmaxAccOps = cscanrecFileSize * MAX_PARALLEL_SCANS_PER_FRAG; + initRecords(); - initialiseRecordsLab(signal, 0); + initialiseRecordsLab(signal, 0, ref, senderData); return; }//Dblqh::execSIZEALT_REP() -void Dblqh::returnInitialiseRecordsLab(Signal* signal) -{ - signal->theData[0] = DBLQH_REF; - sendSignal(CMVMI_REF, GSN_SIZEALT_ACK, signal, 2, JBB); - - - return; -}//Dblqh::returnInitialiseRecordsLab() - /* ########################################################################## */ /* ####### ADD/DELETE FRAGMENT MODULE ####### */ /* THIS MODULE IS USED BY DICTIONARY TO CREATE NEW FRAGMENTS AND DELETE */ @@ -3203,10 +3196,14 @@ void Dblqh::execLQHKEYREQ(Signal* signal) const NodeId tcNodeId = refToNode(sig5); markerPtr.p->tcNodeId = tcNodeId; + CommitAckMarkerPtr tmp; +#ifdef VM_TRACE + ndbrequire(!m_commitAckMarkerHash.find(tmp, * markerPtr.p)); +#endif m_commitAckMarkerHash.add(markerPtr); regTcPtr->commitAckMarker = markerPtr.i; - } - + } + regTcPtr->reqinfo = Treqinfo; regTcPtr->lastReplicaNo = LqhKeyReq::getLastReplicaNo(Treqinfo); regTcPtr->lockType = LqhKeyReq::getLockType(Treqinfo); @@ -7857,27 +7854,10 @@ void Dblqh::scanTupkeyConfLab(Signal* signal) }//if if (scanptr.p->scanKeyinfoFlag) { jam(); - DatabufPtr TdataBuf; - TdataBuf.i = tcConnectptr.p->firstTupkeybuf; - const Uint32 keyLen = tcConnectptr.p->primKeyLen; - const Uint32 dataBufSz = cdatabufFileSize; - - /** - * Note that this code requires signal->theData to be big enough for - * a entire key - */ - ndbrequire(keyLen * 4 <= sizeof(signal->theData)); - KeyInfo20 * keyInfo = (KeyInfo20*)&signal->theData[0]; - for(Uint32 i = 0; i < keyLen; i += 4){ - ptrCheckGuard(TdataBuf, dataBufSz, databuf); - keyInfo->keyData[i + 0] = TdataBuf.p->data[0]; - keyInfo->keyData[i + 1] = TdataBuf.p->data[1]; - keyInfo->keyData[i + 2] = TdataBuf.p->data[2]; - keyInfo->keyData[i + 3] = TdataBuf.p->data[3]; - TdataBuf.i = TdataBuf.p->nextDatabuf; - } sendKeyinfo20(signal, scanptr.p, tcConnectptr.p); releaseOprec(signal); + + tdata4 += tcConnectptr.p->primKeyLen;// Inform API about keyinfo len aswell }//if ndbrequire(scanptr.p->scanCompletedOperations < MAX_PARALLEL_OP_PER_SCAN); scanptr.p->scanOpLength[scanptr.p->scanCompletedOperations] = tdata4; @@ -8313,7 +8293,8 @@ void Dblqh::initScanTc(Signal* signal, tcConnectptr.p->opExec = 1; tcConnectptr.p->operation = ZREAD; tcConnectptr.p->listState = TcConnectionrec::NOT_IN_LIST; - + tcConnectptr.p->commitAckMarker = RNIL; + tabptr.p->usageCount++; }//Dblqh::initScanTc() @@ -8417,72 +8398,119 @@ void Dblqh::sendKeyinfo20(Signal* signal, ndbrequire(scanP->scanCompletedOperations < MAX_PARALLEL_OP_PER_SCAN); KeyInfo20 * keyInfo = (KeyInfo20 *)&signal->theData[0]; + DatabufPtr TdataBuf; + TdataBuf.i = tcConP->firstTupkeybuf; + Uint32 keyLen = tcConP->primKeyLen; + const Uint32 dataBufSz = cdatabufFileSize; + + /** + * Note that this code requires signal->theData to be big enough for + * a entire key + */ + ndbrequire(keyLen * 4 <= sizeof(signal->theData)); + const BlockReference ref = scanP->scanApiBlockref; const Uint32 scanOp = scanP->scanCompletedOperations; + const Uint32 nodeId = refToNode(ref); + const bool connectedToNode = getNodeInfo(nodeId).m_connected; + const Uint32 type = getNodeInfo(nodeId).m_type; + const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::REP); + const bool old_dest = (getNodeInfo(nodeId).m_version < MAKE_VERSION(3,5,0)); + const bool longable = is_api && !old_dest; + + Uint32 * dst = keyInfo->keyData; + dst += nodeId == getOwnNodeId() ? 0 : KeyInfo20::DataLength; + + /** + * Copy keydata from data buffer into signal + * + */ + for(Uint32 i = 0; i < keyLen; i += 4){ + ptrCheckGuard(TdataBuf, dataBufSz, databuf); + * dst++ = TdataBuf.p->data[0]; + * dst++ = TdataBuf.p->data[1]; + * dst++ = TdataBuf.p->data[2]; + * dst++ = TdataBuf.p->data[3]; + TdataBuf.i = TdataBuf.p->nextDatabuf; + } + keyInfo->clientOpPtr = scanP->scanApiOpPtr[scanOp]; - keyInfo->keyLen = tcConP->primKeyLen; + keyInfo->keyLen = keyLen; keyInfo->scanInfo_Node = KeyInfo20::setScanInfo(scanOp, scanP->scanNumber)+ (getOwnNodeId() << 16); - keyInfo->transId1 = tcConP->transid[0]; keyInfo->transId2 = tcConP->transid[1]; - - const BlockReference ref = scanP->scanApiBlockref; - const Uint32 keyLen = tcConP->primKeyLen; - if(refToNode(ref) == getOwnNodeId()){ + + Uint32 * src = signal->theData+25; + if(connectedToNode){ jam(); - EXECUTE_DIRECT(refToBlock(ref), GSN_KEYINFO20, signal, 5 + keyLen); + + if(nodeId != getOwnNodeId()){ + jam(); + + if(keyLen <= KeyInfo20::DataLength || !longable) { + while(keyLen > KeyInfo20::DataLength){ + jam(); + MEMCOPY_NO_WORDS(keyInfo->keyData, src, KeyInfo20::DataLength); + sendSignal(ref, GSN_KEYINFO20, signal, 25, JBB); + src += KeyInfo20::DataLength;; + keyLen -= KeyInfo20::DataLength; + } while(keyLen >= KeyInfo20::DataLength); + + MEMCOPY_NO_WORDS(keyInfo->keyData, src, keyLen); + sendSignal(ref, GSN_KEYINFO20, signal, + KeyInfo20::HeaderLength+keyLen, JBB); + return; + } + + LinearSectionPtr ptr[3]; + ptr[0].p = src; + ptr[0].sz = keyLen; + sendSignal(ref, GSN_KEYINFO20, signal, KeyInfo20::HeaderLength, + JBB, ptr, 1); + return; + } + + EXECUTE_DIRECT(refToBlock(ref), GSN_KEYINFO20, signal, 3 + keyLen); jamEntry(); return; - } - - bool connectedToNode = getNodeInfo(refToNode(ref)).m_connected; - - if (ERROR_INSERTED(5029)){ - // Use error insert to turn routing on - jam(); - connectedToNode = false; } - if (connectedToNode){ - jam(); - Uint32 keyLenLeft = keyLen; - Uint32 keyDataIndex = 20; - for(; keyLenLeft > 20; keyLenLeft -= 20, keyDataIndex += 20){ - jam(); - sendSignal(ref, GSN_KEYINFO20, signal, 25, JBB); - for(Uint32 i = 0; i<20; i++) - keyInfo->keyData[i] = keyInfo->keyData[keyDataIndex + i]; - }//for - sendSignal(ref, GSN_KEYINFO20, signal, 5 + keyLenLeft, JBB); - } else { - /** - * If this node does not have a direct connection - * to the receiving node we want to send the signals - * routed via the control node - */ + /** + * If this node does not have a direct connection + * to the receiving node we want to send the signals + * routed via the node that controls this read + */ + Uint32 routeBlockref = tcConP->clientBlockref; + + if(keyLen < KeyInfo20::DataLength || !longable){ jam(); - Uint32 keyLenLeft = keyLen; - Uint32 keyDataIndex = 19; - BlockReference routeBlockref = tcConP->clientBlockref; - for(; keyLenLeft > 19; keyLenLeft -= 19, keyDataIndex += 19){ - jam(); - // store final destination, but save original value - Uint32 saveOne = keyInfo->keyData[19]; - keyInfo->keyData[19] = ref; + while (keyLen > (KeyInfo20::DataLength - 1)) { + jam(); + MEMCOPY_NO_WORDS(keyInfo->keyData, src, KeyInfo20::DataLength - 1); + keyInfo->keyData[KeyInfo20::DataLength-1] = ref; sendSignal(routeBlockref, GSN_KEYINFO20_R, signal, 25, JBB); - keyInfo->keyData[19] = saveOne; - for(Uint32 i = 0; i<19; i++){ - keyInfo->keyData[i] = keyInfo->keyData[keyDataIndex + i]; - } - }//for - keyInfo->keyData[keyLenLeft] = ref; - sendSignal(routeBlockref, GSN_KEYINFO20_R, signal, 5 + keyLenLeft + 1, JBB); - } + src += KeyInfo20::DataLength - 1; + keyLen -= KeyInfo20::DataLength - 1; + } -}//Dblqh::sendKeyinfo20() + MEMCOPY_NO_WORDS(keyInfo->keyData, src, keyLen); + keyInfo->keyData[keyLen] = ref; + sendSignal(routeBlockref, GSN_KEYINFO20_R, signal, + KeyInfo20::HeaderLength+keyLen+1, JBB); + return; + } + keyInfo->keyData[0] = ref; + LinearSectionPtr ptr[3]; + ptr[0].p = src; + ptr[0].sz = keyLen; + sendSignal(routeBlockref, GSN_KEYINFO20_R, signal, + KeyInfo20::HeaderLength+1, JBB, ptr, 1); + return; +} + /* ------------------------------------------------------------------------ * ------- SEND SCAN_FRAGCONF TO TC THAT CONTROLS THE SCAN ------- * @@ -8863,7 +8891,7 @@ void Dblqh::execTRANSID_AI(Signal* signal) ndbrequire(tcConnectptr.p->transactionState == TcConnectionrec::COPY_TUPKEY); Uint32 * src = &signal->theData[3]; while(length > 22){ - if (saveTupattrbuf(signal, &signal->theData[3], 22) == ZOK) { + if (saveTupattrbuf(signal, src, 22) == ZOK) { ; } else { jam(); @@ -16032,7 +16060,8 @@ void Dblqh::initialisePageRef(Signal* signal) * * TAKES CARE OF INITIATION OF ALL RECORDS IN THIS BLOCK. * ========================================================================= */ -void Dblqh::initialiseRecordsLab(Signal* signal, Uint32 data) +void Dblqh::initialiseRecordsLab(Signal* signal, Uint32 data, + Uint32 retRef, Uint32 retData) { switch (data) { case 0: @@ -16070,90 +16099,81 @@ void Dblqh::initialiseRecordsLab(Signal* signal, Uint32 data) csrExecUndoLogState = EULS_IDLE; c_lcpId = 0; cnoOfFragsCheckpointed = 0; - sendInitialiseRecords(signal, data); break; case 1: jam(); initialiseAddfragrec(signal); - sendInitialiseRecords(signal, data); break; case 2: jam(); initialiseAttrbuf(signal); - sendInitialiseRecords(signal, data); break; case 3: jam(); initialiseDatabuf(signal); - sendInitialiseRecords(signal, data); break; case 4: jam(); initialiseFragrec(signal); - sendInitialiseRecords(signal,data); break; case 5: jam(); initialiseGcprec(signal); initialiseLcpRec(signal); initialiseLcpLocrec(signal); - sendInitialiseRecords(signal, data); break; case 6: jam(); initialiseLogPage(signal); - sendInitialiseRecords(signal, data); break; case 7: jam(); initialiseLfo(signal); - sendInitialiseRecords(signal, data); break; case 8: jam(); initialiseLogFile(signal); initialiseLogPart(signal); - sendInitialiseRecords(signal, data); break; case 9: jam(); initialisePageRef(signal); - sendInitialiseRecords(signal, data); break; case 10: jam(); initialiseScanrec(signal); - sendInitialiseRecords(signal, data); break; case 11: jam(); initialiseTabrec(signal); - sendInitialiseRecords(signal, data); break; case 12: jam(); initialiseTcNodeFailRec(signal); initialiseTcrec(signal); - returnInitialiseRecordsLab(signal); + { + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = retData; + sendSignal(retRef, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); + } return; break; default: ndbrequire(false); break; }//switch - return; -}//Dblqh::initialiseRecordsLab() -/* -------------------------------------------------------------------------- - * SEND REAL-TIME BREAK SIGNAL DURING INITIALISATION IN SYSTEM RESTART. - * ------------------------------------------------------------------------- */ -void Dblqh::sendInitialiseRecords(Signal* signal, Uint32 data) -{ signal->theData[0] = ZINITIALISE_RECORDS; signal->theData[1] = data + 1; signal->theData[2] = 0; - sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 3, JBB); -}//Dblqh::sendInitialiseRecords() + signal->theData[3] = retRef; + signal->theData[4] = retData; + sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 5, JBB); + + return; +}//Dblqh::initialiseRecordsLab() /* ========================================================================== * ======= INITIATE TC CONNECTION RECORD ======= @@ -18020,7 +18040,7 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal) void Dblqh::execSET_VAR_REQ(Signal* signal) { - +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); @@ -18038,7 +18058,7 @@ void Dblqh::execSET_VAR_REQ(Signal* signal) default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); } // switch - +#endif }//execSET_VAR_REQ() diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index 3fc79120942..61e7e42621c 100644 --- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -955,7 +955,6 @@ public: LqhTransState lqhTransStatus; TakeOverState takeOverStatus; bool inPackedList; - UintR ndbVersion; UintR noOfPackedWordsLqh; UintR packedWordsLqh[26]; UintR noOfWordsTCKEYCONF; @@ -994,11 +993,89 @@ public: typedef Ptr<TableRecord> TableRecordPtr; /** + * There is max 16 ScanFragRec's for + * each scan started in TC. Each ScanFragRec is used by + * a scan fragment "process" that scans one fragment at a time. + * It will receive max 16 tuples in each request + */ + struct ScanFragRec { + ScanFragRec(){} + /** + * ScanFragState + * WAIT_GET_PRIMCONF : Waiting for DIGETPRIMCONF when starting a new + * fragment scan + * LQH_ACTIVE : The scan process has sent a command to LQH and is + * waiting for the response + * LQH_ACTIVE_CLOSE : The scan process has sent close to LQH and is + * waiting for the response + * DELIVERED : The result have been delivered, this scan frag process + * are waiting for a SCAN_NEXTREQ to tell us to continue scanning + * RETURNING_FROM_DELIVERY : SCAN_NEXTREQ received and continuing scan + * soon + * QUEUED_FOR_DELIVERY : Result queued in TC and waiting for delivery + * to API + * COMPLETED : The fragment scan processes has completed and finally + * sent a SCAN_PROCCONF + */ + enum ScanFragState { + IDLE = 0, + WAIT_GET_PRIMCONF = 1, + LQH_ACTIVE = 2, + DELIVERED = 4, + QUEUED_FOR_DELIVERY = 6, + COMPLETED = 7 + }; + // Timer for checking timeout of this fragment scan + Uint32 scanFragTimer; + + // Id of the current scanned fragment + Uint32 scanFragId; + + // Blockreference of LQH + BlockReference lqhBlockref; + + // getNodeInfo.m_connectCount, set at seize used so that + // I don't accidently kill a starting node + Uint32 m_connectCount; + + // State of this fragment scan + ScanFragState scanFragState; + + // Id of the ScanRecord this fragment scan belongs to + Uint32 scanRec; + + // The maximum number of operations that can be scanned before + // returning to TC + Uint16 scanFragConcurrency; + + inline void startFragTimer(Uint32 timeVal){ + scanFragTimer = timeVal; + } + inline void stopFragTimer(void){ + scanFragTimer = 0; + } + + Uint32 m_ops; + Uint32 m_chksum; + Uint32 m_apiPtr; + Uint32 m_totalLen; + union { + Uint32 nextPool; + Uint32 nextList; + }; + Uint32 prevList; + }; + + typedef Ptr<ScanFragRec> ScanFragRecPtr; + typedef LocalDLList<ScanFragRec> ScanFragList; + + /** * Each scan allocates one ScanRecord to store information * about the current scan * */ struct ScanRecord { + ScanRecord() {} /** NOTE! This is the old comment for ScanState. - MASV * STATE TRANSITIONS OF SCAN_STATE. SCAN_STATE IS THE STATE * VARIABLE OF THE RECEIVE AND DELIVERY PROCESS. @@ -1058,161 +1135,68 @@ public: WAIT_SCAN_TAB_INFO = 1, WAIT_AI = 2, WAIT_FRAGMENT_COUNT = 3, - SCAN_NEXT_ORDERED = 4, - QUEUED_DELIVERED = 5, - DELIVERED = 6, - CLOSING_SCAN = 7 + RUNNING = 4, + CLOSING_SCAN = 5 }; + // State of this scan ScanState scanState; - // References to ScanFragRecs - Uint32 scanFragrec[16]; - // Refrences to ScanOperationRecords - Uint32 scanOprec[16]; - // Number of ScanOperationRecords allocated - Uint32 noScanOprec; + + DLList<ScanFragRec>::Head m_running_scan_frags; // Currently in LQH + union { Uint32 m_queued_count; Uint32 scanReceivedOperations; }; + DLList<ScanFragRec>::Head m_queued_scan_frags; // In TC !sent to API + DLList<ScanFragRec>::Head m_delivered_scan_frags;// Delivered to API + DLList<ScanFragRec>::Head m_completed_scan_frags;// Completed + // Id of the next fragment to be scanned. Used by scan fragment // processes when they are ready for the next fragment Uint32 scanNextFragId; + // Total number of fragments in the table we are scanning Uint32 scanNoFrag; + // Index of next ScanRecords when in free list Uint32 nextScan; + // Length of expected attribute information Uint32 scanAiLength; + // Reference to ApiConnectRecord Uint32 scanApiRec; + // Reference to TcConnectRecord Uint32 scanTcrec; + // Number of scan frag processes that belong to this scan Uint32 scanParallel; - // The number of recieved operations so far - Uint32 scanReceivedOperations; + // Schema version used by this scan Uint32 scanSchemaVersion; + // Index of stored procedure belonging to this scan Uint32 scanStoredProcId; + // The index of table that is scanned Uint32 scanTableref; + // Number of operation records per scanned fragment Uint16 noOprecPerFrag; - // The number of SCAN_TABINFO to receive - Uint16 noScanTabInfo; - // The number of SCAN_TABINFO received so far - Uint16 scanTabInfoReceived; - // apiIsClosed indicates if it's ok to release all resources - // and send a response to the API - // If it's false resources should not be released wait for API - // to close the scan - bool apiIsClosed; - // The number of scan frag processes that have completed their task - Uint8 scanProcessesCompleted; - // This variable is ZFALSE as long as any scan process is still alive - // It is ZTRUE as soon as all scan processes have been stopped - Uint8 scanCompletedStatus; + // Shall the locks be held until the application have read the // records Uint8 scanLockHold; + // Shall the locks be read or write locks Uint8 scanLockMode; + // Skip locks by other transactions and read latest committed Uint8 readCommitted; + // Scan is on ordered index Uint8 rangeScan; }; typedef Ptr<ScanRecord> ScanRecordPtr; - /** - * Each scan has max 16 ScanOperationRecords - * they are used for storing data to be sent to the api - */ - struct ScanOperationRecord { - // Reference to the scan operation in api - Uint32 apiOpptr[16]; - // Index and length of all recieved operations - // They will be cached here until SCAN_TABCONF is sent to api - Uint32 scanOpLength[16]; - // Next ScanOperationRecord when in free list - Uint32 nextScanOp; - }; /* p2c: size = 132 bytes */ - - typedef Ptr<ScanOperationRecord> ScanOperationRecordPtr; - - /** - * There is max 16 ScanFragRec's for - * each scan started in TC. Each ScanFragRec is used by - * a scan fragment "process" that scans one fragment at a time. - * It will receive max 16 tuples in each request - */ - struct ScanFragRec { - /** - * ScanFragState - * WAIT_GET_PRIMCONF : Waiting for DIGETPRIMCONF when starting a new - * fragment scan - * LQH_ACTIVE : The scan process has sent a command to LQH and is - * waiting for the response - * LQH_ACTIVE_CLOSE : The scan process has sent close to LQH and is - * waiting for the response - * DELIVERED : The result have been delivered, this scan frag process - * are waiting for a SCAN_NEXTREQ to tell us to continue scanning - * RETURNING_FROM_DELIVERY : SCAN_NEXTREQ received and continuing scan - * soon - * QUEUED_FOR_DELIVERY : Result queued in TC and waiting for delivery - * to API - * COMPLETED : The fragment scan processes has completed and finally - * sent a SCAN_PROCCONF - */ - enum ScanFragState { - IDLE = 0, - WAIT_GET_PRIMCONF = 1, - LQH_ACTIVE = 2, - LQH_ACTIVE_CLOSE = 3, - DELIVERED = 4, - RETURNING_FROM_DELIVERY = 5, - QUEUED_FOR_DELIVERY = 6, - COMPLETED = 7 - }; - // Timer for checking timeout of this fragment scan - Uint32 scanFragTimer; - // Id of the current scanned fragment - Uint32 scanFragId; - // Blockreference of LQH - BlockReference lqhBlockref; - // getNodeInfo.m_connectCount, set at seize used so that - // I don't accidently kill a starting node - Uint32 m_connectCount; - // State of this fragment scan - ScanFragState scanFragState; - // Id of the ScanRecord this fragment scan belongs to - Uint32 scanRec; - // Index of next ScanFragRec, when in list of - // free ScanFragRec's - Uint32 nextScanFrag; - // Process id of this scan process within the total scan - Uint32 scanFragProcId; - // Node where current fragment resides - NodeId scanFragNodeId; - // Index of where to store the result in ScanRecord - Uint16 scanIndividual; - // The maximum number of operations that can be scanned before - // returning to TC - Uint16 scanFragConcurrency; - // Current status of the fragment scan - // * 0 = NOT COMPLETED - // * 1 = COMPLETED - // * 2 = CLOSED - Uint8 scanFragCompletedStatus; - - inline void startFragTimer(Uint32 timeVal){ - scanFragTimer = timeVal; - } - inline void stopFragTimer(void){ - scanFragTimer = 0; - } - }; - - typedef Ptr<ScanFragRec> ScanFragRecPtr; - /* **********************************************************************$ */ /* ******$ DATA BUFFER ******$ */ /* */ @@ -1336,7 +1320,7 @@ private: void execSCAN_TABINFO(Signal* signal); void execSCAN_FRAGCONF(Signal* signal); void execSCAN_FRAGREF(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); void execLQH_TRANSCONF(Signal* signal); void execCOMPLETECONF(Signal* signal); void execCOMMITCONF(Signal* signal); @@ -1370,6 +1354,7 @@ private: void execCREATE_TAB_REQ(Signal* signal); void execPREP_DROP_TAB_REQ(Signal* signal); void execDROP_TAB_REQ(Signal* signal); + void execWAIT_DROP_TAB_REF(Signal* signal); void execWAIT_DROP_TAB_CONF(Signal* signal); void checkWaitDropTabFailedLqh(Signal*, Uint32 nodeId, Uint32 tableId); void execALTER_TAB_REQ(Signal* signal); @@ -1429,23 +1414,17 @@ private: Uint32 buddyPtr, UintR transid1, UintR transid2); - void initScanOprec(Signal* signal); void initScanrec(Signal* signal, const UintR scanParallel, const UintR noOprecPerFrag); void initScanfragrec(Signal* signal); - void releaseScanrec(Signal* signal); - void releaseScanResources(Signal* signal); - void releaseScanFragrec(Signal* signal); - void releaseScanOprec(Signal* signal); + void releaseScanResources(ScanRecordPtr); void seizeScanrec(Signal* signal); - void seizeScanFragrec(Signal* signal); - void seizeScanOprec(Signal* signal); void sendScanFragReq(Signal* signal); void sendScanTabConf(Signal* signal); - void sendScanProcConf(Signal* signal); - void setScanReceived(Signal* signal, Uint32 noCompletedOps); - + void close_scan_req(Signal*, ScanRecordPtr); + void close_scan_req_send_conf(Signal*, ScanRecordPtr); + void checkGcp(Signal* signal); void commitGciHandling(Signal* signal, UintR Tgci); void copyApi(Signal* signal); @@ -1474,12 +1453,12 @@ private: void releaseApiCon(Signal* signal, UintR aApiConnectPtr); void releaseApiConCopy(Signal* signal); void releaseApiConnectFail(Signal* signal); - void releaseAttrinfo(Signal* signal); + void releaseAttrinfo(); void releaseGcp(Signal* signal); - void releaseKeys(Signal* signal); + void releaseKeys(); void releaseSimpleRead(Signal* signal); void releaseDirtyWrite(Signal* signal); - void releaseTcCon(Signal* signal); + void releaseTcCon(); void releaseTcConnectFail(Signal* signal); void releaseTransResources(Signal* signal); void saveAttrbuf(Signal* signal); @@ -1496,7 +1475,6 @@ private: AttrbufRecord * const regAttrPtr, UintR TBref); void sendContinueTimeOutControl(Signal* signal, Uint32 TapiConPtr); - void sendInitialiseRecords(Signal* signal, UintR Tnext); void sendKeyinfo(Signal* signal, BlockReference TBRef, Uint32 len); void sendlqhkeyreq(Signal* signal, BlockReference TBRef); void sendSystemError(Signal* signal); @@ -1613,7 +1591,6 @@ private: void scanCompletedLab(Signal* signal); void scanFragError(Signal* signal, Uint32 errorCode); void diverify010Lab(Signal* signal); - void returnInitialiseRecordsLab(Signal* signal); void intstartphase2x010Lab(Signal* signal); void intstartphase3x010Lab(Signal* signal); void sttorryLab(Signal* signal); @@ -1627,7 +1604,7 @@ private: void completeTransAtTakeOverDoLast(Signal* signal, UintR TtakeOverInd); void completeTransAtTakeOverDoOne(Signal* signal, UintR TtakeOverInd); void timeOutLoopStartLab(Signal* signal, Uint32 apiConnectPtr); - void initialiseRecordsLab(Signal* signal, UintR Tdata0); + void initialiseRecordsLab(Signal* signal, UintR Tdata0, Uint32, Uint32); void tckeyreq020Lab(Signal* signal); void intstartphase2x020Lab(Signal* signal); void intstartphase1x010Lab(Signal* signal); @@ -1641,6 +1618,8 @@ private: void checkScanActiveInFailedLqh(Signal* signal, Uint32 scanPtrI, Uint32 failedNodeId); + void checkScanFragList(Signal*, Uint32 failedNodeId, ScanRecord * scanP, + LocalDLList<ScanFragRec>::Head&); // Initialisation void initData(); @@ -1723,17 +1702,10 @@ private: ScanRecordPtr scanptr; UintR cscanrecFileSize; - ScanOperationRecord *scanOperationRecord; - ScanOperationRecordPtr scanOpptr; - UintR cscanOprecFileSize; - - ScanFragRec *scanFragmentRecord; + UnsafeArrayPool<ScanFragRec> c_scan_frag_pool; ScanFragRecPtr scanFragptr; - UintR cscanFragrecFileSize; - UintR cfirstfreeScanOprec; - UintR cnoFreeScanOprec; - UintR cfirstfreeScanFragrec; + UintR cscanFragrecFileSize; UintR cdatabufFilesize; BlockReference cdictblockref; diff --git a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp index 0982ae5bff5..9ac1812492f 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp @@ -35,7 +35,6 @@ void Dbtc::initData() cgcpFilesize = ZGCP_FILESIZE; cscanrecFileSize = ZSCANREC_FILE_SIZE; cscanFragrecFileSize = ZSCAN_FRAGREC_FILE_SIZE; - cscanOprecFileSize = ZSCAN_OPREC_FILE_SIZE; ctabrecFilesize = ZTABREC_FILESIZE; ctcConnectFilesize = ZTC_CONNECT_FILESIZE; cdihblockref = DBDIH_REF; @@ -49,8 +48,6 @@ void Dbtc::initData() hostRecord = 0; tableRecord = 0; scanRecord = 0; - scanOperationRecord = 0; - scanFragmentRecord = 0; databufRecord = 0; attrbufRecord = 0; gcpRecord = 0; @@ -143,16 +140,19 @@ void Dbtc::initRecords() sizeof(ScanRecord), cscanrecFileSize); - scanOperationRecord = (ScanOperationRecord*) - allocRecord("ScanOperationRecord", - sizeof(ScanOperationRecord), - cscanOprecFileSize); - scanFragmentRecord = (ScanFragRec*) - allocRecord("ScanFragRec", - sizeof(ScanFragRec), - cscanFragrecFileSize); + c_scan_frag_pool.setSize(cscanFragrecFileSize); + { + ScanFragRecPtr ptr; + SLList<ScanFragRec> tmp(c_scan_frag_pool); + while(tmp.seize(ptr)) { + new (ptr.p) ScanFragRec(); + } + tmp.release(); + } + indexOps.release(); + databufRecord = (DatabufRecord*)allocRecord("DatabufRecord", sizeof(DatabufRecord), cdatabufFilesize); @@ -182,19 +182,24 @@ Dbtc::Dbtc(const class Configuration & conf): BLOCK_CONSTRUCTOR(Dbtc); - const Properties * p = conf.getOwnProperties(); + const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator(); ndbrequire(p != 0); Uint32 transactionBufferMemory = 0; Uint32 maxNoOfIndexes = 0, maxNoOfConcurrentIndexOperations = 0; Uint32 maxNoOfTriggers = 0, maxNoOfFiredTriggers = 0; - p->get("TransactionBufferMemory", &transactionBufferMemory); - p->get("MaxNoOfIndexes", &maxNoOfIndexes); - p->get("MaxNoOfConcurrentIndexOperations", &maxNoOfConcurrentIndexOperations); - p->get("MaxNoOfTriggers", &maxNoOfTriggers); - p->get("MaxNoOfFiredTriggers", &maxNoOfFiredTriggers); - + ndb_mgm_get_int_parameter(p, CFG_DB_TRANS_BUFFER_MEM, + &transactionBufferMemory); + ndb_mgm_get_int_parameter(p, CFG_DB_NO_INDEXES, + &maxNoOfIndexes); + ndb_mgm_get_int_parameter(p, CFG_DB_NO_INDEX_OPS, + &maxNoOfConcurrentIndexOperations); + ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS, + &maxNoOfTriggers); + ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGER_OPS, + &maxNoOfFiredTriggers); + c_transactionBufferSpace = transactionBufferMemory / AttributeBuffer::getSegmentSize(); c_maxNumberOfIndexes = maxNoOfIndexes; @@ -208,10 +213,7 @@ Dbtc::Dbtc(const class Configuration & conf): addRecSignal(GSN_ATTRINFO, &Dbtc::execATTRINFO); addRecSignal(GSN_CONTINUEB, &Dbtc::execCONTINUEB); addRecSignal(GSN_KEYINFO, &Dbtc::execKEYINFO); - addRecSignal(GSN_SCAN_TABINFO, &Dbtc::execSCAN_TABINFO); addRecSignal(GSN_SCAN_NEXTREQ, &Dbtc::execSCAN_NEXTREQ); - addRecSignal(GSN_SCAN_PROCREQ, &Dbtc::execSCAN_PROCREQ); - addRecSignal(GSN_SCAN_PROCCONF, &Dbtc::execSCAN_PROCCONF); addRecSignal(GSN_TAKE_OVERTCREQ, &Dbtc::execTAKE_OVERTCREQ); addRecSignal(GSN_TAKE_OVERTCCONF, &Dbtc::execTAKE_OVERTCCONF); addRecSignal(GSN_LQHKEYREF, &Dbtc::execLQHKEYREF); @@ -247,7 +249,7 @@ Dbtc::Dbtc(const class Configuration & conf): addRecSignal(GSN_SCAN_TABREQ, &Dbtc::execSCAN_TABREQ); addRecSignal(GSN_SCAN_FRAGCONF, &Dbtc::execSCAN_FRAGCONF); addRecSignal(GSN_SCAN_FRAGREF, &Dbtc::execSCAN_FRAGREF); - addRecSignal(GSN_SIZEALT_REP, &Dbtc::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbtc::execREAD_CONFIG_REQ, true); addRecSignal(GSN_LQH_TRANSCONF, &Dbtc::execLQH_TRANSCONF); addRecSignal(GSN_COMPLETECONF, &Dbtc::execCOMPLETECONF); addRecSignal(GSN_COMMITCONF, &Dbtc::execCOMMITCONF); @@ -285,6 +287,7 @@ Dbtc::Dbtc(const class Configuration & conf): //addRecSignal(GSN_CREATE_TAB_REQ, &Dbtc::execCREATE_TAB_REQ); addRecSignal(GSN_DROP_TAB_REQ, &Dbtc::execDROP_TAB_REQ); addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dbtc::execPREP_DROP_TAB_REQ); + addRecSignal(GSN_WAIT_DROP_TAB_REF, &Dbtc::execWAIT_DROP_TAB_REF); addRecSignal(GSN_WAIT_DROP_TAB_CONF, &Dbtc::execWAIT_DROP_TAB_CONF); addRecSignal(GSN_ALTER_TAB_REQ, &Dbtc::execALTER_TAB_REQ); @@ -318,17 +321,7 @@ Dbtc::~Dbtc() deallocRecord((void **)&scanRecord, "ScanRecord", sizeof(ScanRecord), cscanrecFileSize); - - deallocRecord((void **)&scanOperationRecord, - "ScanOperationRecord", - sizeof(ScanOperationRecord), - cscanOprecFileSize); - - deallocRecord((void **)&scanFragmentRecord, - "ScanFragRec", - sizeof(ScanFragRec), - cscanFragrecFileSize); - + deallocRecord((void **)&databufRecord, "DatabufRecord", sizeof(DatabufRecord), cdatabufFilesize); diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index feb5712d9d3..edb51ea3c89 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -29,8 +29,6 @@ #include <signaldata/AttrInfo.hpp> #include <signaldata/TransIdAI.hpp> #include <signaldata/TcRollbackRep.hpp> -#include <signaldata/TcSizeAltReq.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/NodeFailRep.hpp> #include <signaldata/ReadNodesConf.hpp> #include <signaldata/NFCompleteRep.hpp> @@ -108,16 +106,11 @@ void Dbtc::execCONTINUEB(Signal* signal) tcase = signal->theData[0]; UintR Tdata0 = signal->theData[1]; UintR Tdata1 = signal->theData[2]; + UintR Tdata2 = signal->theData[3]; switch (tcase) { case TcContinueB::ZRETURN_FROM_QUEUED_DELIVERY: jam(); - scanptr.i = Tdata0; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); - scanFragptr.i = Tdata1; - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); - ndbrequire(scanFragptr.p->scanFragState == - ScanFragRec::RETURNING_FROM_DELIVERY); - returnFromQueuedDeliveryLab(signal); + ndbrequire(false); return; case TcContinueB::ZCOMPLETE_TRANS_AT_TAKE_OVER: jam(); @@ -138,7 +131,7 @@ void Dbtc::execCONTINUEB(Signal* signal) return; case TcContinueB::ZINITIALISE_RECORDS: jam(); - initialiseRecordsLab(signal, Tdata0); + initialiseRecordsLab(signal, Tdata0, Tdata2, signal->theData[4]); return; case TcContinueB::ZSEND_COMMIT_LOOP: jam(); @@ -376,6 +369,39 @@ Dbtc::execWAIT_DROP_TAB_CONF(Signal* signal) } void +Dbtc::execWAIT_DROP_TAB_REF(Signal* signal) +{ + jamEntry(); + WaitDropTabRef * ref = (WaitDropTabRef*)signal->getDataPtr(); + + TableRecordPtr tabPtr; + tabPtr.i = ref->tableId; + ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord); + + ndbrequire(tabPtr.p->dropping == true); + Uint32 nodeId = refToNode(ref->senderRef); + tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor(nodeId); + + ndbrequire(ref->errorCode == WaitDropTabRef::NoSuchTable || + ref->errorCode == WaitDropTabRef::NF_FakeErrorREF); + + if(!tabPtr.p->dropTable.waitDropTabCount.done()){ + jam(); + return; + } + + { + PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend(); + conf->tableId = tabPtr.i; + conf->senderRef = reference(); + conf->senderData = tabPtr.p->dropTable.senderData; + sendSignal(tabPtr.p->dropTable.senderRef, GSN_PREP_DROP_TAB_CONF, signal, + PrepDropTabConf::SignalLength, JBB); + tabPtr.p->dropTable.senderRef = 0; + } +} + +void Dbtc::checkWaitDropTabFailedLqh(Signal* signal, Uint32 nodeId, Uint32 tableId) { @@ -497,33 +523,55 @@ void Dbtc::execALTER_TAB_REQ(Signal * signal) /* ***************************************************************************/ /* START / RESTART */ /* ***************************************************************************/ -void Dbtc::execSIZEALT_REP(Signal* signal) +void Dbtc::execREAD_CONFIG_REQ(Signal* signal) { + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + jamEntry(); - tblockref = signal->theData[TcSizeAltReq::IND_BLOCK_REF]; - const UintR apiConnect = signal->theData[TcSizeAltReq::IND_API_CONNECT]; - const UintR tcConnect = signal->theData[TcSizeAltReq::IND_TC_CONNECT]; - const UintR tables = signal->theData[TcSizeAltReq::IND_TABLE]; - const UintR localScan = signal->theData[TcSizeAltReq::IND_LOCAL_SCAN]; - const UintR tcScan = signal->theData[TcSizeAltReq::IND_TC_SCAN]; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + UintR apiConnect; + UintR tcConnect; + UintR tables; + UintR localScan; + UintR tcScan; + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_API_CONNECT, &apiConnect)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_TC_CONNECT, &tcConnect)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_TABLE, &tables)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_LOCAL_SCAN, &localScan)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_SCAN, &tcScan)); ccacheFilesize = (apiConnect/3) + 1; capiConnectFilesize = apiConnect; ctcConnectFilesize = tcConnect; ctabrecFilesize = tables; cscanrecFileSize = tcScan; - cscanOprecFileSize = localScan; cscanFragrecFileSize = localScan; initRecords(); - initialiseRecordsLab(signal, (UintR)0); -}//Dbtc::execSIZEALT_REP() + initialiseRecordsLab(signal, 0, ref, senderData); -void Dbtc::returnInitialiseRecordsLab(Signal* signal) -{ - signal->theData[0] = DBTC_REF; - sendSignal(CMVMI_REF, GSN_SIZEALT_ACK, signal, 2, JBB); -}//Dbtc::returnInitialiseRecordsLab() + Uint32 val = 3000; + ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, &val); + set_timeout_value(val); + + val = 3000; + ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &val); + set_appl_timeout_value(val); + + val = 1; + //ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_TRANSACTION_TAKEOVER, &val); + set_no_parallel_takeover(val); + + ctimeOutCheckDelay = 50; // 500ms +}//Dbtc::execSIZEALT_REP() void Dbtc::execSTTOR(Signal* signal) { @@ -568,19 +616,13 @@ void Dbtc::execNDB_STTOR(Signal* signal) tnodeid = signal->theData[1]; tndbstartphase = signal->theData[2]; /* START PHASE */ tstarttype = signal->theData[3]; /* START TYPE */ - Uint32 config1 = signal->theData[12]; /* CONFIG INFO TC */ - Uint32 config2 = signal->theData[13]; /* CONFIG INFO TC */ switch (tndbstartphase) { case ZINTSPH1: jam(); - ctimeOutCheckDelay = 50; // 500ms - set_timeout_value(config1); - set_no_parallel_takeover(config2); intstartphase1x010Lab(signal); return; case ZINTSPH2: jam(); - set_appl_timeout_value(config2); intstartphase2x010Lab(signal); return; case ZINTSPH3: @@ -747,10 +789,8 @@ void Dbtc::execREAD_NODESCONF(Signal* signal) if (NodeBitmask::get(readNodes->allNodes, i)) { hostptr.i = i; ptrCheckGuard(hostptr, chostFilesize, hostRecord); - + hostptr.p->takeOverStatus = TOS_IDLE; - hostptr.p->ndbVersion = ReadNodesConf::getVersionId - (i, readNodes->theVersionIds); if (NodeBitmask::get(readNodes->inactiveNodes, i)) { jam(); @@ -868,7 +908,15 @@ Dbtc::handleFailedApiNode(Signal* signal, // sending several signals we will increase the loop count by 64. /*********************************************************************/ jam(); - handleScanStop(signal, TapiFailedNode); + + apiConnectptr.p->apiFailState = ZTRUE; + capiConnectClosing[TapiFailedNode]++; + + ScanRecordPtr scanPtr; + scanPtr.i = apiConnectptr.p->apiScanRec; + ptrCheckGuard(scanPtr, cscanrecFileSize, scanRecord); + close_scan_req(signal, scanPtr); + TloopCount += 64; break; case CS_CONNECTED: @@ -1058,6 +1106,7 @@ void Dbtc::handleApiFailState(Signal* signal, UintR TapiConnectptr) */ void Dbtc::handleScanStop(Signal* signal, UintR TapiFailedNode) { +#if JONAS_NOT_DONE arrGuard(TapiFailedNode, MAX_NODES); scanptr.i = apiConnectptr.p->apiScanRec; @@ -1077,7 +1126,7 @@ void Dbtc::handleScanStop(Signal* signal, UintR TapiFailedNode) * We will release the resources and then release the connection * to the failed API. */ - releaseScanResources(signal); + releaseScanResources(scanptr); if (apiNodeHasFailed) { jam(); releaseApiCon(signal, apiConnectptr.i); @@ -1175,6 +1224,7 @@ void Dbtc::handleScanStop(Signal* signal, UintR TapiFailedNode) break; }//switch +#endif }//Dbtc::handleScanStop() /**************************************************************************** @@ -1327,6 +1377,7 @@ void Dbtc::sendSignalErrorRefuseLab(Signal* signal) ptrGuard(apiConnectptr); if (apiConnectptr.p->apiConnectstate != CS_DISCONNECTED) { jam(); + ndbrequire(false); signal->theData[0] = apiConnectptr.p->ndbapiConnect; signal->theData[1] = signal->theData[ttransid_ptr]; signal->theData[2] = signal->theData[ttransid_ptr + 1]; @@ -1410,6 +1461,7 @@ Dbtc::TCKEY_abort(Signal* signal, int place) signal->theData[1] = t1; signal->theData[2] = t2; signal->theData[3] = ZABORT_ERROR; + ndbrequire(false); sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKREP, signal, 4, JBB); return; @@ -1867,7 +1919,7 @@ void Dbtc::packKeyData000Lab(Signal* signal, /* THERE WERE UNSENT INFORMATION, SEND IT. */ /*---------------------------------------------------------------------*/ sendKeyinfo(signal, TBRef, tdataPos); - releaseKeys(signal); + releaseKeys(); return; }//if databufptr.i = databufptr.p->nextDatabuf; @@ -3224,7 +3276,7 @@ void Dbtc::packLqhkeyreq040Lab(Signal* signal, /*-------------------------------------------------------------------- * WE HAVE SENT ALL THE SIGNALS OF THIS OPERATION. SET STATE AND EXIT. *---------------------------------------------------------------------*/ - releaseAttrinfo(signal); + releaseAttrinfo(); if (Tboth) { jam(); releaseSimpleRead(signal); @@ -3250,7 +3302,7 @@ void Dbtc::packLqhkeyreq040Lab(Signal* signal, /* ========================================================================= */ /* ------- RELEASE ALL ATTRINFO RECORDS IN AN OPERATION RECORD ------- */ /* ========================================================================= */ -void Dbtc::releaseAttrinfo(Signal* signal) +void Dbtc::releaseAttrinfo() { UintR Tmp; AttrbufRecordPtr Tattrbufptr; @@ -3282,7 +3334,7 @@ void Dbtc::releaseAttrinfo(Signal* signal) regApiPtr->cachePtr = RNIL; return; }//if - systemErrorLab(signal); + systemErrorLab(0); return; }//Dbtc::releaseAttrinfo() @@ -3292,7 +3344,7 @@ void Dbtc::releaseAttrinfo(Signal* signal) void Dbtc::releaseSimpleRead(Signal* signal) { unlinkReadyTcCon(signal); - releaseTcCon(signal); + releaseTcCon(); /** * No LQHKEYCONF in Simple/Dirty read @@ -3356,7 +3408,7 @@ void Dbtc::unlinkReadyTcCon(Signal* signal) }//if }//Dbtc::unlinkReadyTcCon() -void Dbtc::releaseTcCon(Signal* signal) +void Dbtc::releaseTcCon() { TcConnectRecord * const regTcPtr = tcConnectptr.p; UintR TfirstfreeTcConnect = cfirstfreeTcConnect; @@ -4773,7 +4825,7 @@ void Dbtc::releaseTransResources(Signal* signal) tcConnectptr.i = localTcConnectptr.i; tcConnectptr.p = localTcConnectptr.p; localTcConnectptr.i = rtrTcConnectptrIndex; - releaseTcCon(signal); + releaseTcCon(); } while (localTcConnectptr.i != RNIL); handleGcp(signal); releaseFiredTriggerData(&apiConnectptr.p->theFiredTriggers); @@ -4827,7 +4879,7 @@ void Dbtc::releaseApiConCopy(Signal* signal) void Dbtc::releaseDirtyWrite(Signal* signal) { unlinkReadyTcCon(signal); - releaseTcCon(signal); + releaseTcCon(); ApiConnectRecord * const regApiPtr = apiConnectptr.p; if (regApiPtr->apiConnectstate == CS_START_COMMITTING) { if (regApiPtr->firstTcConnect == RNIL) { @@ -4928,7 +4980,7 @@ void Dbtc::execLQHKEYREF(Signal* signal) regApiPtr->lqhkeyconfrec++; unlinkReadyTcCon(signal); - releaseTcCon(signal); + releaseTcCon(); opPtr.p->triggerExecutionCount--; if (opPtr.p->triggerExecutionCount == 0) { @@ -4984,7 +5036,7 @@ void Dbtc::execLQHKEYREF(Signal* signal) Uint32 indexOp = tcConnectptr.p->indexOp; Uint32 clientData = regTcPtr->clientData; unlinkReadyTcCon(signal); /* LINK TC CONNECT RECORD OUT OF */ - releaseTcCon(signal); /* RELEASE THE TC CONNECT RECORD */ + releaseTcCon(); /* RELEASE THE TC CONNECT RECORD */ setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__); if (isIndexOp) { jam(); @@ -6374,7 +6426,7 @@ void Dbtc::timeOutLoopStartFragLab(Signal* signal, Uint32 TscanConPtr) UintR texpiredTime[8]; UintR TloopCount = 0; Uint32 TtcTimer = ctcTimer; - + while ((TscanConPtr + 8) < cscanFragrecFileSize) { jam(); timeOutPtr[0].i = TscanConPtr + 0; @@ -6386,14 +6438,14 @@ void Dbtc::timeOutLoopStartFragLab(Signal* signal, Uint32 TscanConPtr) timeOutPtr[6].i = TscanConPtr + 6; timeOutPtr[7].i = TscanConPtr + 7; - ptrAss(timeOutPtr[0], scanFragmentRecord); - ptrAss(timeOutPtr[1], scanFragmentRecord); - ptrAss(timeOutPtr[2], scanFragmentRecord); - ptrAss(timeOutPtr[3], scanFragmentRecord); - ptrAss(timeOutPtr[4], scanFragmentRecord); - ptrAss(timeOutPtr[5], scanFragmentRecord); - ptrAss(timeOutPtr[6], scanFragmentRecord); - ptrAss(timeOutPtr[7], scanFragmentRecord); + c_scan_frag_pool.getPtrForce(timeOutPtr[0]); + c_scan_frag_pool.getPtrForce(timeOutPtr[1]); + c_scan_frag_pool.getPtrForce(timeOutPtr[2]); + c_scan_frag_pool.getPtrForce(timeOutPtr[3]); + c_scan_frag_pool.getPtrForce(timeOutPtr[4]); + c_scan_frag_pool.getPtrForce(timeOutPtr[5]); + c_scan_frag_pool.getPtrForce(timeOutPtr[6]); + c_scan_frag_pool.getPtrForce(timeOutPtr[7]); tfragTimer[0] = timeOutPtr[0].p->scanFragTimer; tfragTimer[1] = timeOutPtr[1].p->scanFragTimer; @@ -6445,7 +6497,7 @@ void Dbtc::timeOutLoopStartFragLab(Signal* signal, Uint32 TscanConPtr) for ( ; TscanConPtr < cscanFragrecFileSize; TscanConPtr++){ jam(); timeOutPtr[0].i = TscanConPtr; - ptrAss(timeOutPtr[0], scanFragmentRecord); + c_scan_frag_pool.getPtrForce(timeOutPtr[0]); if (timeOutPtr[0].p->scanFragTimer != 0) { texpiredTime[0] = ctcTimer - timeOutPtr[0].p->scanFragTimer; if (texpiredTime[0] > ctimeOutValue) { @@ -6461,6 +6513,7 @@ void Dbtc::timeOutLoopStartFragLab(Signal* signal, Uint32 TscanConPtr) }//if }//for ctimeOutCheckFragActive = TOCS_FALSE; + return; }//timeOutLoopStartFragLab() @@ -6473,11 +6526,9 @@ void Dbtc::execSCAN_HBREP(Signal* signal) jamEntry(); scanFragptr.i = signal->theData[0]; - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); - + c_scan_frag_pool.getPtr(scanFragptr); switch (scanFragptr.p->scanFragState){ case ScanFragRec::LQH_ACTIVE: - case ScanFragRec::LQH_ACTIVE_CLOSE: break; default: @@ -6527,7 +6578,7 @@ void Dbtc::execSCAN_HBREP(Signal* signal) void Dbtc::timeOutFoundFragLab(Signal* signal, UintR TscanConPtr) { scanFragptr.i = TscanConPtr; - ptrAss(scanFragptr, scanFragmentRecord); + c_scan_frag_pool.getPtr(scanFragptr); DEBUG("timeOutFoundFragLab: scanFragState = "<<scanFragptr.p->scanFragState); /*-------------------------------------------------------------------------*/ @@ -6549,39 +6600,11 @@ void Dbtc::timeOutFoundFragLab(Signal* signal, UintR TscanConPtr) */ scanFragError(signal, ZSCAN_FRAG_LQH_ERROR); DEBUG(" LQH_ACTIVE - closing the fragment scan in node " - <<scanFragptr.p->scanFragNodeId); - break; - - case ScanFragRec::LQH_ACTIVE_CLOSE:{ - jam(); - /** - * The close of LQH expired its time-out. This is not - * acceptable behaviour from LQH and thus we will shoot - * it down. - */ - Uint32 nodeId = scanFragptr.p->scanFragNodeId; - Uint32 cc = scanFragptr.p->m_connectCount; - if(getNodeInfo(nodeId).m_connectCount == cc){ - const BlockReference errRef = calcNdbCntrBlockRef(nodeId); - SystemError * const sysErr = (SystemError*)&signal->theData[0]; - sysErr->errorCode = SystemError::ScanfragTimeout; - sysErr->errorRef = reference(); - sysErr->data1 = scanFragptr.i; - sysErr->data2 = scanFragptr.p->scanRec; - sendSignal(errRef, GSN_SYSTEM_ERROR, signal, - SystemError::SignalLength, JBA); - DEBUG(" node " << nodeId << " killed"); - } else { - DEBUG(" node " << nodeId << " not killed as it has restarted"); - } - scanFragptr.p->stopFragTimer(); + << refToNode(scanFragptr.p->lqhBlockref)); break; - } case ScanFragRec::DELIVERED: jam(); - case ScanFragRec::RETURNING_FROM_DELIVERY: - jam(); case ScanFragRec::IDLE: jam(); case ScanFragRec::QUEUED_FOR_DELIVERY: @@ -6837,47 +6860,17 @@ void Dbtc::execNODE_FAILREP(Signal* signal) }//Dbtc::execNODE_FAILREP() void Dbtc::checkScanActiveInFailedLqh(Signal* signal, - Uint32 scanPtrI, - Uint32 failedNodeId){ + Uint32 scanPtrI, + Uint32 failedNodeId){ for (scanptr.i = scanPtrI; scanptr.i < cscanrecFileSize; scanptr.i++) { jam(); ptrAss(scanptr, scanRecord); if (scanptr.p->scanState != ScanRecord::IDLE){ - for (Uint32 i=0; i<16; i++) { - jam(); - scanFragptr.i = scanptr.p->scanFragrec[i]; - if (scanFragptr.i != RNIL) { - jam(); - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); - if (scanFragptr.p->scanFragNodeId == failedNodeId){ - switch (scanFragptr.p->scanFragState){ - case ScanFragRec::LQH_ACTIVE: - case ScanFragRec::LQH_ACTIVE_CLOSE: - jam(); - apiConnectptr.i = scanptr.p->scanApiRec; - ptrCheckGuard(apiConnectptr, capiConnectFilesize, - apiConnectRecord); - - // The connection to this LQH is closed - scanFragptr.p->lqhBlockref = RNIL; - - DEBUG("checkScanActiveInFailedLqh: scanFragError"); - scanFragError(signal, ZSCAN_LQH_ERROR); - - break; - - default: - /* empty */ - jam(); - break; - }// switch + checkScanFragList(signal, failedNodeId, + scanptr.p, scanptr.p->m_running_scan_frags); + } - } //if - } //if - } //for - } //if - // Send CONTINUEB to continue later signal->theData[0] = TcContinueB::ZCHECK_SCAN_ACTIVE_FAILED_LQH; signal->theData[1] = scanptr.i + 1; // Check next scanptr @@ -6887,6 +6880,37 @@ void Dbtc::checkScanActiveInFailedLqh(Signal* signal, }//for } +void +Dbtc::checkScanFragList(Signal* signal, + Uint32 failedNodeId, + ScanRecord * scanP, + ScanFragList::Head & head){ + + ScanFragRecPtr ptr; + ScanFragList list(c_scan_frag_pool, head); + + for(list.first(ptr); !ptr.isNull(); list.next(ptr)){ + if (refToNode(ptr.p->lqhBlockref) == failedNodeId){ + switch (ptr.p->scanFragState){ + case ScanFragRec::LQH_ACTIVE: + jam(); + apiConnectptr.i = scanptr.p->scanApiRec; + ptrCheckGuard(apiConnectptr, capiConnectFilesize, + apiConnectRecord); + + DEBUG("checkScanActiveInFailedLqh: scanFragError"); + scanFragError(signal, ZSCAN_LQH_ERROR); + + break; + default: + /* empty */ + jam(); + break; + } + } + } +} + void Dbtc::execTAKE_OVERTCCONF(Signal* signal) { jamEntry(); @@ -8393,11 +8417,21 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) const Uint32 buddyPtr = (tmpXX == 0xFFFFFFFF ? RNIL : tmpXX); Uint32 currSavePointId = 0; - Uint8 scanConcurrency = scanTabReq->getParallelism(reqinfo); - Uint32 scanParallel; - Uint32 noOprecPerFrag; + Uint32 scanConcurrency = scanTabReq->getParallelism(reqinfo); + Uint32 noOprecPerFrag = ScanTabReq::getScanBatch(reqinfo); + Uint32 scanParallel = scanConcurrency; Uint32 errCode; + if(noOprecPerFrag == 0){ + jam(); + scanParallel = (scanConcurrency + 15) / 16; + noOprecPerFrag = (scanConcurrency >= 16 ? 16 : scanConcurrency & 15); + } +#ifdef VM_TRACE + ndbout_c("noOprecPerFrag=%d", noOprecPerFrag); + ndbout_c("scanParallel=%d", scanParallel); +#endif + jamEntry(); apiConnectptr.i = scanTabReq->apiConnectPtr; tabptr.i = scanTabReq->tableId; @@ -8447,43 +8481,19 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) errCode = ZNO_CONCURRENCY_ERROR; goto SCAN_TAB_error; }//if - if (scanConcurrency <= 16) { - jam(); - noOprecPerFrag = scanConcurrency; - } else { - if (scanConcurrency <= 240) { - jam(); - //If scanConcurrency > 16 it must be a multiple of 16 - if (((scanConcurrency >> 4) << 4) < scanConcurrency) { - scanConcurrency = ((scanConcurrency >> 4) << 4) + 16; - }//if - } else { - jam(); - errCode = ZTOO_HIGH_CONCURRENCY_ERROR; - goto SCAN_TAB_error; - }//if - noOprecPerFrag = 16; - }//if - - scanParallel = ((scanConcurrency - 1) >> 4) + 1; + /********************************************************** * CALCULATE THE NUMBER OF SCAN_TABINFO SIGNALS THAT WILL * ARRIVE TO DEFINE THIS SCAN. THIS ALSO DEFINES THE NUMBER * OF PARALLEL SCANS AND IT ALSO DEFINES THE NUMBER OF SCAN * OPERATION POINTER RECORDS TO ALLOCATE. **********************************************************/ - if (cnoFreeScanOprec < scanParallel) { - jam(); - errCode = ZNO_SCANREC_ERROR; - goto SCAN_TAB_error; - // WE DID NOT HAVE ENOUGH OF FREE SCAN OPERATION POINTER RECORDS. - // THUS WE REFUSE THE SCAN OPERATION. - }//if if (cfirstfreeTcConnect == RNIL) { jam(); errCode = ZNO_FREE_TC_CONNECTION; goto SCAN_TAB_error; }//if + if (cfirstfreeScanrec == RNIL) { jam(); errCode = ZNO_SCANREC_ERROR; @@ -8508,9 +8518,8 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) seizeCacheRecord(signal); seizeScanrec(signal); initScanrec(signal, scanParallel, noOprecPerFrag); - initScanTcrec(signal); + tcConnectptr.p->apiConnect = apiConnectptr.i; initScanApirec(signal, buddyPtr, transid1, transid2); - cnoFreeScanOprec = cnoFreeScanOprec - scanParallel; // The scan is started apiConnectptr.p->apiConnectstate = CS_START_SCAN; @@ -8522,11 +8531,7 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) ***********************************************************/ setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__); updateBuddyTimer(apiConnectptr); - if (scanptr.p->noScanTabInfo > 1) { - jam(); - scanptr.p->scanState = ScanRecord::WAIT_SCAN_TAB_INFO; - return; - }//if + /*********************************************************** * WE HAVE NOW RECEIVED ALL REFERENCES TO SCAN OBJECTS IN * THE API. WE ARE NOW READY TO RECEIVE THE ATTRIBUTE INFO @@ -8552,10 +8557,6 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) return; }//Dbtc::execSCAN_TABREQ() -void Dbtc::initScanTcrec(Signal* signal) -{ - tcConnectptr.p->apiConnect = apiConnectptr.i; -}//Dbtc::initScanTcrec() void Dbtc::initScanApirec(Signal* signal, Uint32 buddyPtr, UintR transid1, UintR transid2) @@ -8569,16 +8570,6 @@ void Dbtc::initScanApirec(Signal* signal, }//Dbtc::initScanApirec() -void Dbtc::initScanOprec(Signal* signal) -{ - UintR tisoIndex; - - for (tisoIndex = 0; tisoIndex < 16; tisoIndex++) { - scanOpptr.p->apiOpptr[tisoIndex] = cdata[tisoIndex]; - scanOpptr.p->scanOpLength[tisoIndex] = RNIL; - }//for -}//Dbtc::initScanOprec() - void Dbtc::initScanrec(Signal* signal, UintR scanParallel, UintR noOprecPerFrag) @@ -8593,34 +8584,26 @@ void Dbtc::initScanrec(Signal* signal, scanptr.p->scanTableref = tabptr.i; scanptr.p->scanSchemaVersion = scanTabReq->tableSchemaVersion; scanptr.p->scanParallel = scanParallel; - scanptr.p->noScanOprec = scanParallel; - scanptr.p->noScanTabInfo = scanParallel; - scanptr.p->scanTabInfoReceived = 1; - scanptr.p->scanProcessesCompleted = 0; + scanptr.p->noOprecPerFrag = noOprecPerFrag; scanptr.p->scanLockMode = ScanTabReq::getLockMode(reqinfo); scanptr.p->scanLockHold = ScanTabReq::getHoldLockFlag(reqinfo); scanptr.p->readCommitted = ScanTabReq::getReadCommittedFlag(reqinfo); scanptr.p->rangeScan = ScanTabReq::getRangeScanFlag(reqinfo); scanptr.p->scanStoredProcId = scanTabReq->storedProcId; - scanptr.p->scanReceivedOperations = 0; - scanptr.p->noOprecPerFrag = noOprecPerFrag; - scanptr.p->apiIsClosed = false; - scanptr.p->scanCompletedStatus = ZFALSE; - scanptr.p->scanState = ScanRecord::SCAN_NEXT_ORDERED; - for (Uint32 i = 0; i < 16; i++) { - if (i < scanParallel){ - jam(); - seizeScanOprec(signal); - scanptr.p->scanOprec[i] = scanOpptr.i; - } else { - jam(); - scanptr.p->scanOprec[i] = RNIL; - } - scanptr.p->scanFragrec[i] = RNIL; + scanptr.p->scanState = ScanRecord::RUNNING; + scanptr.p->m_queued_count = 0; + + ScanFragList list(c_scan_frag_pool, + scanptr.p->m_running_scan_frags); + for (Uint32 i = 0; i < scanParallel; i++) { + jam(); + ScanFragRecPtr ptr; + ndbrequire(list.seize(ptr)); + ptr.p->scanRec = scanptr.i; + ptr.p->scanFragId = 0; + ptr.p->scanFragConcurrency = noOprecPerFrag; + ptr.p->m_apiPtr = cdata[i]; }//for - scanOpptr.i = scanptr.p->scanOprec[0]; - ptrCheckGuard(scanOpptr, cscanOprecFileSize, scanOperationRecord); - initScanOprec(signal); }//Dbtc::initScanrec() void Dbtc::scanTabRefLab(Signal* signal, Uint32 errCode) @@ -8634,58 +8617,6 @@ void Dbtc::scanTabRefLab(Signal* signal, Uint32 errCode) signal, ScanTabRef::SignalLength, JBB); }//Dbtc::scanTabRefLab() -/****************************************************** - * execSCAN_TABINFO - ******************************************************/ -void Dbtc::execSCAN_TABINFO(Signal* signal) -{ - jamEntry(); - apiConnectptr.i = signal->theData[0]; - for(int i=0; i<16; i++) - cdata[i] = signal->theData[i+1]; - - if (apiConnectptr.i >= capiConnectFilesize) { - jam(); - warningHandlerLab(signal); - return; - }//if - ptrAss(apiConnectptr, apiConnectRecord); - - if (apiConnectptr.p->apiConnectstate != CS_START_SCAN){ - jam(); - DEBUG("apiPtr(" << apiConnectptr.i << ") Dropping SCAN_TABINFO, wrong state: " << apiConnectptr.p->apiConnectstate); - return; - } - - scanptr.i = apiConnectptr.p->apiScanRec; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); - - const Uint32 tscanOprec = scanptr.p->scanTabInfoReceived; - scanptr.p->scanTabInfoReceived++; - arrGuard(tscanOprec, 16); - scanOpptr.i = scanptr.p->scanOprec[tscanOprec]; - ptrCheckGuard(scanOpptr, cscanOprecFileSize, scanOperationRecord); - // Start timer and wait for response from API node. - setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__); - updateBuddyTimer(apiConnectptr); - - initScanOprec(signal); - // Start timer and wait for response from API node. - setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__); - updateBuddyTimer(apiConnectptr); - - if (scanptr.p->scanTabInfoReceived == scanptr.p->noScanTabInfo) { - jam(); - /****************************************************************** - * WE HAVE NOW RECEIVED ALL REFERENCES TO SCAN OBJECTS IN THE API. - * WE ARE NOW READY TO RECEIVE THE ATTRIBUTE INFO IF ANY TO RECEIVE. - ******************************************************************/ - scanptr.p->scanState = ScanRecord::WAIT_AI; - return; - } - ndbrequire(scanptr.p->scanTabInfoReceived <= scanptr.p->noScanTabInfo); -}//Dbtc::execSCAN_TABINFO() - /*---------------------------------------------------------------------------*/ /* */ /* RECEPTION OF ATTRINFO FOR SCAN TABLE REQUEST. */ @@ -8791,7 +8722,7 @@ void Dbtc::execDI_FCOUNTCONF(Signal* signal) ndbrequire(scanptr.p->scanState == ScanRecord::WAIT_FRAGMENT_COUNT); if (apiConnectptr.p->apiFailState == ZTRUE) { jam(); - releaseScanResources(signal); + releaseScanResources(scanptr); handleApiFailState(signal, apiConnectptr.i); return; }//if @@ -8814,31 +8745,40 @@ void Dbtc::execDI_FCOUNTCONF(Signal* signal) return; } - if (tfragCount < scanptr.p->scanParallel) { + if(scanptr.p->scanParallel > tfragCount){ jam(); - for (Uint32 i = tfragCount; i < scanptr.p->scanParallel; i++) { - jam(); - arrGuard(i, 16); - scanOpptr.i = scanptr.p->scanOprec[i]; - ptrCheckGuard(scanOpptr, cscanOprecFileSize, scanOperationRecord); - releaseScanOprec(signal); - scanptr.p->scanOprec[i] = RNIL; - }//for - scanptr.p->scanParallel = tfragCount; - }//if + abortScanLab(signal, ZTOO_HIGH_CONCURRENCY_ERROR); + return; + } + + scanptr.p->scanParallel = tfragCount; scanptr.p->scanNoFrag = tfragCount; - for (UintR i = 0; i < scanptr.p->scanParallel; i++) { - jam(); - // START EACH OF THE PARALLEL SCAN PROCESSES - signal->theData[0] = scanptr.i; - signal->theData[1] = i; - signal->theData[2] = scanptr.p->noOprecPerFrag; - sendSignal(cownref, GSN_SCAN_PROCREQ, signal, 3, JBB); - }//for - // We don't need the timer for checking API anymore, control goes to LQH. + scanptr.p->scanNextFragId = 0; setApiConTimer(apiConnectptr.i, 0, __LINE__); - scanptr.p->scanNextFragId = scanptr.p->scanParallel; - scanptr.p->scanState = ScanRecord::SCAN_NEXT_ORDERED; + updateBuddyTimer(apiConnectptr); + + ScanFragRecPtr ptr; + ScanFragList list(c_scan_frag_pool, + scanptr.p->m_running_scan_frags); + for (list.first(ptr); !ptr.isNull(); list.next(ptr)){ + jam(); + +#ifdef VM_TRACE + ndbout_c("DIGETPRIMREQ(%d, %d)", + scanptr.p->scanTableref, scanptr.p->scanNextFragId); +#endif + + ptr.p->startFragTimer(ctcTimer); + ptr.p->scanFragId = scanptr.p->scanNextFragId++; + ptr.p->scanFragState = ScanFragRec::WAIT_GET_PRIMCONF; + ptr.p->startFragTimer(ctcTimer); + + signal->theData[0] = tcConnectptr.p->dihConnectptr; + signal->theData[1] = ptr.i; + signal->theData[2] = scanptr.p->scanTableref; + signal->theData[3] = ptr.p->scanFragId; + sendSignal(cdihblockref, GSN_DIGETPRIMREQ, signal, 4, JBB); + }//for }//Dbtc::execDI_FCOUNTCONF() /****************************************************** @@ -8857,7 +8797,7 @@ void Dbtc::execDI_FCOUNTREF(Signal* signal) ndbrequire(scanptr.p->scanState == ScanRecord::WAIT_FRAGMENT_COUNT); if (apiConnectptr.p->apiFailState == ZTRUE) { jam(); - releaseScanResources(signal); + releaseScanResources(scanptr); handleApiFailState(signal, apiConnectptr.i); return; }//if @@ -8866,126 +8806,43 @@ void Dbtc::execDI_FCOUNTREF(Signal* signal) void Dbtc::abortScanLab(Signal* signal, Uint32 errCode) { - releaseScanResources(signal); scanTabRefLab(signal, errCode); + releaseScanResources(scanptr); }//Dbtc::abortScanLab() -void Dbtc::scanReleaseResourcesLab(Signal* signal) -{ - apiConnectptr.i = scanptr.p->scanApiRec; - ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); - if (apiConnectptr.p->returncode != 0) { - jam(); - ScanTabRef * ref = (ScanTabRef*)&signal->theData[0]; - ref->apiConnectPtr = apiConnectptr.p->ndbapiConnect; - ref->transId1 = apiConnectptr.p->transid[0]; - ref->transId2 = apiConnectptr.p->transid[1]; - ref->errorCode = apiConnectptr.p->returncode; - sendSignal(apiConnectptr.p->ndbapiBlockref, - GSN_SCAN_TABREF, signal, ScanTabRef::SignalLength, JBB); - } else { - jam(); - sendScanTabConf(signal); - }//if - releaseScanResources(signal); - if (apiConnectptr.p->apiFailState == ZTRUE) { - jam(); - handleApiFailState(signal, apiConnectptr.i); - return; - }//if -}//Dbtc::scanReleaseResourcesLab() - -void Dbtc::releaseScanResources(Signal* signal) +void Dbtc::releaseScanResources(ScanRecordPtr scanPtr) { +#ifdef VM_TRACE + ndbout_c("releaseScanResources: %d", scanPtr.i); +#endif if (apiConnectptr.p->cachePtr != RNIL) { cachePtr.i = apiConnectptr.p->cachePtr; ptrCheckGuard(cachePtr, ccacheFilesize, cacheRecord); - releaseAttrinfo(signal); + releaseAttrinfo(); }//if - cnoFreeScanOprec = cnoFreeScanOprec + scanptr.p->noScanOprec; - scanptr.p->scanCompletedStatus = ZCLOSED; - tcConnectptr.i = scanptr.p->scanTcrec; + tcConnectptr.i = scanPtr.p->scanTcrec; ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord); - releaseTcCon(signal); - for (Uint32 i = 0; i < 16; i++) { - jam(); - scanFragptr.i = scanptr.p->scanFragrec[i]; - scanptr.p->scanFragrec[i] = RNIL; - if (scanFragptr.i != RNIL) { - jam(); - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); - releaseScanFragrec(signal); - }//if - scanOpptr.i = scanptr.p->scanOprec[i]; - scanptr.p->scanOprec[i] = RNIL; - if (scanOpptr.i != RNIL) { - jam(); - ptrCheckGuard(scanOpptr, cscanOprecFileSize, scanOperationRecord); - releaseScanOprec(signal); - }//if - }//for - releaseScanrec(signal); + releaseTcCon(); + + ScanFragList x(c_scan_frag_pool, + scanPtr.p->m_completed_scan_frags); + x.release(); + ndbrequire(scanPtr.p->m_running_scan_frags.isEmpty()); + ndbrequire(scanPtr.p->m_queued_scan_frags.isEmpty()); + ndbrequire(scanPtr.p->m_delivered_scan_frags.isEmpty()); + + // link into free list + scanPtr.p->nextScan = cfirstfreeScanrec; + scanPtr.p->scanState = ScanRecord::IDLE; + scanPtr.p->scanTcrec = RNIL; + cfirstfreeScanrec = scanPtr.i; + apiConnectptr.p->apiScanRec = RNIL; apiConnectptr.p->apiConnectstate = CS_CONNECTED; setApiConTimer(apiConnectptr.i, 0, __LINE__); }//Dbtc::releaseScanResources() -/****************************************************** - * execSCAN_PROCREQ - ******************************************************/ -void Dbtc::execSCAN_PROCREQ(Signal* signal) -{ - jamEntry(); - scanptr.i = signal->theData[0]; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); - - const UintR tscanFragId = signal->theData[1]; - ndbrequire(tscanFragId < 16); - const UintR tscanNoOprec = signal->theData[2]; - - ndbrequire(cfirstfreeScanFragrec != RNIL); - seizeScanFragrec(signal); - - apiConnectptr.i = scanptr.p->scanApiRec; - ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); - setApiConTimer(apiConnectptr.i, 0, __LINE__); - - scanptr.p->scanFragrec[tscanFragId] = scanFragptr.i; - scanFragptr.p->scanRec = scanptr.i; - scanFragptr.p->scanIndividual = tscanFragId * tscanNoOprec; - scanFragptr.p->scanFragProcId = tscanFragId; - scanFragptr.p->scanFragId = tscanFragId; - scanFragptr.p->scanFragConcurrency = tscanNoOprec; - scanFragptr.p->scanFragCompletedStatus = ZFALSE; - tcConnectptr.i = scanptr.p->scanTcrec; - ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord); - - { - /** - * Check table - */ - TableRecordPtr tabPtr; - tabPtr.i = scanptr.p->scanTableref; - ptrAss(tabPtr, tableRecord); - Uint32 schemaVersion = scanptr.p->scanSchemaVersion; - if(tabPtr.p->checkTable(schemaVersion) == false){ - jam(); - scanFragError(signal, tabPtr.p->getErrorCode(schemaVersion)); - return; - } - } - - signal->theData[0] = tcConnectptr.p->dihConnectptr; - signal->theData[1] = scanFragptr.i; - signal->theData[2] = scanptr.p->scanTableref; - signal->theData[3] = tscanFragId; - sendSignal(cdihblockref, GSN_DIGETPRIMREQ, signal, 4, JBB); - scanFragptr.p->scanFragState = ScanFragRec::WAIT_GET_PRIMCONF; - updateBuddyTimer(apiConnectptr); - scanFragptr.p->startFragTimer(ctcTimer); -}//Dbtc::execSCAN_PROCREQ() - /**************************************************************** * execDIGETPRIMCONF * @@ -8998,14 +8855,13 @@ void Dbtc::execDIGETPRIMCONF(Signal* signal) jamEntry(); // tcConnectptr.i in theData[0] is not used scanFragptr.i = signal->theData[1]; - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); + c_scan_frag_pool.getPtr(scanFragptr); tnodeid = signal->theData[2]; arrGuard(tnodeid, MAX_NDB_NODES); ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::WAIT_GET_PRIMCONF); scanFragptr.p->stopFragTimer(); - scanFragptr.p->lqhBlockref = RNIL; scanptr.i = scanFragptr.p->scanRec; ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); @@ -9035,16 +8891,22 @@ void Dbtc::execDIGETPRIMCONF(Signal* signal) case ScanRecord::CLOSING_SCAN: jam(); updateBuddyTimer(apiConnectptr); - scanFragptr.p->startFragTimer(ctcTimer); - sendScanProcConf(signal); + { + ScanFragList run(c_scan_frag_pool, scanptr.p->m_running_scan_frags); + ScanFragList comp(c_scan_frag_pool, scanptr.p->m_completed_scan_frags); + + run.remove(scanFragptr); + comp.add(scanFragptr); + } + close_scan_req_send_conf(signal, scanptr); return; default: jam(); /*empty*/; break; }//switch - scanFragptr.p->scanFragNodeId = tnodeid; - scanFragptr.p->lqhBlockref = calcLqhBlockRef(tnodeid); + Uint32 ref = calcLqhBlockRef(tnodeid); + scanFragptr.p->lqhBlockref = ref; scanFragptr.p->m_connectCount = getNodeInfo(tnodeid).m_connectCount; sendScanFragReq(signal); attrbufptr.i = cachePtr.p->firstAttrbuf; @@ -9054,12 +8916,12 @@ void Dbtc::execDIGETPRIMCONF(Signal* signal) sendAttrinfo(signal, scanFragptr.i, attrbufptr.p, - scanFragptr.p->lqhBlockref); + ref); attrbufptr.i = attrbufptr.p->attrbuf[ZINBUF_NEXT]; }//while scanFragptr.p->scanFragState = ScanFragRec::LQH_ACTIVE; - updateBuddyTimer(apiConnectptr); scanFragptr.p->startFragTimer(ctcTimer); + updateBuddyTimer(apiConnectptr); /********************************************* * WE HAVE NOW STARTED A FRAGMENT SCAN. NOW * WAIT FOR THE FIRST SCANNED RECORDS @@ -9079,7 +8941,7 @@ void Dbtc::execDIGETPRIMREF(Signal* signal) // tcConnectptr.i in theData[0] is not used. scanFragptr.i = signal->theData[1]; const Uint32 errCode = signal->theData[2]; - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); + c_scan_frag_pool.getPtr(scanFragptr); ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::WAIT_GET_PRIMCONF); scanFragError(signal, errCode); }//Dbtc::execDIGETPRIMREF() @@ -9098,7 +8960,7 @@ void Dbtc::execSCAN_FRAGREF(Signal* signal) const Uint32 errCode = ref->errorCode; scanFragptr.i = ref->senderData; - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); + c_scan_frag_pool.getPtr(scanFragptr); scanptr.i = scanFragptr.p->scanRec; ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); @@ -9119,7 +8981,6 @@ void Dbtc::execSCAN_FRAGREF(Signal* signal) * stop fragment timer and call scanFragError to start * close of the other fragment scans */ - scanFragptr.p->lqhBlockref = RNIL; scanFragError(signal, errCode); }//Dbtc::execSCAN_FRAGREF() @@ -9140,33 +9001,20 @@ void Dbtc::scanFragError(Signal* signal, Uint32 errorCode) << ", scanState = " << scanptr.p->scanState); scanFragptr.p->stopFragTimer(); +#if JONAS_NOT_DONE apiConnectptr.i = scanptr.p->scanApiRec; ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); - if (scanFragptr.p->lqhBlockref == RNIL){ - // Since the lqh is closed, this scan process should be reported - // as completed immediately - jam(); - updateBuddyTimer(apiConnectptr); - scanFragptr.p->startFragTimer(ctcTimer); - sendScanProcConf(signal); - }//if // If close of the scan is not already started if (scanptr.p->scanState != ScanRecord::CLOSING_SCAN) { jam(); apiConnectptr.p->returncode = errorCode; - /** - * Only set apiIsClosed if API is waiting for an answer - */ - if (scanptr.p->scanState == ScanRecord::SCAN_NEXT_ORDERED){ - jam(); - scanptr.p->apiIsClosed = true; - } scanCompletedLab(signal); return; }//if +#endif }//Dbtc::scanFragError() @@ -9183,14 +9031,12 @@ void Dbtc::execSCAN_FRAGCONF(Signal* signal) const ScanFragConf * const conf = (ScanFragConf*)&signal->theData[0]; const Uint32 noCompletedOps = conf->completedOps; - for(Uint32 i = 0; i<noCompletedOps; i++) - cdata[i] = conf->opReturnDataLen[i]; scanFragptr.i = conf->senderData; - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); - + c_scan_frag_pool.getPtr(scanFragptr); + scanptr.i = scanFragptr.p->scanRec; ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); - + apiConnectptr.i = scanptr.p->scanApiRec; ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); @@ -9201,143 +9047,21 @@ void Dbtc::execSCAN_FRAGCONF(Signal* signal) jam(); systemErrorLab(signal); }//if - - scanFragptr.p->scanFragCompletedStatus = conf->fragmentCompleted; + + ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::LQH_ACTIVE); + + const Uint32 status = conf->fragmentCompleted; scanFragptr.p->stopFragTimer(); - switch (scanFragptr.p->scanFragCompletedStatus) { - case ZFALSE: - case ZTRUE: - jam(); - /* empty */ - break; - - case ZCLOSED: - /* The scan has finished this fragment. */ - jam(); - returnFromQueuedDeliveryLab(signal); - return; - break; - - default: - jam(); - systemErrorLab(signal); - break; - }//switch - - // CHECK THE STATE OF THE DELIVERY PROCESS TO THE APPLICATION. - switch (scanptr.p->scanState) { - case ScanRecord::SCAN_NEXT_ORDERED: - jam(); - /** - * THE APPLICATION HAVE ISSUED A SCAN_NEXTREQ AND IS WAITING - * FOR MORE OPERATIONS. SEND OPERATIONS DIRECTLY - */ - if (noCompletedOps > 0) { - jam(); - setScanReceived(signal, noCompletedOps); - sendScanTabConf(signal); - scanptr.p->scanState = ScanRecord::DELIVERED; - scanFragptr.p->scanFragState = ScanFragRec::DELIVERED; - return; - }//if - break; - - case ScanRecord::DELIVERED: - case ScanRecord::QUEUED_DELIVERED: - jam(); - /** - * THE APPLICATION HAVE ALREADY RECEIVED A DELIVERY. - * QUEUE THE RECEIVED SCAN OPERATIONS AND ISSUE THEM - * WHEN THE APPLICATION ASKS FOR MORE. - */ - if (noCompletedOps > 0) { - jam(); - setScanReceived(signal, noCompletedOps); - scanptr.p->scanState = ScanRecord::QUEUED_DELIVERED; - scanFragptr.p->scanFragState = ScanFragRec::QUEUED_FOR_DELIVERY; - return; - }//if - break; - - case ScanRecord::CLOSING_SCAN: - jam(); - /************************************************* - * WE ARE CURRENTLY CLOSING THE SCAN. - * - * WE HAVE ALREADY ORDERED THE FRAGMENT TO CLOSE ITS - * SCAN. THIS SIGNAL MUST HAVE BEEN SENT BEFORE THIS - * CLOSE SIGNAL ARRIVED. SIMPLY IGNORE THIS SIGNAL. - **************************************************/ - return; - break; - - default: - jam(); - systemErrorLab(signal); - break; - - }//switch - - /** - * THERE WAS NO TUPLES LEFT TO REPORT IN THIS FRAGMENT. CLOSE SCAN - * HAVE NOT BEEN ORDERED. WE CAN CONTINUE THE SCAN PROCESS IMMEDIATELY. - * THE COMPLETED STATUS MUST BE TRUE SINCE IT IS NOT CLOSED. IF IT WAS - * FALSE IT MUST HAVE BEEN MORE TUPLES TO SCAN AND AT LEAST ONE OF - * THOSE SHOULD HAVE BEEN REPORTED. - */ - if (scanFragptr.p->scanFragCompletedStatus == ZFALSE) { - jam(); - /** - * THE SENDING NODE IS OUT OF ORDER WE WILL KILL IT BY SENDING SYSTEM - * ERROR TO IT - */ - const BlockReference errRef = - calcNdbCntrBlockRef(scanFragptr.p->scanFragNodeId); - SystemError * const sysErr = (SystemError*)&signal->theData[0]; - sysErr->errorCode = SystemError::ScanfragStateError; - sysErr->errorRef = reference(); - sendSignal(errRef, GSN_SYSTEM_ERROR, signal, - SystemError::SignalLength, JBA); - return; - }//if - returnFromQueuedDeliveryLab(signal); -}//Dbtc::execSCAN_FRAGCONF() - -void Dbtc::returnFromQueuedDeliveryLab(Signal* signal) -{ - apiConnectptr.i = scanptr.p->scanApiRec; - ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); - - switch(scanFragptr.p->scanFragCompletedStatus) { - case ZFALSE: - { - /********************************************************************* - * WE HAVE SENT THE SCANNED OPERATION TO THE APPLICATION AND WE HAVE - * RECEIVED THE ORDER TO CONTINUE SCANNING. THE CURRENT FRAGMENT STILL - * CONTAINS MORE TUPLES TO SCAN. - *********************************************************************/ - jam(); - scanFragptr.p->scanFragState = ScanFragRec::LQH_ACTIVE; - ScanFragNextReq * nextReq = (ScanFragNextReq*)&signal->theData[0]; - nextReq->senderData = scanFragptr.i; - nextReq->closeFlag = ZFALSE; - nextReq->transId1 = apiConnectptr.p->transid[0]; - nextReq->transId2 = apiConnectptr.p->transid[1]; - sendSignal(scanFragptr.p->lqhBlockref, GSN_SCAN_NEXTREQ, signal, - ScanFragNextReq::SignalLength, JBB); - } - break; + if(scanptr.p->scanState == ScanRecord::CLOSING_SCAN){ + if(status == ZFALSE){ + /** + * Dont deliver to api, but instead close in LQH + * Dont need to mess with queues + */ + ndbout_c("running -> running(close)"); - case ZTRUE: - { - /********************************************************************* - * WE HAVE SENT THE SCANNED OPERATION TO THE APPLICATION AND WE HAVE - * RECEIVED THE ORDER TO CONTINUE SCANNING. THE CURRENT FRAGMENT HAVE - * BEEN COMPLETELY SCANNED AND WE ARE READY TO CLOSE IT. - *********************************************************************/ jam(); - scanFragptr.p->scanFragState = ScanFragRec::LQH_ACTIVE_CLOSE; ScanFragNextReq * nextReq = (ScanFragNextReq*)&signal->theData[0]; nextReq->senderData = scanFragptr.i; nextReq->closeFlag = ZTRUE; @@ -9345,126 +9069,66 @@ void Dbtc::returnFromQueuedDeliveryLab(Signal* signal) nextReq->transId2 = apiConnectptr.p->transid[1]; sendSignal(scanFragptr.p->lqhBlockref, GSN_SCAN_NEXTREQ, signal, ScanFragNextReq::SignalLength, JBB); + return; + } else { + jam(); + ScanFragList run(c_scan_frag_pool, scanptr.p->m_running_scan_frags); + ScanFragList comp(c_scan_frag_pool, scanptr.p->m_completed_scan_frags); + + run.remove(scanFragptr); + comp.add(scanFragptr); } - break; - - case ZCLOSED: - { - /******************************************************************** - * THE SCANNED FRAGMENT HAVE BEEN CLOSED. IF CLOSE SCAN HAVE BEEN - * ORDERED THEN WE CAN REPORT THAT THIS SCAN PROCESS IS COMPLETED. - * ALSO IF THERE ARE NO MORE FRAGMENTS TO SCAN WE CAN REPORT THAT - * THE SCAN PROCESS IS COMPLETED. - ********************************************************************/ - jam(); - scanFragptr.p->lqhBlockref = RNIL; - if ((scanptr.p->scanState != ScanRecord::CLOSING_SCAN) && - (scanptr.p->scanNextFragId < scanptr.p->scanNoFrag)){ - jam(); - scanFragptr.p->scanFragState = ScanFragRec::WAIT_GET_PRIMCONF; - tcConnectptr.i = scanptr.p->scanTcrec; - ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord); - scanFragptr.p->scanFragId = scanptr.p->scanNextFragId; - scanptr.p->scanNextFragId++; - signal->theData[0] = tcConnectptr.p->dihConnectptr; - signal->theData[1] = scanFragptr.i; - signal->theData[2] = scanptr.p->scanTableref; - signal->theData[3] = scanFragptr.p->scanFragId; - sendSignal(cdihblockref, GSN_DIGETPRIMREQ, signal, 4, JBB); - } else { - jam(); - sendScanProcConf(signal); - }//if - } - break; - - default: - jam(); - systemErrorLab(signal); - break; - }//switch - - updateBuddyTimer(apiConnectptr); - scanFragptr.p->startFragTimer(ctcTimer); -}//Dbtc::returnFromQueuedDeliveryLab() - -/********************************************************** - * execSCAN_PROCCONF - **********************************************************/ -void Dbtc::execSCAN_PROCCONF(Signal* signal) -{ - jamEntry(); + close_scan_req_send_conf(signal, scanptr); + return; + } + + if(status == ZCLOSED && scanptr.p->scanNextFragId < scanptr.p->scanNoFrag){ + /** + * Start on next fragment + */ + ndbrequire(noCompletedOps == 0); + scanFragptr.p->scanFragState = ScanFragRec::WAIT_GET_PRIMCONF; + scanFragptr.p->startFragTimer(ctcTimer); - scanptr.i = signal->theData[0]; - ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); - scanptr.p->scanProcessesCompleted++; - ndbassert(scanptr.p->scanProcessesCompleted <= scanptr.p->scanParallel); + tcConnectptr.i = scanptr.p->scanTcrec; + ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord); + scanFragptr.p->scanFragId = scanptr.p->scanNextFragId++; + signal->theData[0] = tcConnectptr.p->dihConnectptr; + signal->theData[1] = scanFragptr.i; + signal->theData[2] = scanptr.p->scanTableref; + signal->theData[3] = scanFragptr.p->scanFragId; + sendSignal(cdihblockref, GSN_DIGETPRIMREQ, signal, 4, JBB); + return; + } + + Uint32 chksum = 0; + Uint32 totalLen = 0; + for(Uint32 i = 0; i<noCompletedOps; i++){ + Uint32 tmp = conf->opReturnDataLen[i]; + chksum += (tmp << i); + totalLen += tmp; + } + + { + ScanFragList run(c_scan_frag_pool, scanptr.p->m_running_scan_frags); + ScanFragList queued(c_scan_frag_pool, scanptr.p->m_queued_scan_frags); + + run.remove(scanFragptr); + queued.add(scanFragptr); + scanptr.p->m_queued_count++; + } - scanFragptr.i = signal->theData[1]; - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); + scanFragptr.p->m_ops = noCompletedOps; + scanFragptr.p->m_chksum = chksum; + scanFragptr.p->m_totalLen = totalLen; + scanFragptr.p->scanFragState = ScanFragRec::QUEUED_FOR_DELIVERY; scanFragptr.p->stopFragTimer(); - scanFragptr.p->scanFragState = ScanFragRec::COMPLETED; - - if (scanptr.p->scanProcessesCompleted == scanptr.p->scanParallel) { - jam(); - - // Check that all scan processes are in state COMPLETED - for (Uint32 i = 0; i < 16; i++) { - scanFragptr.i = scanptr.p->scanFragrec[i]; - if (scanFragptr.i != RNIL) { - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); - ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::COMPLETED); - } - } - // ALL SCAN PROCESSES HAS COMPLETED - scanptr.p->scanCompletedStatus = ZTRUE; - switch (scanptr.p->scanState) { - - case ScanRecord::CLOSING_SCAN: - jam(); - if (scanptr.p->apiIsClosed == true) { - jam(); - /* - * The API has either failed or ordered a close of this scan - * it's resources should be released and a response sent - */ - scanReleaseResourcesLab(signal); - return; - }//if - - /** - * The close have been performed but the API is still alive and not - * expecting a response, keep resources until API fails or it orders - * a close - */ - return; - case ScanRecord::SCAN_NEXT_ORDERED: - jam(); - /** - * The scan is completed and api is waiting for a response. - * Reslease resources and send a response. - */ - scanReleaseResourcesLab(signal); - return; - case ScanRecord::DELIVERED: - case ScanRecord::QUEUED_DELIVERED: - jam(); - /** - * All processes have reported completion, wait for a new request from - * API and start close of the scan then. - */ - scanptr.p->scanReceivedOperations = 0; - scanptr.p->scanState = ScanRecord::CLOSING_SCAN; - return; - default: - jam(); - systemErrorLab(signal); - break; - }//switch + if(scanptr.p->m_queued_count > /** Min */ 0){ + jam(); + sendScanTabConf(signal); } -}//Dbtc::execSCAN_PROCCONF() - +}//Dbtc::execSCAN_FRAGCONF() /**************************************************************************** * execSCAN_NEXTREQ @@ -9527,7 +9191,7 @@ void Dbtc::execSCAN_NEXTREQ(Signal* signal) scanTabRefLab(signal, ZSTATE_ERROR); return; }//if - + /******************************************************* * START THE ACTUAL LOGIC OF SCAN_NEXTREQ. ********************************************************/ @@ -9535,202 +9199,176 @@ void Dbtc::execSCAN_NEXTREQ(Signal* signal) setApiConTimer(apiConnectptr.i, 0, __LINE__); scanptr.i = apiConnectptr.p->apiScanRec; ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord); + ScanRecord* scanP = scanptr.p; - if (scanptr.p->apiIsClosed == true) { - jam(); - /** - * The close is already started. Api has failed or - * has not responded in time so this signal is not allowed - */ - DEBUG("execSCAN_NEXTREQ: apiIsClosed == true"); - DEBUG(" apiConnectstate="<<apiConnectptr.p->apiConnectstate); - DEBUG(" scanState="<<scanptr.p->scanState); - return; - }//if - - - if (scanptr.p->scanState == ScanRecord::CLOSING_SCAN) { - jam(); - /********************************************************************* - * WE HAVE STARTED A CLOSE OF THIS SCAN OPERATION. NOW WE CAN REPORT - * THIS TO THE APPLICATION. BEFORE WE REPORT IT TO THE APPLICATION WE - * MUST COMPLETE THE CLOSE FIRST. - *********************************************************************/ - if (scanptr.p->scanCompletedStatus == ZTRUE) { - jam(); - /********************************************************************* - * THE SCAN IS ALREADY COMPLETED. WE ARE NOW READY TO COMPLETE THE SCAN - * BY RELEASING ALL RESOURCES AND SENDING THE CONFIRMATION TO THE - * APPLICATION. - *********************************************************************/ - scanReleaseResourcesLab(signal); - return; - } else { - jam(); - /********************************************************************* - * THE CLOSE IS ONGOING BUT NOT YET COMPLETED. WE WILL SET THE STATE - * TO INDICATE THAT THE APPLICATION IS WAITING FOR THE RESPONSE. - *********************************************************************/ - scanptr.p->apiIsClosed = true; - return; - }//if - }//if + const Uint32 len = signal->getLength() - 4; if (stopScan == ZTRUE) { jam(); /********************************************************************* * APPLICATION IS CLOSING THE SCAN. **********************************************************************/ - scanptr.p->apiIsClosed = true; - scanCompletedLab(signal); + ndbrequire(len == 0); + close_scan_req(signal, scanptr); return; }//if - /********************************************************************* - * THOSE SCAN PROCESSES THAT WAS SENT IN PREVIOUS MESSAGE ARE - * ACKNOWLEDGED BY THIS REQUEST FOR MORE SCANNED OPERATIONS. WE CAN - * THUS RESTART THOSE SCAN PROCESSES. - *********************************************************************/ - for (Uint32 i = 0; i < 16; i++) { - jam(); - scanFragptr.i = scanptr.p->scanFragrec[i]; - if (scanFragptr.i != RNIL) { - jam(); - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); - if (scanFragptr.p->scanFragState == ScanFragRec::DELIVERED) { - jam(); - scanFragptr.p->scanFragState = ScanFragRec::RETURNING_FROM_DELIVERY; - signal->theData[0] = TcContinueB::ZRETURN_FROM_QUEUED_DELIVERY; - signal->theData[1] = scanptr.i; - signal->theData[2] = scanFragptr.i; - sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB); - } - }//if - }//for + // Copy op ptrs so I dont overwrite them when sending... + memcpy(signal->getDataPtrSend()+25, signal->getDataPtr()+4, 4 * len); - switch (scanptr.p->scanState) { - case ScanRecord::QUEUED_DELIVERED: - /********************************************************************* - * A NUMBER OF SCAN PROCESSES ARE READY TO DELIVER. DELIVER AND SET - * STATE TO DELIVERED. ALSO CONTINUE PROCESS QUEUED SCAN PROCESSES. - *********************************************************************/ - jam(); - sendScanTabConf(signal); - scanptr.p->scanState = ScanRecord::DELIVERED; - /********************************************************************* - * UPDATE STATUS OF THE SCAN PROCESSES THAT WAS NOW SENT TO THE - * APPLICATION TO DELIVERED. PREVIOUSLY THEY WERE QUEUED FOR DELIVERY. - *********************************************************************/ - for (Uint32 i = 0; i < 16; i++) { - jam(); - scanFragptr.i = scanptr.p->scanFragrec[i]; - if (scanFragptr.i != RNIL) { - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); - if (scanFragptr.p->scanFragState == ScanFragRec::QUEUED_FOR_DELIVERY) { - jam(); - scanFragptr.p->scanFragState = ScanFragRec::DELIVERED; - }//if - }//if - }//for - return; - case ScanRecord::DELIVERED: - jam(); - /********************************************************************* - * WE HAVE NOT ANY QUEUED DELIVERIES. SET STATE TO INDICATE IT IS OK - * TO SEND SCAN_TABCONF AS SOON AS ANY FRAGMENT IS READY TO DELIVER. - *********************************************************************/ - scanptr.p->scanState = ScanRecord::SCAN_NEXT_ORDERED; - return; - case ScanRecord::SCAN_NEXT_ORDERED: - jam(); - /* empty */ - return; - default: + ScanFragNextReq * nextReq = (ScanFragNextReq*)&signal->theData[0]; + nextReq->closeFlag = ZFALSE; + nextReq->transId1 = apiConnectptr.p->transid[0]; + nextReq->transId2 = apiConnectptr.p->transid[1]; + + ScanFragList running(c_scan_frag_pool, scanP->m_running_scan_frags); + ScanFragList delivered(c_scan_frag_pool, scanP->m_delivered_scan_frags); + for(Uint32 i = 0 ; i<len; i++){ jam(); - systemErrorLab(signal); - return; - }//switch -}//Dbtc::execSCAN_NEXTREQ() - -void Dbtc::scanCompletedLab(Signal* signal) { - scanptr.p->scanReceivedOperations = 0; - scanptr.p->scanState = ScanRecord::CLOSING_SCAN; - - // Iterate over all fragment scans and check if - // they need to be closed in LQH - for (Uint32 i = 0; i < 16; i++) { - if (scanptr.p->scanFragrec[i] == RNIL) { - jam(); - continue; - } - scanFragptr.i = scanptr.p->scanFragrec[i]; - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); - - if (scanFragptr.p->lqhBlockref == RNIL){ - // The connection to this LQH has been closed - jam(); - continue; - } - - if (scanFragptr.p->scanFragCompletedStatus == ZCLOSED){ - // The fragment scan is already completed - jam(); - continue; - } - - if (scanFragptr.p->scanFragState == ScanFragRec::RETURNING_FROM_DELIVERY){ - // The scan process is soon to continue executing - // Set scanFragCompletedStatus to ZTRUE so that LQH is properly closed - // when this scan process "returns from delivery" - jam(); - DEBUG("scanCompletedLab: setting scanFragCompletedStatus to ZTRUE"); - scanFragptr.p->scanFragCompletedStatus = ZTRUE; - continue; - } + scanFragptr.i = signal->theData[i+25]; + c_scan_frag_pool.getPtr(scanFragptr); + ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::DELIVERED); - apiConnectptr.i = scanptr.p->scanApiRec; - ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); + scanFragptr.p->scanFragState = ScanFragRec::LQH_ACTIVE; + scanFragptr.p->startFragTimer(ctcTimer); - ScanFragNextReq * nextReq = (ScanFragNextReq*)&signal->theData[0]; + scanFragptr.p->m_ops = 0; nextReq->senderData = scanFragptr.i; - nextReq->closeFlag = ZTRUE; - nextReq->transId1 = apiConnectptr.p->transid[0]; - nextReq->transId2 = apiConnectptr.p->transid[1]; sendSignal(scanFragptr.p->lqhBlockref, GSN_SCAN_NEXTREQ, signal, ScanFragNextReq::SignalLength, JBB); - updateBuddyTimer(apiConnectptr); + delivered.remove(scanFragptr); + running.add(scanFragptr); + }//for + +}//Dbtc::execSCAN_NEXTREQ() - updateBuddyTimer(apiConnectptr); - scanFragptr.p->startFragTimer(ctcTimer); - scanFragptr.p->scanFragState = ScanFragRec::LQH_ACTIVE_CLOSE; +void +Dbtc::close_scan_req(Signal* signal, ScanRecordPtr scanPtr){ +#ifdef VM_TRACE + ndbout_c("%d close_scan_req", apiConnectptr.i); +#endif + ScanRecord* scanP = scanPtr.p; + scanPtr.p->scanState = ScanRecord::CLOSING_SCAN; - }//for -}//Dbtc::scanCompletedLab() + /** + * Queue : Action + * ========== : ================= + * completed : - + * running : - + * delivered : close -> LQH + * queued w/ : close -> LQH + * queued wo/ : move to completed + */ + + /** + * All delivered should to be closed + */ + ScanFragNextReq * nextReq = (ScanFragNextReq*)&signal->theData[0]; + nextReq->closeFlag = ZTRUE; + nextReq->transId1 = apiConnectptr.p->transid[0]; + nextReq->transId2 = apiConnectptr.p->transid[1]; + + { + ScanFragRecPtr ptr; + ScanFragList running(c_scan_frag_pool, scanP->m_running_scan_frags); + ScanFragList completed(c_scan_frag_pool, scanP->m_completed_scan_frags); + ScanFragList delivered(c_scan_frag_pool, scanP->m_delivered_scan_frags); + for(delivered.first(ptr); !ptr.isNull(); ){ + jam(); + ScanFragRecPtr curr = ptr; // Remove while iterating... + delivered.next(ptr); + + ndbrequire(curr.p->scanFragState == ScanFragRec::DELIVERED); + delivered.remove(curr); + + if(curr.p->m_ops > 0){ + jam(); + running.add(curr); + curr.p->scanFragState = ScanFragRec::LQH_ACTIVE; + curr.p->startFragTimer(ctcTimer); + nextReq->senderData = curr.i; + sendSignal(curr.p->lqhBlockref, GSN_SCAN_NEXTREQ, signal, + ScanFragNextReq::SignalLength, JBB); + + ndbout_c("delivered -> running"); + } else { + jam(); + completed.add(curr); + curr.p->scanFragState = ScanFragRec::COMPLETED; + curr.p->stopFragTimer(); + ndbout_c("delivered -> completed"); + } + }//for -void Dbtc::sendScanProcConf(Signal* signal){ - signal->theData[0] = scanptr.i; - signal->theData[1] = scanFragptr.i; - sendSignal(cownref, GSN_SCAN_PROCCONF, signal, 2, JBB); + /** + * All queued with data should be closed + */ + ScanFragList queued(c_scan_frag_pool, scanP->m_queued_scan_frags); + for(queued.first(ptr); !ptr.isNull(); ){ + jam(); + ndbrequire(ptr.p->scanFragState == ScanFragRec::QUEUED_FOR_DELIVERY); + ScanFragRecPtr curr = ptr; // Remove while iterating... + queued.next(ptr); + + queued.remove(curr); + scanP->m_queued_count--; + + if(curr.p->m_ops > 0){ + jam(); + running.add(curr); + curr.p->scanFragState = ScanFragRec::LQH_ACTIVE; + curr.p->startFragTimer(ctcTimer); + nextReq->senderData = curr.i; + sendSignal(curr.p->lqhBlockref, GSN_SCAN_NEXTREQ, signal, + ScanFragNextReq::SignalLength, JBB); + + ndbout_c("queued -> running"); + } else { + jam(); + completed.add(curr); + curr.p->scanFragState = ScanFragRec::COMPLETED; + curr.p->stopFragTimer(); + ndbout_c("queued -> completed"); + } + } + } + close_scan_req_send_conf(signal, scanptr); } -void Dbtc::releaseScanrec(Signal* signal) { - scanptr.p->nextScan = cfirstfreeScanrec; - scanptr.p->scanState = ScanRecord::IDLE; - scanptr.p->scanTcrec = RNIL; - cfirstfreeScanrec = scanptr.i; -}//Dbtc::releaseScanrec() - -void Dbtc::releaseScanFragrec(Signal* signal) { - scanFragptr.p->nextScanFrag = cfirstfreeScanFragrec; - scanFragptr.p->scanFragState = ScanFragRec::IDLE; - cfirstfreeScanFragrec = scanFragptr.i; - scanFragptr.p->stopFragTimer(); -}//Dbtc::releaseScanFragrec() +void +Dbtc::close_scan_req_send_conf(Signal* signal, ScanRecordPtr scanPtr){ -void Dbtc::releaseScanOprec(Signal* signal) { - scanOpptr.p->nextScanOp = cfirstfreeScanOprec; - cfirstfreeScanOprec = scanOpptr.i; -}//Dbtc::releaseScanOprec() + jam(); + ndbrequire(scanPtr.p->m_queued_scan_frags.isEmpty()); + ndbrequire(scanPtr.p->m_delivered_scan_frags.isEmpty()); + if(!scanPtr.p->m_running_scan_frags.isEmpty()){ + jam(); + return; + } + + const bool apiFail = (apiConnectptr.p->apiFailState == ZTRUE); + + if(!apiFail){ + jam(); + Uint32 ref = apiConnectptr.p->ndbapiBlockref; + ScanTabConf * conf = (ScanTabConf*)&signal->theData[0]; + conf->apiConnectPtr = apiConnectptr.p->ndbapiConnect; + conf->requestInfo = ScanTabConf::EndOfData; + conf->transId1 = apiConnectptr.p->transid[0]; + conf->transId2 = apiConnectptr.p->transid[1]; + sendSignal(ref, GSN_SCAN_TABCONF, signal, ScanTabConf::SignalLength, JBB); + } + + releaseScanResources(scanPtr); + + if(apiFail){ + jam(); + /** + * API has failed + */ + handleApiFailState(signal, apiConnectptr.i); + } +} void Dbtc::seizeScanrec(Signal* signal) { scanptr.i = cfirstfreeScanrec; @@ -9740,27 +9378,7 @@ void Dbtc::seizeScanrec(Signal* signal) { ndbrequire(scanptr.p->scanState == ScanRecord::IDLE); }//Dbtc::seizeScanrec() -void Dbtc::seizeScanFragrec(Signal* signal) { - scanFragptr.i = cfirstfreeScanFragrec; - ptrCheckGuard(scanFragptr, cscanFragrecFileSize, scanFragmentRecord); - cfirstfreeScanFragrec = scanFragptr.p->nextScanFrag; - scanFragptr.p->nextScanFrag = RNIL; - ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::IDLE); -}//Dbtc::seizeScanFragrec() - -void Dbtc::seizeScanOprec(Signal* signal) { - scanOpptr.i = cfirstfreeScanOprec; - ptrCheckGuard(scanOpptr, cscanOprecFileSize, scanOperationRecord); - cfirstfreeScanOprec = scanOpptr.p->nextScanOp; - scanOpptr.p->nextScanOp = RNIL; -}//Dbtc::seizeScanOprec() - - void Dbtc::sendScanFragReq(Signal* signal) { - arrGuard(scanFragptr.p->scanFragProcId, 16); - scanOpptr.i = scanptr.p->scanOprec[scanFragptr.p->scanFragProcId]; - ptrCheckGuard(scanOpptr, cscanOprecFileSize, scanOperationRecord); - Uint32 requestInfo = 0; ScanFragReq::setConcurrency(requestInfo, scanFragptr.p->scanFragConcurrency); ScanFragReq::setLockMode(requestInfo, scanptr.p->scanLockMode); @@ -9786,96 +9404,72 @@ void Dbtc::sendScanFragReq(Signal* signal) { req->transId1 = apiConnectptr.p->transid[0]; req->transId2 = apiConnectptr.p->transid[1]; for(int i = 0; i<16; i++){ - req->clientOpPtr[i] = scanOpptr.p->apiOpptr[i]; + req->clientOpPtr[i] = scanFragptr.p->m_apiPtr; } sendSignal(scanFragptr.p->lqhBlockref, GSN_SCAN_FRAGREQ, signal, 25, JBB); updateBuddyTimer(apiConnectptr); scanFragptr.p->startFragTimer(ctcTimer); - scanFragptr.p->scanFragCompletedStatus = ZFALSE; }//Dbtc::sendScanFragReq() void Dbtc::sendScanTabConf(Signal* signal) { jam(); - /******************************************************* - * Send SCAN_TABINFO with information about all - * received operations - *******************************************************/ - Int32 operationsToSend = scanptr.p->scanReceivedOperations; - Uint32 sstOpIndex = 0; - - while (operationsToSend > 0){ + Uint32* ops = signal->getDataPtrSend()+4; + Uint32 op_count = scanptr.p->m_queued_count; + if(4 + 3 * op_count > 25){ jam(); - - ScanTabInfo * info = (ScanTabInfo*)&signal->theData[0]; - info->apiConnectPtr = apiConnectptr.p->ndbapiConnect; - - for (int i = 0; i < 16; i++){ - jam(); - arrGuard(sstOpIndex, 16); - scanOpptr.i = scanptr.p->scanOprec[sstOpIndex]; - ptrCheckGuard(scanOpptr, cscanOprecFileSize, scanOperationRecord); - info->operLenAndIdx[i] = scanOpptr.p->scanOpLength[i]; - operationsToSend--; - scanOpptr.p->scanOpLength[i] = RNIL; - } - sstOpIndex++; - sendSignal(apiConnectptr.p->ndbapiBlockref, - GSN_SCAN_TABINFO, signal, ScanTabInfo::SignalLength, JBB); + ops += 21; } - - /******************************************************** - * Send SCAN_TABCONF signaling that a result set have - * been sent to the API - *********************************************************/ - Uint32 requestInfo = 0; - ScanTabConf::setOperations(requestInfo, scanptr.p->scanReceivedOperations); - ScanTabConf::setScanStatus(requestInfo, scanptr.p->scanCompletedStatus); - + ScanTabConf * conf = (ScanTabConf*)&signal->theData[0]; conf->apiConnectPtr = apiConnectptr.p->ndbapiConnect; - conf->requestInfo = requestInfo; + conf->requestInfo = op_count; conf->transId1 = apiConnectptr.p->transid[0]; conf->transId2 = apiConnectptr.p->transid[1]; - sendSignal(apiConnectptr.p->ndbapiBlockref, - GSN_SCAN_TABCONF, signal, ScanTabConf::SignalLength, JBB); - - scanptr.p->scanReceivedOperations = 0; - // Start the scanRec-timer again and wait for response from the API. - setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__); - updateBuddyTimer(apiConnectptr); + ScanFragRecPtr ptr; + ScanRecord* scanP = scanptr.p; + ScanFragList queued(c_scan_frag_pool, scanP->m_queued_scan_frags); + ScanFragList completed(c_scan_frag_pool, scanP->m_completed_scan_frags); + ScanFragList delivered(c_scan_frag_pool, scanP->m_delivered_scan_frags); + for(queued.first(ptr); !ptr.isNull(); ){ + ndbrequire(ptr.p->scanFragState == ScanFragRec::QUEUED_FOR_DELIVERY); + ScanFragRecPtr curr = ptr; // Remove while iterating... + queued.next(ptr); + + * ops++ = curr.p->m_apiPtr; + * ops++ = curr.i; + * ops++ = (curr.p->m_totalLen << 5) + curr.p->m_ops; + + queued.remove(curr); + if(curr.p->m_ops > 0){ + delivered.add(curr); + curr.p->scanFragState = ScanFragRec::DELIVERED; + curr.p->stopFragTimer(); + } else { + (* --ops) = ScanTabConf::EndOfData; ops++; + completed.add(curr); + curr.p->scanFragState = ScanFragRec::COMPLETED; + curr.p->stopFragTimer(); + } + } + + if(4 + 3 * op_count > 25){ + jam(); + LinearSectionPtr ptr[3]; + ptr[0].p = signal->getDataPtrSend()+25; + ptr[0].sz = 3 * op_count; + sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_SCAN_TABCONF, signal, + ScanTabConf::SignalLength, JBB, ptr, 1); + } else { + jam(); + sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_SCAN_TABCONF, signal, + ScanTabConf::SignalLength + 3 * op_count, JBB); + } + scanptr.p->m_queued_count = 0; }//Dbtc::sendScanTabConf() -/* - * Write index and length of all operations received into - * scanOprec->scanOpLength buffer - */ -void Dbtc::setScanReceived(Signal* signal, Uint32 noCompletedOps) -{ - UintR tssrIndividual; - UintR tssrOprecIndex; - UintR tssrLengthPlusIndex; - UintR tssrOpIndex; - - ndbrequire(noCompletedOps <= 16); - tssrIndividual = scanFragptr.p->scanIndividual; - for (Uint32 i = 0; i < noCompletedOps; i++) { - jam(); - tssrOprecIndex = scanptr.p->scanReceivedOperations >> 4; - arrGuard(tssrOprecIndex, 16); - scanOpptr.i = scanptr.p->scanOprec[tssrOprecIndex]; - ptrCheckGuard(scanOpptr, cscanOprecFileSize, scanOperationRecord); - tssrLengthPlusIndex = tssrIndividual << 24; - tssrLengthPlusIndex += cdata[i]; - tssrOpIndex = scanptr.p->scanReceivedOperations & 15; - scanOpptr.p->scanOpLength[tssrOpIndex] = tssrLengthPlusIndex; - scanptr.p->scanReceivedOperations++; - tssrIndividual++; - }//for -}//Dbtc::setScanReceived() - void Dbtc::gcpTcfinished(Signal* signal) { signal->theData[1] = tcheckGcpId; @@ -10032,7 +9626,6 @@ void Dbtc::inithost(Signal* signal) hostptr.p->inPackedList = false; hostptr.p->takeOverStatus = TOS_NOT_DEFINED; hostptr.p->lqhTransStatus = LTS_IDLE; - hostptr.p->ndbVersion = ZNIL; hostptr.p->noOfWordsTCKEYCONF = 0; hostptr.p->noOfWordsTCINDXCONF = 0; hostptr.p->noOfPackedWordsLqh = 0; @@ -10040,7 +9633,8 @@ void Dbtc::inithost(Signal* signal) }//for }//Dbtc::inithost() -void Dbtc::initialiseRecordsLab(Signal* signal, UintR Tdata0) +void Dbtc::initialiseRecordsLab(Signal* signal, UintR Tdata0, + Uint32 retRef, Uint32 retData) { switch (Tdata0) { case 0: @@ -10090,7 +9684,14 @@ void Dbtc::initialiseRecordsLab(Signal* signal, UintR Tdata0) case 11: jam(); initTcFail(signal); - returnInitialiseRecordsLab(signal); + + { + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = retData; + sendSignal(retRef, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); + } return; break; default: @@ -10099,16 +9700,26 @@ void Dbtc::initialiseRecordsLab(Signal* signal, UintR Tdata0) return; break; }//switch - sendInitialiseRecords(signal, (Tdata0 + 1)); - return; -}//Dbtc::initialiseRecordsLab() + signal->theData[0] = TcContinueB::ZINITIALISE_RECORDS; + signal->theData[1] = Tdata0 + 1; + signal->theData[2] = 0; + signal->theData[3] = retRef; + signal->theData[4] = retData; + sendSignal(DBTC_REF, GSN_CONTINUEB, signal, 5, JBB); +} + +/* ========================================================================= */ +/* ======= INITIALISE_SCANREC ======= */ +/* */ +/* ========================================================================= */ void Dbtc::initialiseScanrec(Signal* signal) { ndbrequire(cscanrecFileSize > 0); for (scanptr.i = 0; scanptr.i < cscanrecFileSize; scanptr.i++) { jam(); ptrAss(scanptr, scanRecord); + new (scanptr.p) ScanRecord(); scanptr.p->scanState = ScanRecord::IDLE; scanptr.p->nextScan = scanptr.i + 1; }//for @@ -10120,34 +9731,10 @@ void Dbtc::initialiseScanrec(Signal* signal) void Dbtc::initialiseScanFragrec(Signal* signal) { - ndbrequire(cscanFragrecFileSize > 0); - for (scanFragptr.i = 0; scanFragptr.i < cscanFragrecFileSize; - scanFragptr.i++) { - jam(); - ptrAss(scanFragptr, scanFragmentRecord); - scanFragptr.p->scanFragState = ScanFragRec::IDLE; - scanFragptr.p->stopFragTimer(); - scanFragptr.p->nextScanFrag = scanFragptr.i + 1; - }//for - scanFragptr.i = cscanFragrecFileSize - 1; - ptrAss(scanFragptr, scanFragmentRecord); - scanFragptr.p->nextScanFrag = RNIL; - cfirstfreeScanFragrec = 0; }//Dbtc::initialiseScanFragrec() void Dbtc::initialiseScanOprec(Signal* signal) { - ndbrequire(cscanOprecFileSize > 0); - for (scanOpptr.i = 0; scanOpptr.i < cscanOprecFileSize; scanOpptr.i++) { - jam(); - ptrAss(scanOpptr, scanOperationRecord); - scanOpptr.p->nextScanOp = scanOpptr.i + 1; - }//for - scanOpptr.i = cscanOprecFileSize - 1; - ptrAss(scanOpptr, scanOperationRecord); - scanOpptr.p->nextScanOp = RNIL; - cfirstfreeScanOprec = 0; - cnoFreeScanOprec = cscanOprecFileSize; }//Dbtc::initialiseScanOprec() void Dbtc::initTable(Signal* signal) @@ -10272,8 +9859,8 @@ void Dbtc::releaseAbortResources(Signal* signal) if (apiConnectptr.p->cachePtr != RNIL) { cachePtr.i = apiConnectptr.p->cachePtr; ptrCheckGuard(cachePtr, ccacheFilesize, cacheRecord); - releaseAttrinfo(signal); - releaseKeys(signal); + releaseAttrinfo(); + releaseKeys(); }//if tcConnectptr.i = apiConnectptr.p->firstTcConnect; while (tcConnectptr.i != RNIL) { @@ -10282,7 +9869,7 @@ void Dbtc::releaseAbortResources(Signal* signal) // Clear any markers that were set in CS_RECEIVING state clearCommitAckMarker(apiConnectptr.p, tcConnectptr.p); rarTcConnectptr.i = tcConnectptr.p->nextTcConnect; - releaseTcCon(signal); + releaseTcCon(); tcConnectptr.i = rarTcConnectptr.i; }//while apiConnectptr.p->firstTcConnect = RNIL; @@ -10373,7 +9960,7 @@ void Dbtc::releaseGcp(Signal* signal) cfirstfreeGcp = gcpPtr.i; }//Dbtc::releaseGcp() -void Dbtc::releaseKeys(Signal* signal) +void Dbtc::releaseKeys() { UintR Tmp; databufptr.i = cachePtr.p->firstKeybuf; @@ -10529,18 +10116,6 @@ void Dbtc::sendContinueTimeOutControl(Signal* signal, Uint32 TapiConPtr) sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB); }//Dbtc::sendContinueTimeOutControl() -/* ------------------------------------------------------------------------- - * SEND REAL-TIME BREAK DURING INITIALISATION OF VARIABLES DURING - * SYSTEM RESTART. - * ------------------------------------------------------------------------- */ -void Dbtc::sendInitialiseRecords(Signal* signal, UintR Tnext) -{ - signal->theData[0] = TcContinueB::ZINITIALISE_RECORDS; - signal->theData[1] = Tnext; - signal->theData[2] = 0; - sendSignal(DBTC_REF, GSN_CONTINUEB, signal, 3, JBB); -}//Dbtc::sendInitialiseRecords() - void Dbtc::sendKeyinfo(Signal* signal, BlockReference TBRef, Uint32 len) { signal->theData[0] = tcConnectptr.i; @@ -10664,20 +10239,15 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal) ScanFragRecPtr sfp; sfp.i = recordNo; - ptrAss(sfp, scanFragmentRecord); - infoEvent("Dbtc::ScanFragRec[%d]: state=%d, status=%d, " - "fragid=%d, procid=%d, ", + c_scan_frag_pool.getPtr(sfp); + infoEvent("Dbtc::ScanFragRec[%d]: state=%d fragid=%d", sfp.i, sfp.p->scanFragState, - sfp.p->scanFragCompletedStatus, - sfp.p->scanFragId, - sfp.p->scanFragProcId); - infoEvent(" nodeid=%d, ind=%d, concurr=%d, timer=%d, next=%d", - sfp.p->scanFragNodeId, - sfp.p->scanIndividual, + sfp.p->scanFragId); + infoEvent(" nodeid=%d, concurr=%d, timer=%d", + refToNode(sfp.p->lqhBlockref), sfp.p->scanFragConcurrency, - sfp.p->scanFragTimer, - sfp.p->nextScanFrag); + sfp.p->scanFragTimer); } // Dump all ScanRecords @@ -10744,11 +10314,10 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal) ScanRecordPtr sp; sp.i = recordNo; ptrAss(sp, scanRecord); - infoEvent("Dbtc::ScanRecord[%d]: state=%d, scanOprec=%d, " + infoEvent("Dbtc::ScanRecord[%d]: state=%d" "nextfrag=%d, nofrag=%d", sp.i, sp.p->scanState, - sp.p->noScanOprec, sp.p->scanNextFragId, sp.p->scanNoFrag); infoEvent(" ailen=%d, para=%d, receivedop=%d, noOprePperFrag=%d", @@ -10756,17 +10325,11 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal) sp.p->scanParallel, sp.p->scanReceivedOperations, sp.p->noOprecPerFrag); - infoEvent(" schv=%d, tab=%d, sproc=%d, noTI=%d, norecTI=%d", + infoEvent(" schv=%d, tab=%d, sproc=%d", sp.p->scanSchemaVersion, sp.p->scanTableref, - sp.p->scanStoredProcId, - sp.p->noScanTabInfo, - sp.p->scanTabInfoReceived); - infoEvent(" apiclosed=%d, noProcCompl=%d, " - "complStat=%d, lhold=%d, lmode=%d", - sp.p->apiIsClosed, - sp.p->scanProcessesCompleted, - sp.p->scanCompletedStatus, + sp.p->scanStoredProcId); + infoEvent(" lhold=%d, lmode=%d", sp.p->scanLockHold, sp.p->scanLockMode); infoEvent(" apiRec=%d, next=%d", @@ -10774,13 +10337,20 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal) if (sp.p->scanState != ScanRecord::IDLE){ // Request dump of ScanFragRec - for (Uint32 i = 0; i < 16; i++){ - if (sp.p->scanFragrec[i] != RNIL){ - dumpState->args[0] = DumpStateOrd::TcDumpOneScanFragRec; - dumpState->args[1] = sp.p->scanFragrec[i]; - execDUMP_STATE_ORD(signal); - } - } + ScanFragRecPtr sfptr; +#define DUMP_SFR(x){\ + ScanFragList list(c_scan_frag_pool, x);\ + for(list.first(sfptr); !sfptr.isNull(); list.next(sfptr)){\ + dumpState->args[0] = DumpStateOrd::TcDumpOneScanFragRec; \ + dumpState->args[1] = sfptr.i;\ + execDUMP_STATE_ORD(signal);\ + }} + + DUMP_SFR(sp.p->m_running_scan_frags); + DUMP_SFR(sp.p->m_queued_scan_frags); + DUMP_SFR(sp.p->m_delivered_scan_frags); + DUMP_SFR(sp.p->m_completed_scan_frags); + // Request dump of ApiConnectRecord dumpState->args[0] = DumpStateOrd::TcDumpOneApiConnectRec; dumpState->args[1] = sp.p->scanApiRec; @@ -10861,7 +10431,7 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal) void Dbtc::execSET_VAR_REQ(Signal* signal) { - +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); int val = setVarReq->value(); @@ -10886,7 +10456,7 @@ void Dbtc::execSET_VAR_REQ(Signal* signal) default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); } // switch - +#endif } void Dbtc::execABORT_ALL_REQ(Signal* signal) @@ -10933,7 +10503,6 @@ void Dbtc::execABORT_ALL_REQ(Signal* signal) c_abortRec.oldTimeOutValue = ctimeOutValue; ctimeOutValue = 0; - const Uint32 sleepTime = (2 * 10 * ctimeOutCheckDelay + 199) / 200; checkAbortAllTimeout(signal, (sleepTime == 0 ? 1 : sleepTime)); diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index 053b853fa82..70b8a739fef 100644 --- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -950,9 +950,6 @@ typedef Ptr<TableDescriptor> TableDescriptorPtr; struct HostBuffer { bool inPackedList; - Uint32 packetLenRC; - Uint32 noOfPacketsRC; - Uint32 packetBufferRC[29]; Uint32 packetLenTA; Uint32 noOfPacketsTA; Uint32 packetBufferTA[30]; @@ -1029,7 +1026,7 @@ private: void execFSREADCONF(Signal* signal); void execFSREADREF(Signal* signal); void execNDB_STTOR(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); void execSET_VAR_REQ(Signal* signal); void execDROP_TAB_REQ(Signal* signal); void execALTER_TAB_REQ(Signal* signal); @@ -1637,11 +1634,7 @@ private: //------------------------------------------------------------------ //------------------------------------------------------------------ - void bufferREADCONF(Signal* signal, BlockReference aRef, Uint32* buffer, Uint32 Tlen); - -//------------------------------------------------------------------ -//------------------------------------------------------------------ - void bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32* buffer, Uint32 Tlen); + void bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32 Tlen); //------------------------------------------------------------------ // Trigger handling routines @@ -1900,7 +1893,7 @@ private: void releaseTabDescr(Tablerec* const regTabPtr); void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* const regTabPtr); - void initialiseRecordsLab(Signal* signal, Uint32 switchData); + void initialiseRecordsLab(Signal* signal, Uint32 switchData, Uint32, Uint32); void initializeAttrbufrec(); void initializeCheckpointInfoRec(); void initializeDiskBufferSegmentRecord(); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp b/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp index 90c6dbc6802..cd5057d8a62 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp @@ -35,7 +35,6 @@ void Dbtup::execSEND_PACKED(Signal* signal) hostId = cpackedList[i]; ndbrequire((hostId - 1) < (MAX_NODES - 1)); // Also check not zero Uint32 TpacketTA = hostBuffer[hostId].noOfPacketsTA; - Uint32 TpacketRC = hostBuffer[hostId].noOfPacketsRC; if (TpacketTA != 0) { ljam(); BlockReference TBref = numberToRef(API_PACKED, hostId); @@ -47,91 +46,17 @@ void Dbtup::execSEND_PACKED(Signal* signal) hostBuffer[hostId].noOfPacketsTA = 0; hostBuffer[hostId].packetLenTA = 0; }//if - if (TpacketRC != 0) { - ljam(); - BlockReference TBref = numberToRef(API_PACKED, hostId); - Uint32 TpacketLen = hostBuffer[hostId].packetLenRC; - MEMCOPY_NO_WORDS(&signal->theData[0], - &hostBuffer[hostId].packetBufferRC[0], - TpacketLen); - sendSignal(TBref, GSN_READCONF, signal, TpacketLen, JBB); - hostBuffer[hostId].noOfPacketsRC = 0; - hostBuffer[hostId].packetLenRC = 0; - }//if hostBuffer[hostId].inPackedList = false; }//for cpackedListIndex = 0; }//Dbtup::execSEND_PACKED() -void Dbtup::bufferREADCONF(Signal* signal, BlockReference aRef, - Uint32* buffer, Uint32 Tlen) -{ - Uint32 hostId = refToNode(aRef); - Uint32 Theader = ((refToBlock(aRef) << 16) + (Tlen-3)); - - ndbrequire(hostId < MAX_NODES); - Uint32 TpacketLen = hostBuffer[hostId].packetLenRC; - Uint32 TnoOfPackets = hostBuffer[hostId].noOfPacketsRC; - Uint32 sig0 = signal->theData[0]; - Uint32 sig1 = signal->theData[1]; - Uint32 sig2 = signal->theData[2]; - Uint32 sig3 = signal->theData[3]; - - BlockReference TBref = numberToRef(API_PACKED, hostId); - - if ((Tlen + TpacketLen + 1) <= 25) { -// ---------------------------------------------------------------- -// There is still space in the buffer. We will copy it into the -// buffer. -// ---------------------------------------------------------------- - ljam(); - updatePackedList(signal, hostId); - } else if (TnoOfPackets == 1) { -// ---------------------------------------------------------------- -// The buffer is full and there was only one packet buffered. We -// will send this as a normal signal. -// ---------------------------------------------------------------- - Uint32 TnewRef = numberToRef((hostBuffer[hostId].packetBufferRC[0] >> 16), - hostId); - MEMCOPY_NO_WORDS(&signal->theData[0], - &hostBuffer[hostId].packetBufferRC[1], - TpacketLen - 1); - sendSignal(TnewRef, GSN_READCONF, signal, (TpacketLen - 1), JBB); - TpacketLen = 0; - TnoOfPackets = 0; - } else { -// ---------------------------------------------------------------- -// The buffer is full but at least two packets. Send those in -// packed form. -// ---------------------------------------------------------------- - MEMCOPY_NO_WORDS(&signal->theData[0], - &hostBuffer[hostId].packetBufferRC[0], - TpacketLen); - sendSignal(TBref, GSN_READCONF, signal, TpacketLen, JBB); - TpacketLen = 0; - TnoOfPackets = 0; - }//if -// ---------------------------------------------------------------- -// Copy the signal into the buffer -// ---------------------------------------------------------------- - hostBuffer[hostId].packetBufferRC[TpacketLen + 0] = Theader; - hostBuffer[hostId].packetBufferRC[TpacketLen + 1] = sig0; - hostBuffer[hostId].packetBufferRC[TpacketLen + 2] = sig1; - hostBuffer[hostId].packetBufferRC[TpacketLen + 3] = sig2; - hostBuffer[hostId].packetBufferRC[TpacketLen + 4] = sig3; - hostBuffer[hostId].noOfPacketsRC = TnoOfPackets + 1; - hostBuffer[hostId].packetLenRC = Tlen + TpacketLen + 1; - MEMCOPY_NO_WORDS(&hostBuffer[hostId].packetBufferRC[TpacketLen + 5], - buffer, - Tlen - 4); -}//Dbtup::bufferREADCONF() - void Dbtup::bufferTRANSID_AI(Signal* signal, BlockReference aRef, - Uint32* buffer, Uint32 Tlen) + Uint32 Tlen) { Uint32 hostId = refToNode(aRef); Uint32 Theader = ((refToBlock(aRef) << 16)+(Tlen-3)); - + ndbrequire(hostId < MAX_NODES); Uint32 TpacketLen = hostBuffer[hostId].packetLenTA; Uint32 TnoOfPackets = hostBuffer[hostId].noOfPacketsTA; @@ -148,7 +73,7 @@ void Dbtup::bufferTRANSID_AI(Signal* signal, BlockReference aRef, // ---------------------------------------------------------------- ljam(); updatePackedList(signal, hostId); - } else if (TnoOfPackets == 1) { + } else if (false && TnoOfPackets == 1) { // ---------------------------------------------------------------- // The buffer is full and there was only one packet buffered. We // will send this as a normal signal. @@ -183,7 +108,7 @@ void Dbtup::bufferTRANSID_AI(Signal* signal, BlockReference aRef, hostBuffer[hostId].noOfPacketsTA = TnoOfPackets + 1; hostBuffer[hostId].packetLenTA = Tlen + TpacketLen + 1; MEMCOPY_NO_WORDS(&hostBuffer[hostId].packetBufferTA[TpacketLen + 4], - buffer, + &signal->theData[25], Tlen - 3); }//Dbtup::bufferTRANSID_AI() @@ -206,124 +131,122 @@ void Dbtup::sendReadAttrinfo(Signal* signal, const Operationrec * const regOperPtr) { const BlockReference recBlockref = regOperPtr->recBlockref; - bool toOwnNode = refToNode(recBlockref) == getOwnNodeId(); - bool connectedToNode = getNodeInfo(refToNode(recBlockref)).m_connected; - const Uint32 type = getNodeInfo(refToNode(recBlockref)).m_type; + const Uint32 block = refToBlock(recBlockref); + const Uint32 nodeId = refToNode(recBlockref); + + bool connectedToNode = getNodeInfo(nodeId).m_connected; + const Uint32 type = getNodeInfo(nodeId).m_type; bool is_api = (type >= NodeInfo::API && type <= NodeInfo::REP); + bool old_dest = (getNodeInfo(nodeId).m_version < MAKE_VERSION(3,5,0)); - if (ERROR_INSERTED(4006)){ + if (ERROR_INSERTED(4006) && (nodeId != getOwnNodeId())){ // Use error insert to turn routing on ljam(); connectedToNode = false; } - if (!toOwnNode && !connectedToNode){ - /** - * If this node does not have a direct connection - * to the receiving node we want to send the signals - * routed via the node that controls this read - */ - Uint32 routeBlockref = regOperPtr->coordinatorTC; - + Uint32 sig0 = regOperPtr->tcOperationPtr; + Uint32 sig1 = regOperPtr->transid1; + Uint32 sig2 = regOperPtr->transid2; + + TransIdAI * transIdAI = (TransIdAI *)signal->getDataPtrSend(); + transIdAI->connectPtr = sig0; + transIdAI->transId[0] = sig1; + transIdAI->transId[1] = sig2; + + if (connectedToNode){ /** - * Fill in a TRANSID_AI signal, use last word to store - * final destination and send it to route node - * as signal TRANSID_AI_R (R as in Routed) - */ - TransIdAI * const transIdAI = (TransIdAI *)signal->getDataPtr(); - transIdAI->connectPtr = regOperPtr->tcOperationPtr; - transIdAI->transId[0] = regOperPtr->transid1; - transIdAI->transId[1] = regOperPtr->transid2; + * Own node -> execute direct + */ + if(nodeId != getOwnNodeId()){ + ljam(); + + /** + * Send long sig + */ + if(ToutBufIndex >= 22 && is_api && !old_dest) { + ljam(); + LinearSectionPtr ptr[3]; + ptr[0].p = &signal->theData[25]; + ptr[0].sz = ToutBufIndex; + sendSignal(recBlockref, GSN_TRANSID_AI, signal, 3, JBB, ptr, 1); + return; + } - Uint32 tot = ToutBufIndex; - Uint32 sent = 0; - Uint32 maxLen = TransIdAI::DataLength - 1; - while (sent < tot) { - ljam(); - Uint32 dataLen = (tot - sent > maxLen) ? maxLen : tot - sent; - Uint32 sigLen = dataLen + TransIdAI::HeaderLength + 1; - MEMCOPY_NO_WORDS(&transIdAI->attrData, - &coutBuffer[sent], - dataLen); - // Set final destination in last word - transIdAI->attrData[dataLen] = recBlockref; - - sendSignal(routeBlockref, GSN_TRANSID_AI_R, - signal, sigLen, JBB); - sent += dataLen; + /** + * short sig + api -> buffer + */ +#ifndef NDB_NO_DROPPED_SIGNAL + if (ToutBufIndex < 22 && is_api){ + ljam(); + bufferTRANSID_AI(signal, recBlockref, 3+ToutBufIndex); + return; + }//if +#endif + + /** + * rest -> old send sig + */ + Uint32 * src = signal->theData+25; + if(ToutBufIndex >= 22){ + do { + ljam(); + MEMCOPY_NO_WORDS(&signal->theData[3], src, 22); + sendSignal(recBlockref, GSN_TRANSID_AI, signal, 25, JBB); + ToutBufIndex -= 22; + src += 22; + } while(ToutBufIndex >= 22); + } + if(ToutBufIndex > 0){ + ljam(); + MEMCOPY_NO_WORDS(&signal->theData[3], src, ToutBufIndex); + sendSignal(recBlockref, GSN_TRANSID_AI, signal, 3+ToutBufIndex, JBB); + } + return; } + EXECUTE_DIRECT(block, GSN_TRANSID_AI, signal, 3 + ToutBufIndex); + ljamEntry(); return; } - Uint32 TbufIndex = 0; - Uint32 sig0 = regOperPtr->tcOperationPtr; - Uint32 sig1 = regOperPtr->transid1; - Uint32 sig2 = regOperPtr->transid2; - signal->theData[0] = sig0; - signal->theData[1] = sig1; - signal->theData[2] = sig2; - - while (ToutBufIndex > 21) { - ljam(); - MEMCOPY_NO_WORDS(&signal->theData[3], - &coutBuffer[TbufIndex], - 22); - TbufIndex += 22; - ToutBufIndex -= 22; - const BlockReference sendBref = regOperPtr->recBlockref; - if (refToNode(sendBref) != getOwnNodeId()) { - ljam(); - sendSignal(sendBref, GSN_TRANSID_AI, signal, 25, JBB); - ljam(); - } else { - ljam(); - EXECUTE_DIRECT(refToBlock(sendBref), GSN_TRANSID_AI, signal, 25); - ljamEntry(); - }//if - }//while - - Uint32 TsigNumber; - Uint32 TsigLen; - Uint32 TdataIndex; - if ((regOperPtr->opSimple == ZTRUE) && - (regOperPtr->optype == ZREAD)) { - /* DIRTY OPERATIONS ARE ALSO SIMPLE */ - ljam(); - Uint32 sig3 = regOperPtr->attroutbufLen; - TdataIndex = 4; - TsigLen = 4 + ToutBufIndex; - TsigNumber = GSN_READCONF; - signal->theData[3] = sig3; - if ((TsigLen < 18) && is_api){ - bufferREADCONF(signal, regOperPtr->recBlockref, - &coutBuffer[TbufIndex], TsigLen); - return; - }//if - } else if (ToutBufIndex > 0) { - ljam(); - TdataIndex = 3; - TsigLen = 3 + ToutBufIndex; - TsigNumber = GSN_TRANSID_AI; - if ((TsigLen < 18) && is_api){ - ljam(); - bufferTRANSID_AI(signal, regOperPtr->recBlockref, - &coutBuffer[TbufIndex], TsigLen); - return; - }//if - } else { + /** + * If this node does not have a direct connection + * to the receiving node we want to send the signals + * routed via the node that controls this read + */ + Uint32 routeBlockref = regOperPtr->coordinatorTC; + + if(is_api && !old_dest){ ljam(); + transIdAI->attrData[0] = recBlockref; + LinearSectionPtr ptr[3]; + ptr[0].p = &signal->theData[25]; + ptr[0].sz = ToutBufIndex; + sendSignal(routeBlockref, GSN_TRANSID_AI_R, signal, 4, JBB, ptr, 1); return; - }//if - MEMCOPY_NO_WORDS(&signal->theData[TdataIndex], - &coutBuffer[TbufIndex], - ToutBufIndex); - const BlockReference sendBref = regOperPtr->recBlockref; - if (refToNode(sendBref) != getOwnNodeId()) { - ljam(); - sendSignal(sendBref, TsigNumber, signal, TsigLen, JBB); - } else { - EXECUTE_DIRECT(refToBlock(sendBref), GSN_TRANSID_AI, signal, TsigLen); - ljamEntry(); - }//if + } + + /** + * Fill in a TRANSID_AI signal, use last word to store + * final destination and send it to route node + * as signal TRANSID_AI_R (R as in Routed) + */ + Uint32 tot = ToutBufIndex; + Uint32 sent = 0; + Uint32 maxLen = TransIdAI::DataLength - 1; + while (sent < tot) { + ljam(); + Uint32 dataLen = (tot - sent > maxLen) ? maxLen : tot - sent; + Uint32 sigLen = dataLen + TransIdAI::HeaderLength + 1; + MEMCOPY_NO_WORDS(&transIdAI->attrData, + &signal->theData[25+sent], + dataLen); + // Set final destination in last word + transIdAI->attrData[dataLen] = recBlockref; + + sendSignal(routeBlockref, GSN_TRANSID_AI_R, + signal, sigLen, JBB); + sent += dataLen; + } }//Dbtup::sendReadAttrinfo() diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index 07bad00acf1..eb9ff08c2b1 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -873,6 +873,7 @@ int Dbtup::handleReadReq(Signal* signal, Page* pagePtr) { Uint32 Ttupheadoffset = regOperPtr->pageOffset; + const BlockReference sendBref = regOperPtr->recBlockref; if (regTabPtr->checksumIndicator && (calculateChecksum(pagePtr, Ttupheadoffset, regTabPtr->tupheadsize) != 0)) { @@ -882,14 +883,29 @@ int Dbtup::handleReadReq(Signal* signal, return -1; }//if + Uint32 * dst = &signal->theData[25]; + Uint32 dstLen = (sizeof(signal->theData) / 4) - 25; + const Uint32 node = refToNode(sendBref); + if(node != 0 && node != getOwnNodeId()) { + ; + } else { + jam(); + /** + * execute direct + */ + dst = &signal->theData[3]; + dstLen = (sizeof(signal->theData) / 4) - 3; + } + if (regOperPtr->interpretedExec != 1) { jam(); + Uint32 TnoOfDataRead = readAttributes(pagePtr, Ttupheadoffset, &cinBuffer[0], regOperPtr->attrinbufLen, - &coutBuffer[0], - (Uint32)ZATTR_BUFFER_SIZE); + dst, + dstLen); if (TnoOfDataRead != (Uint32)-1) { /* ------------------------------------------------------------------------- */ // We have read all data into coutBuffer. Now send it to the API. @@ -1214,11 +1230,8 @@ int Dbtup::interpreterStartLab(Signal* signal, Uint32 RattrinbufLen = regOperPtr->attrinbufLen; const BlockReference sendBref = regOperPtr->recBlockref; - Uint32 * dst = &coutBuffer[0]; - Uint32 dstLen = sizeof(coutBuffer) / 4; - Uint32 * tmp = &signal->theData[3]; - Uint32 tmpLen = (sizeof(signal->theData) / 4) - 3; - bool executeDirect = false; + Uint32 * dst = &signal->theData[25]; + Uint32 dstLen = (sizeof(signal->theData) / 4) - 25; const Uint32 node = refToNode(sendBref); if(node != 0 && node != getOwnNodeId()) { ; @@ -1227,12 +1240,8 @@ int Dbtup::interpreterStartLab(Signal* signal, /** * execute direct */ - executeDirect = true; dst = &signal->theData[3]; dstLen = (sizeof(signal->theData) / 4) - 3; - - tmp = &coutBuffer[0]; - tmpLen = sizeof(coutBuffer) / 4; } RtotalLen = RinitReadLen; @@ -1292,8 +1301,8 @@ int Dbtup::interpreterStartLab(Signal* signal, RexecRegionLen, &cinBuffer[RsubPC], RsubLen, - tmp, - tmpLen); + &coutBuffer[0], + sizeof(coutBuffer) / 4); if (TnoDataRW != (Uint32)-1) { RinstructionCounter += RexecRegionLen; RlogSize = TnoDataRW; @@ -1350,20 +1359,7 @@ int Dbtup::interpreterStartLab(Signal* signal, }//if regOperPtr->logSize = RlogSize; regOperPtr->attroutbufLen = RattroutCounter; - if(!executeDirect) { - jam(); - sendReadAttrinfo(signal, RattroutCounter, regOperPtr); - } else { - jam(); - Uint32 sig0 = regOperPtr->tcOperationPtr; - Uint32 sig1 = regOperPtr->transid1; - Uint32 sig2 = regOperPtr->transid2; - signal->theData[0] = sig0; - signal->theData[1] = sig1; - signal->theData[2] = sig2; - EXECUTE_DIRECT(refToBlock(sendBref), GSN_TRANSID_AI, signal, - 3 + RattroutCounter); - }//if + sendReadAttrinfo(signal, RattroutCounter, regOperPtr); if (RlogSize > 0) { sendLogAttrinfo(signal, RlogSize, regOperPtr); }//if diff --git a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 982e1b8df24..3b54817edb0 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -27,10 +27,8 @@ #include <signaldata/FsConf.hpp> #include <signaldata/FsRef.hpp> #include <signaldata/FsRemoveReq.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/TupCommit.hpp> #include <signaldata/TupKey.hpp> -#include <signaldata/TupSizeAltReq.hpp> #include <signaldata/DropTab.hpp> #include <new> @@ -118,7 +116,7 @@ Dbtup::Dbtup(const class Configuration & conf) addRecSignal(GSN_FSREADCONF, &Dbtup::execFSREADCONF); addRecSignal(GSN_FSREADREF, &Dbtup::execFSREADREF); addRecSignal(GSN_NDB_STTOR, &Dbtup::execNDB_STTOR); - addRecSignal(GSN_SIZEALT_REP, &Dbtup::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbtup::execREAD_CONFIG_REQ, true); addRecSignal(GSN_SET_VAR_REQ, &Dbtup::execSET_VAR_REQ); // Trigger Signals @@ -538,7 +536,8 @@ void Dbtup::execCONTINUEB(Signal* signal) break; case ZINITIALISE_RECORDS: ljam(); - initialiseRecordsLab(signal, dataPtr); + initialiseRecordsLab(signal, dataPtr, + signal->theData[2], signal->theData[3]); break; case ZREL_FRAG: ljam(); @@ -610,22 +609,37 @@ void Dbtup::execSTTOR(Signal* signal) // SIZE_ALTREP INITIALIZE DATA STRUCTURES, FILES AND DS VARIABLES, GET READY FOR EXTERNAL // CONNECTIONS. /************************************************************************************************/ -void Dbtup::execSIZEALT_REP(Signal* signal) +void Dbtup::execREAD_CONFIG_REQ(Signal* signal) { - BlockReference tsizealtBlockRef; - + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + ljamEntry(); - tsizealtBlockRef = signal->theData[TupSizeAltReq::IND_BLOCK_REF]; - cnoOfFragrec = signal->theData[TupSizeAltReq::IND_FRAG]; - cnoOfOprec = signal->theData[TupSizeAltReq::IND_OP_RECS]; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_FRAG, &cnoOfFragrec)); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_OP_RECS, &cnoOfOprec)); + // MemorySpaceTuples is specified in 8k pages, divide by 4 for 32k pages - Uint64 noOfWords = (signal->theData[TupSizeAltReq::IND_PAGE] * 2048) + (ZWORDS_ON_PAGE - 1); - Uint64 noOfPages = noOfWords / (Uint64)ZWORDS_ON_PAGE; - cnoOfPage = (Uint32)noOfPages; - initPageRangeSize(signal->theData[TupSizeAltReq::IND_PAGE_RANGE]); - cnoOfTablerec = signal->theData[TupSizeAltReq::IND_TABLE]; - cnoOfTabDescrRec = signal->theData[TupSizeAltReq::IND_TABLE_DESC]; - Uint32 noOfStoredProc = signal->theData[TupSizeAltReq::IND_STORED_PROC]; + Uint32 tmp; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &tmp)); + Uint64 pages = (tmp * 2048 + (ZWORDS_ON_PAGE - 1))/ (Uint64)ZWORDS_ON_PAGE; + cnoOfPage = (Uint32)pages; + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE_RANGE, &tmp)); + initPageRangeSize(tmp); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_TABLE, &cnoOfTablerec)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_TABLE_DESC, + &cnoOfTabDescrRec)); + Uint32 noOfStoredProc; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_STORED_PROC, + &noOfStoredProc)); cnoOfTabDescrRec = (cnoOfTabDescrRec & 0xFFFFFFF0) + 16; c_storedProcPool.setSize(noOfStoredProc); @@ -639,7 +653,14 @@ void Dbtup::execSIZEALT_REP(Signal* signal) cnoOfLocalLogInfo = 0; cnoFreeUndoSeg = 0; - initialiseRecordsLab(signal, 0); + initialiseRecordsLab(signal, 0, ref, senderData); + + clblPagesPerTick = 50; + //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTick); + + clblPagesPerTickAfterSr = 50; + //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTickAfterSr); + }//Dbtup::execSIZEALT_REP() void Dbtup::initRecords() @@ -732,7 +753,8 @@ void Dbtup::initRecords() bat[2].bits.v = 5; }//Dbtup::initRecords() -void Dbtup::initialiseRecordsLab(Signal* signal, Uint32 switchData) +void Dbtup::initialiseRecordsLab(Signal* signal, Uint32 switchData, + Uint32 retRef, Uint32 retData) { switch (switchData) { case 0: @@ -794,19 +816,24 @@ void Dbtup::initialiseRecordsLab(Signal* signal, Uint32 switchData) case 14: ljam(); initializeRestartInfoRec(); - signal->theData[0] = cownref; - sendSignal(CMVMI_REF, GSN_SIZEALT_ACK, signal, 1, JBB); + + { + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = retData; + sendSignal(retRef, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); + } return; default: ndbrequire(false); break; }//switch -/******************************************************************************/ -/* SEND REAL-TIME BREAK DURING INITIALISATION OF VARIABLES IN SYSTEM RESTART */ -/******************************************************************************/ signal->theData[0] = ZINITIALISE_RECORDS; signal->theData[1] = switchData + 1; - sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB); + signal->theData[2] = retRef; + signal->theData[3] = retData; + sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB); return; }//Dbtup::initialiseRecordsLab() @@ -816,8 +843,6 @@ void Dbtup::execNDB_STTOR(Signal* signal) cndbcntrRef = signal->theData[0]; Uint32 ownNodeId = signal->theData[1]; Uint32 startPhase = signal->theData[2]; - Uint32 data1 = signal->theData[14]; - Uint32 data2 = signal->theData[15]; switch (startPhase) { case ZSTARTPHASE1: ljam(); @@ -829,7 +854,7 @@ void Dbtup::execNDB_STTOR(Signal* signal) break; case ZSTARTPHASE3: ljam(); - startphase3Lab(signal, data1, data2); + startphase3Lab(signal, ~0, ~0); break; case ZSTARTPHASE4: ljam(); @@ -856,20 +881,6 @@ void Dbtup::execNDB_STTOR(Signal* signal) void Dbtup::startphase3Lab(Signal* signal, Uint32 config1, Uint32 config2) { - if (config1 > 0) { - ljam(); - clblPagesPerTick = config1; - } else { - ljam(); - clblPagesPerTick = 1; - }//if - if (config2 > 0) { - ljam(); - clblPagesPerTickAfterSr = config2; - } else { - ljam(); - clblPagesPerTickAfterSr = 1; - }//if clblPageCounter = clblPagesPerTick; signal->theData[0] = ZLOAD_BAL_LCP_TIMER; sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 100, 1); @@ -955,9 +966,7 @@ void Dbtup::initializeHostBuffer() for (hostId = 0; hostId < MAX_NODES; hostId++) { hostBuffer[hostId].inPackedList = false; hostBuffer[hostId].noOfPacketsTA = 0; - hostBuffer[hostId].noOfPacketsRC = 0; hostBuffer[hostId].packetLenTA = 0; - hostBuffer[hostId].packetLenRC = 0; }//for }//Dbtup::initializeHostBuffer() @@ -1291,6 +1300,7 @@ void Dbtup::seizePendingFileOpenInfoRecord(PendingFileOpenInfoPtr& pfoiPtr) void Dbtup::execSET_VAR_REQ(Signal* signal) { +#if 0 SetVarReq* const setVarReq = (SetVarReq*)signal->getDataPtrSend(); ConfigParamId var = setVarReq->variable(); int val = setVarReq->value(); @@ -1310,7 +1320,7 @@ void Dbtup::execSET_VAR_REQ(Signal* signal) default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); } // switch - +#endif }//execSET_VAR_REQ() diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp index b73af5b0d76..e871fc86dea 100644 --- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp +++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp @@ -28,7 +28,6 @@ // signal classes #include <signaldata/DictTabInfo.hpp> #include <signaldata/TuxContinueB.hpp> -#include <signaldata/TuxSizeAltReq.hpp> #include <signaldata/BuildIndx.hpp> #include <signaldata/TupFrag.hpp> #include <signaldata/AlterIndx.hpp> @@ -620,7 +619,7 @@ private: */ void execCONTINUEB(Signal* signal); void execSTTOR(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); // utils void copyAttrs(Data dst, ConstData src, CopyPar& copyPar); diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp index 32d66422d5c..082b243bcb1 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp @@ -16,6 +16,8 @@ #define DBTUX_GEN_CPP #include "Dbtux.hpp" +#include <signaldata/TuxContinueB.hpp> +#include <signaldata/TuxContinueB.hpp> Dbtux::Dbtux(const Configuration& conf) : SimulatedBlock(DBTUX, conf), @@ -42,7 +44,7 @@ Dbtux::Dbtux(const Configuration& conf) : */ addRecSignal(GSN_CONTINUEB, &Dbtux::execCONTINUEB); addRecSignal(GSN_STTOR, &Dbtux::execSTTOR); - addRecSignal(GSN_SIZEALT_REP, &Dbtux::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbtux::execREAD_CONFIG_REQ, true); /* * DbtuxMeta.cpp */ @@ -143,18 +145,32 @@ Dbtux::execSTTOR(Signal* signal) } void -Dbtux::execSIZEALT_REP(Signal* signal) +Dbtux::execREAD_CONFIG_REQ(Signal* signal) { jamEntry(); - const Uint32* data = signal->getDataPtr(); - BlockReference sender = data[TuxSizeAltReq::IND_BLOCK_REF]; - const Uint32 nIndex = data[TuxSizeAltReq::IND_INDEX]; - const Uint32 nFragment = data[TuxSizeAltReq::IND_FRAGMENT]; - const Uint32 nAttribute = data[TuxSizeAltReq::IND_ATTRIBUTE]; + + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + + Uint32 nIndex; + Uint32 nFragment; + Uint32 nAttribute; + Uint32 nScanOp; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_INDEX, &nIndex)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_FRAGMENT, &nFragment)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_ATTRIBUTE, &nAttribute)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_SCAN_OP, &nScanOp)); + const Uint32 nDescPage = (nIndex + nAttribute + DescPageSize - 1) / DescPageSize; - const Uint32 nScanOp = data[TuxSizeAltReq::IND_SCAN]; const Uint32 nScanBoundWords = nScanOp * ScanBoundSegmentSize * 4; - // allocate records + c_indexPool.setSize(nIndex); c_fragPool.setSize(nFragment); c_descPagePool.setSize(nDescPage); @@ -179,7 +195,11 @@ Dbtux::execSIZEALT_REP(Signal* signal) // allocate buffers c_keyBuffer = (Uint32*)allocRecord("c_keyBuffer", sizeof(Uint64), (MaxAttrDataSize + 1) >> 1); // ack - sendSignal(sender, GSN_SIZEALT_ACK, signal, 1, JBB); + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = senderData; + sendSignal(ref, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); } // utils diff --git a/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp b/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp index a481573e370..639d300d6df 100644 --- a/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp +++ b/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp @@ -21,10 +21,13 @@ #include <pc.hpp> #include <SimulatedBlock.hpp> #include <ndb_limits.h> -#include <signaldata/CmvmiCfgConf.hpp> #include <signaldata/StopReq.hpp> #include <signaldata/ResumeReq.hpp> #include <signaldata/DictTabInfo.hpp> +#include <signaldata/CntrStart.hpp> +#include <signaldata/CheckNodeGroups.hpp> + +#include <signaldata/UpgradeStartup.hpp> #include <NodeState.hpp> #include <NdbTick.h> @@ -39,70 +42,13 @@ ----------------- */ #define ZNO_NDB_BLOCKS 6 /* ACC, DICT, DIH, LQH, TC, TUP */ -#define ZDELAY_NODERESTART 5 /* MASTER REFUSED NODERESTART, WAIT SEC */ -#define ZDELAY_START 25 /* WAIT SECONDS FOR OTHER NODES, RESTART*/ -#define ZHB_INTERVAL 10 /* HEART BEAT INTERVAL TIME MS */ -#define ZNO_NDB_NODES 1 -#define ZHB_TYPE 1 - -//------- ERROR CODES ----------------------------------------- -#define ZERROR_ALREADY_EXISTS 901 -#define ZERROR_DOESNT_EXIST 902 -#define ZERROR_VALUE_OUT_OF_RANGE 903 -#define ZERROR_NOT_STARTED 904 -#define ZERROR_NODE_RESTART 905 -#define ZERROR_NO_RESTART_NODES 906 -#define ZERROR_STARTPHASE_VALUE 907 -#define ZERROR_CNTR_MASTERREQ 908 -#define ZERROR_CNTR_MASTERREF 909 -#define ZERROR_CNTR_MASTERCONF 910 -#define ZERROR_NOT_RUNNING 911 -#define ZERROR_CNTR_WAITREP 912 + #define ZNOT_AVAILABLE 913 -#define ZERROR_DISK_FAILURE 914 -#define ZERROR_TOO_MANY_NODES 915 -#define ZERROR_TYPEOFSTART 916 -#define ZERROR_CTYPE_OF_START 917 -#define ZERROR_ZSTART 918 -#define ZERROR_AT_SELECT_START 919 -#define ZERROR_CNTR_CHANGEREP 920 -#define ZERR_DETECT_NODERESTART_1 921 -#define ZERR_DETECT_NODERESTART_2 922 -#define ZERROR_CONTINUEB 923 -#define ZERR_APPL_REGREF 924 -#define ZERR_DICTADDATTRREF 925 -#define ZERR_DICTPREPAREREF 926 -#define ZERR_DICTRELEASEREF 927 -#define ZERR_DICTTABREF 928 -#define ZERR_DICTSEIZEREF 929 -#define ZERR_NDB_STARTREF 930 -#define ZERR_NODE_STATESREF 931 -#define ZERR_READ_NODESREF 932 -#define ZERR_TCKEYREF 933 -#define ZERR_TCRELEASEREF 934 -#define ZERR_TCSEIZEREF 935 -#define ZNOTVALIDSTATE_1 936 -#define ZNOTVALIDSTATE_2 937 -#define ZNODE_FAILURE_DURING_RESTART 938 -#define ZSTART_IN_PROGRESS_ERROR 939 -#define ZCOULD_NOT_OCCUR_ERROR 940 -#define ZTOO_MANY_NODES_ERROR 941 -#define ZNODE_RESTART_ONGOING_ERROR 942 -#define ZWE_ARE_DECLARED_DEAD_ERROR 943 -#define ZTIME_OUT_ERROR 944 -#define ZTYPE_OF_START_ERROR 945 -#define ZMASTER_CONFLICT_ERROR 946 -#define ZNODE_CONFLICT_ERROR 947 //------- OTHERS --------------------------------------------- -#define ZCONTINUEB_1 1 -#define ZCONTINUEB_2 2 -#define ZSHUTDOWN 3 - -#define ZAPPL_SUBTYPE 0 -#define ZNAME_OF_APPL "NDB" -#define ZVOTING 2 -#define ZSIZE_CFG_BLOCK_REC 8 +#define ZSTARTUP 1 +#define ZSHUTDOWN 2 + #define ZSIZE_NDB_BLOCKS_REC 16 /* MAX BLOCKS IN NDB */ #define ZSIZE_SYSTAB 2048 #define ZSTART_PHASE_1 1 @@ -124,28 +70,10 @@ #define ZWAITPOINT_7_1 7 #define ZWAITPOINT_7_2 8 #define ZSYSTAB_VERSION 1 -/* -------- SIGNAL CONSTANTS ----------------------------------- -*/ -#define ZNOT_MASTER 0 -/* REASON OF CNTR_MASTERREF */ -#define ZTOO_FEW_NODES 1 -#define ZNEW_MASTER 0 -#define ZDELETE_NODE 1 -#define ZSYSTAB_EXIST 3 -#define ZVOTE_NEW_NODE 4 -#define ZVARIABLE_NO 1 -#define ZAMOUNT_PAGES 8 #endif class Ndbcntr: public SimulatedBlock { public: - // State values - enum State { - NOT_ACTIVE = 0, - ACTIVE = 1 - }; - // Records /* FSREADREQ FSWRITEREQ */ @@ -154,59 +82,27 @@ public: * ------------------------------------------------------------ */ -/** - * CFG_BLOCK_REC CONTAINS ALL CONFIG DATA SENT IN EACH NDB_STTOR - * SOME OTHER CONFIG DATA IS STORED IN RECORD 0 - * - * WHEN CFG_BLOCK_PTR = ZSTART_PHASE_X ( CINTERNAL_STARTPHASE ) - * WORD 0 DICT_1 - * WORD 1 DICT_2 - * WORD 2 DIH_1 - * WORD 3 DIH_2 - * WORD 4 LQH_1 - * WORD 5 LQH_2 - * WORD 6 TC_1 - * WORD 7 TC_2 - * WORD 8 TUP_1 - * WORD 9 TUP_2 - * WORD 10 ACC_1 - * WORD 11 ACC_2 - * - * CFG_BLOCK_PTR = 0 - * WORD 0 CDELAY_START - * WORD 1 CDELAY_NODERESTART - *------------------------------------------------------------------------*/ - struct CfgBlockRec { - UintR cfgData[CmvmiCfgConf::NO_OF_WORDS]; - }; /* p2c: size = 64 bytes */ + struct StartRecord { + Uint64 m_startTime; + + void reset(); + NdbNodeBitmask m_starting; + NdbNodeBitmask m_waiting; // == (m_withLog | m_withoutLog) + NdbNodeBitmask m_withLog; + NdbNodeBitmask m_withoutLog; + Uint32 m_lastGci; + Uint32 m_lastGciNodeId; + + Uint64 m_startPartialTimeout; + Uint64 m_startPartitionedTimeout; + Uint64 m_startFailureTimeout; + struct { + Uint32 m_nodeId; + Uint32 m_lastGci; + } m_logNodes[MAX_NDB_NODES]; + Uint32 m_logNodesCount; + } c_start; - typedef Ptr<CfgBlockRec> CfgBlockRecPtr; - -/*------------------------------------------------------------------------*/ -// CONTAIN INFO ABOUT ALL NODES IN CLUSTER. NODE_PTR ARE USED AS NODE NUMBER. -// IF THE STATE ARE ZDELETE THEN THE NODE DOESN'T EXIST. NODES ARE ALLOWED -// TO REGISTER (ZADD) DURING RESTART. -// WHEN THE SYSTEM IS RUNNING THE MASTER WILL CHECK IF ANY NODE HAS MADE A -// CNTR_MASTERREQ AND TAKE CARE OF THE -// REQUEST. TO CONFIRM THE REQ, THE MASTER DEMANDS THAT ALL RUNNING NODES HAS -// VOTED FOR THE NEW NODE. -// NODE_PTR:MASTER_REQ IS USED DURING RESTART TO LOG POSTPONED -// CNTR_MASTERREQ'S -/*------------------------------------------------------------------------*/ - struct NodeRec { - UintR dynamicId; - BlockReference cntrBlockref; - Uint16 masterReq; - Uint16 state; - Uint16 ndbVersion; - Uint16 subType; - Uint8 votes; - Uint8 voter; - UintR nodeDefined; - }; /* p2c: size = 16 bytes */ - - typedef Ptr<NodeRec> NodeRecPtr; - struct NdbBlocksRec { BlockReference blockref; }; /* p2c: size = 2 bytes */ @@ -266,16 +162,14 @@ private: void execCONTINUEB(Signal* signal); void execREAD_NODESCONF(Signal* signal); void execREAD_NODESREF(Signal* signal); - void execCNTR_MASTERREQ(Signal* signal); - void execCNTR_MASTERCONF(Signal* signal); - void execCNTR_MASTERREF(Signal* signal); + void execCM_ADD_REP(Signal* signal); + void execCNTR_START_REQ(Signal* signal); + void execCNTR_START_REF(Signal* signal); + void execCNTR_START_CONF(Signal* signal); + void execCNTR_START_REP(Signal* signal); void execCNTR_WAITREP(Signal* signal); - void execNODE_STATESREQ(Signal* signal); - void execNODE_STATESCONF(Signal* signal); - void execNODE_STATESREF(Signal* signal); void execNODE_FAILREP(Signal* signal); void execSYSTEM_ERROR(Signal* signal); - void execVOTE_MASTERORD(Signal* signal); // Received signals void execDUMP_STATE_ORD(Signal* signal); @@ -295,12 +189,7 @@ private: void execNDB_STTORRY(Signal* signal); void execNDB_STARTCONF(Signal* signal); void execREAD_NODESREQ(Signal* signal); - void execAPPL_REGCONF(Signal* signal); - void execAPPL_REGREF(Signal* signal); - void execAPPL_CHANGEREP(Signal* signal); - void execAPPL_STARTCONF(Signal* signal); void execNDB_STARTREF(Signal* signal); - void execCMVMI_CFGCONF(Signal* signal); void execSET_VAR_REQ(Signal* signal); void execSTOP_PERM_REF(Signal* signal); @@ -323,19 +212,17 @@ private: // Statement blocks void sendCreateTabReq(Signal* signal, const char* buffer, Uint32 bufLen); void startInsertTransactions(Signal* signal); - UintR checkNodelist(Signal* signal, Uint16 TnoRestartNodes); - void chooseRestartNodes(Signal* signal); - void copyCfgVariables(Signal* signal); - void deleteNode(Signal* signal); - void detectNoderestart(Signal* signal); - void getStartNodes(Signal* signal); void initData(Signal* signal); - void replyMasterconfToAll(Signal* signal); void resetStartVariables(Signal* signal); - void sendCntrMasterreq(Signal* signal); + void sendCntrStartReq(Signal* signal); + void sendCntrStartRef(Signal*, Uint32 nodeId, CntrStartRef::ErrorCode); void sendNdbSttor(Signal* signal); void sendSttorry(Signal* signal); + bool trySystemRestart(Signal* signal); + void startWaitingNodes(Signal* signal); + CheckNodeGroups::Output checkNodeGroups(Signal*, const NdbNodeBitmask &); + // Generated statement blocks void systemErrorLab(Signal* signal); @@ -367,13 +254,6 @@ private: void ph7ALab(Signal* signal); void ph8ALab(Signal* signal); - void masterreq010Lab(Signal* signal, - Uint16 TnoRestartNodes, - Uint16 TuserNodeId); - void masterreq020Lab(Signal* signal); - void masterreq030Lab(Signal* signal, - Uint16 TnoRestartNodes, - Uint16 TuserNodeId); void waitpoint41Lab(Signal* signal); void waitpoint51Lab(Signal* signal); @@ -401,62 +281,40 @@ private: * NODE_PTR:MASTER_REQ IS USED DURING RESTART TO LOG * POSTPONED CNTR_MASTERREQ'S *------------------------------------------------------------------------*/ - CfgBlockRec *cfgBlockRec; - NodeRec *nodeRec; NdbBlocksRec *ndbBlocksRec; - NodeRecPtr nodePtr; -/* -2.4 COMMON STORED VARIABLES -*/ - Uint16 cstartNodes[MAX_NDB_NODES]; - BlockReference ccmvmiBlockref; - BlockReference cqmgrBlockref; - BlockReference cdictBlockref; - BlockReference cdihBlockref; - BlockReference clqhBlockref; - BlockReference cownBlockref; - BlockReference ctcBlockref; - UintR cnoNdbNodes; - UintR capplStartconfFlag; + + /* + 2.4 COMMON STORED VARIABLES + */ UintR cgciSystab; UintR ckey; - UintR cnoRegNodes; - UintR cnoRunNodes; - UintR cnoNeedNodes; - UintR cnoWaitrep; + //UintR csystabId; UintR cnoWaitrep6; UintR cnoWaitrep7; - //UintR csystabId; UintR ctcConnectionP; UintR ctcReqInfo; - UintR clastGci; - UintR cmasterLastGci; - UintR cmasterCurrentId; - Uint16 cmasterDihId; + Uint8 ctransidPhase; Uint16 cresponses; - Uint16 cdelayStart; + Uint8 cstartPhase; Uint16 cinternalStartphase; + Uint16 cmasterNodeId; - Uint16 cmasterCandidateId; Uint16 cndbBlocksCount; Uint16 cnoStartNodes; - Uint16 cnoVoters; - Uint16 cstartProgressFlag; - Uint16 cqmgrConnectionP; - Uint16 csignalKey; + UintR cnoWaitrep; NodeState::StartType ctypeOfStart; - Uint16 cmasterVoters; Uint16 cdynamicNodeId; - Uint8 cwaitContinuebFlag; - Uint8 cstartPhase; - Uint8 ctransidPhase; Uint32 c_fsRemoveCount; Uint32 c_nodeGroup; void clearFilesystem(Signal* signal); void execFSREMOVEREF(Signal* signal); void execFSREMOVECONF(Signal* signal); + + NdbNodeBitmask c_allDefinedNodes; + NdbNodeBitmask c_clusterNodes; // All members of qmgr cluster + NdbNodeBitmask c_startedNodes; // All cntr started nodes public: struct StopRecord { @@ -495,6 +353,8 @@ private: void execSTART_ORD(Signal* signal); void execSTTORRY(Signal* signal); void sendNextSTTOR(Signal* signal); + void execREAD_CONFIG_CONF(Signal* signal); + void sendNextREAD_CONFIG_REQ(Signal* signal); BlockNumber number() const { return cntr.number(); } void progError(int line, int cause, const char * extra) { @@ -508,6 +368,9 @@ private: void execSTTORRY(Signal* signal); void execSTART_ORD(Signal* signal); + void execREAD_CONFIG_CONF(Signal*); + + friend struct UpgradeStartup; }; #endif diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp index 9af6359876b..1069cf93b06 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp @@ -27,8 +27,6 @@ void Ndbcntr::initData() { // Records with constant sizes - cfgBlockRec = new CfgBlockRec[ZSIZE_CFG_BLOCK_REC]; - nodeRec = new NodeRec[MAX_NDB_NODES]; ndbBlocksRec = new NdbBlocksRec[ZSIZE_NDB_BLOCKS_REC]; }//Ndbcntr::initData() @@ -51,17 +49,15 @@ Ndbcntr::Ndbcntr(const class Configuration & conf): addRecSignal(GSN_CONTINUEB, &Ndbcntr::execCONTINUEB); addRecSignal(GSN_READ_NODESCONF, &Ndbcntr::execREAD_NODESCONF); addRecSignal(GSN_READ_NODESREF, &Ndbcntr::execREAD_NODESREF); - addRecSignal(GSN_CNTR_MASTERREQ, &Ndbcntr::execCNTR_MASTERREQ); - addRecSignal(GSN_CNTR_MASTERCONF, &Ndbcntr::execCNTR_MASTERCONF); - addRecSignal(GSN_CNTR_MASTERREF, &Ndbcntr::execCNTR_MASTERREF); + addRecSignal(GSN_CM_ADD_REP, &Ndbcntr::execCM_ADD_REP); + addRecSignal(GSN_CNTR_START_REQ, &Ndbcntr::execCNTR_START_REQ); + addRecSignal(GSN_CNTR_START_REF, &Ndbcntr::execCNTR_START_REF); + addRecSignal(GSN_CNTR_START_CONF, &Ndbcntr::execCNTR_START_CONF); addRecSignal(GSN_CNTR_WAITREP, &Ndbcntr::execCNTR_WAITREP); - addRecSignal(GSN_NODE_STATESREQ, &Ndbcntr::execNODE_STATESREQ); - addRecSignal(GSN_NODE_STATESCONF, &Ndbcntr::execNODE_STATESCONF); - addRecSignal(GSN_NODE_STATESREF, &Ndbcntr::execNODE_STATESREF); + addRecSignal(GSN_CNTR_START_REP, &Ndbcntr::execCNTR_START_REP); addRecSignal(GSN_NODE_FAILREP, &Ndbcntr::execNODE_FAILREP); addRecSignal(GSN_SYSTEM_ERROR , &Ndbcntr::execSYSTEM_ERROR); - addRecSignal(GSN_VOTE_MASTERORD, &Ndbcntr::execVOTE_MASTERORD); - + // Received signals addRecSignal(GSN_DUMP_STATE_ORD, &Ndbcntr::execDUMP_STATE_ORD); addRecSignal(GSN_STTOR, &Ndbcntr::execSTTOR); @@ -80,12 +76,7 @@ Ndbcntr::Ndbcntr(const class Configuration & conf): addRecSignal(GSN_NDB_STTORRY, &Ndbcntr::execNDB_STTORRY); addRecSignal(GSN_NDB_STARTCONF, &Ndbcntr::execNDB_STARTCONF); addRecSignal(GSN_READ_NODESREQ, &Ndbcntr::execREAD_NODESREQ); - addRecSignal(GSN_APPL_REGCONF, &Ndbcntr::execAPPL_REGCONF); - addRecSignal(GSN_APPL_REGREF, &Ndbcntr::execAPPL_REGREF); - addRecSignal(GSN_APPL_CHANGEREP, &Ndbcntr::execAPPL_CHANGEREP); - addRecSignal(GSN_APPL_STARTCONF, &Ndbcntr::execAPPL_STARTCONF); addRecSignal(GSN_NDB_STARTREF, &Ndbcntr::execNDB_STARTREF); - addRecSignal(GSN_CMVMI_CFGCONF, &Ndbcntr::execCMVMI_CFGCONF); addRecSignal(GSN_SET_VAR_REQ, &Ndbcntr::execSET_VAR_REQ); addRecSignal(GSN_STOP_PERM_REF, &Ndbcntr::execSTOP_PERM_REF); @@ -107,18 +98,18 @@ Ndbcntr::Ndbcntr(const class Configuration & conf): addRecSignal(GSN_START_ORD, &Ndbcntr::execSTART_ORD); addRecSignal(GSN_STTORRY, &Ndbcntr::execSTTORRY); + addRecSignal(GSN_READ_CONFIG_CONF, &Ndbcntr::execREAD_CONFIG_CONF); addRecSignal(GSN_FSREMOVEREF, &Ndbcntr::execFSREMOVEREF); addRecSignal(GSN_FSREMOVECONF, &Ndbcntr::execFSREMOVECONF); initData(); ctypeOfStart = NodeState::ST_ILLEGAL_TYPE; + c_start.m_startTime = NdbTick_CurrentMillisecond(); }//Ndbcntr::Ndbcntr() Ndbcntr::~Ndbcntr() { - delete []cfgBlockRec; - delete []nodeRec; delete []ndbBlocksRec; }//Ndbcntr::~Ndbcntr() diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index 4211645ace6..5965673f25f 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -23,13 +23,10 @@ #include <signaldata/DictTabInfo.hpp> #include <signaldata/CreateTable.hpp> #include <signaldata/ReadNodesConf.hpp> -#include <signaldata/CntrMasterReq.hpp> -#include <signaldata/CntrMasterConf.hpp> #include <signaldata/NodeFailRep.hpp> #include <signaldata/TcKeyReq.hpp> #include <signaldata/TcKeyConf.hpp> #include <signaldata/EventReport.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/NodeStateSignalData.hpp> #include <signaldata/StopPerm.hpp> #include <signaldata/StopMe.hpp> @@ -39,9 +36,11 @@ #include <signaldata/AbortAll.hpp> #include <signaldata/SystemError.hpp> #include <signaldata/NdbSttor.hpp> +#include <signaldata/CntrStart.hpp> #include <signaldata/DumpStateOrd.hpp> #include <signaldata/FsRemoveReq.hpp> +#include <signaldata/ReadConfig.hpp> #include <AttributeHeader.hpp> #include <Configuration.hpp> @@ -50,8 +49,6 @@ #include <NdbOut.hpp> #include <NdbTick.h> -#define ZSYSTEM_RUN 256 - /** * ALL_BLOCKS Used during start phases and while changing node state * @@ -60,25 +57,27 @@ struct BlockInfo { BlockReference Ref; // BlockReference Uint32 NextSP; // Next start phase + Uint32 ErrorInsertStart; + Uint32 ErrorInsertStop; }; static BlockInfo ALL_BLOCKS[] = { - { DBTC_REF, 1 }, - { DBDIH_REF, 1 }, - { DBLQH_REF, 1 }, - { DBACC_REF, 1 }, - { DBTUP_REF, 1 }, - { DBDICT_REF, 1 }, - { NDBFS_REF, 0 }, - { NDBCNTR_REF, 0 }, - { QMGR_REF, 1 }, - { CMVMI_REF, 1 }, + { DBTC_REF, 1 , 8000, 8035 }, + { DBDIH_REF, 1 , 7000, 7173 }, + { DBLQH_REF, 1 , 5000, 5030 }, + { DBACC_REF, 1 , 3000, 3999 }, + { DBTUP_REF, 1 , 4000, 4007 }, + { DBDICT_REF, 1 , 6000, 6003 }, + { NDBFS_REF, 0 , 2000, 2999 }, + { NDBCNTR_REF, 0 , 1000, 1999 }, + { QMGR_REF, 1 , 1, 999 }, + { CMVMI_REF, 1 , 9000, 9999 }, { TRIX_REF, 1 }, - { BACKUP_REF, 1 }, - { DBUTIL_REF, 1 }, - { SUMA_REF, 1 }, + { BACKUP_REF, 1 , 10000, 10999 }, + { DBUTIL_REF, 1 , 11000, 11999 }, + { SUMA_REF, 1 , 13000, 13999 }, { GREP_REF, 1 }, - { DBTUX_REF, 1 } + { DBTUX_REF, 1 , 12000, 12999 } }; static const Uint32 ALL_BLOCKS_SZ = sizeof(ALL_BLOCKS)/sizeof(BlockInfo); @@ -91,33 +90,27 @@ void Ndbcntr::execCONTINUEB(Signal* signal) jamEntry(); UintR Ttemp1 = signal->theData[0]; switch (Ttemp1) { - case ZCONTINUEB_1: - jam(); - if (cwaitContinuebFlag == ZFALSE) { - jam(); -/*******************************/ -/* SIGNAL NOT WANTED ANYMORE */ -/*******************************/ - return; - } else { + case ZSTARTUP:{ + if(getNodeState().startLevel == NodeState::SL_STARTED){ jam(); -/*******************************/ -/* START ALREADY IN PROGRESS */ -/*******************************/ - if (cstartProgressFlag == ZVOTING) { - jam(); - systemErrorLab(signal); - return; - }//if - if (ctypeOfStart == NodeState::ST_NODE_RESTART) { - jam(); - systemErrorLab(signal); - return; - }//if - ph2ELab(signal); return; - }//if + } + + if(cmasterNodeId == getOwnNodeId() && c_start.m_starting.isclear()){ + jam(); + trySystemRestart(signal); + // Fall-through + } + + Uint64 now = NdbTick_CurrentMillisecond(); + if(c_start.m_startFailureTimeout > now){ + ndbrequire(false); + } + + signal->theData[0] = ZSTARTUP; + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 1); break; + } case ZSHUTDOWN: jam(); c_stopRec.checkTimeout(signal); @@ -189,28 +182,18 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* signal) return; }//Ndbcntr::execSYSTEM_ERROR() -/*---------------------------------------------------------------------------*/ -/* The STTOR signal is on level C, we use CONTINUEB to get into level B */ -/*---------------------------------------------------------------------------*/ -/**************************** >----------------------------------------------*/ -/* STTOR > SENDER : MISSRA */ -/**************************** >------------------+ RECEIVER : NDBCNTR */ - /* INPUT : CSTART_PHASE */ - /* CSIGNAL_KEY */ - /*---------------------------*/ -/*******************************/ -/* STTOR */ -/*******************************/ void Ndbcntr::execSTTOR(Signal* signal) { jamEntry(); cstartPhase = signal->theData[1]; - csignalKey = signal->theData[6]; NodeState newState(NodeState::SL_STARTING, cstartPhase, (NodeState::StartType)ctypeOfStart); updateNodeState(signal, newState); + cndbBlocksCount = 0; + cinternalStartphase = cstartPhase - 1; + switch (cstartPhase) { case 0: if(theConfiguration.getInitialStart()){ @@ -244,6 +227,7 @@ void Ndbcntr::execSTTOR(Signal* signal) case 6: jam(); getNodeGroup(signal); + // Fall through break; case ZSTART_PHASE_8: jam(); @@ -327,80 +311,37 @@ void Ndbcntr::execNDB_STTORRY(Signal* signal) }//switch }//Ndbcntr::execNDB_STTORRY() -/* -4.2 START PHASE 1 */ -/*###########################################################################*/ -/*LOAD OUR BLOCK REFERENCE AND OUR NODE ID. LOAD NODE IDS OF ALL NODES IN */ -/* CLUSTER CALCULATE BLOCK REFERENCES OF ALL BLOCKS IN THIS NODE */ -/*---------------------------------------------------------------------------*/ -/*******************************/ -/* STTOR */ -/*******************************/ void Ndbcntr::startPhase1Lab(Signal* signal) { jamEntry(); initData(signal); - cownBlockref = calcNdbCntrBlockRef(0); - cnoRunNodes = 0; - cnoRegNodes = 0; - - NdbBlocksRecPtr ndbBlocksPtr; cdynamicNodeId = 0; - cownBlockref = calcNdbCntrBlockRef(getOwnNodeId()); - cqmgrBlockref = calcQmgrBlockRef(getOwnNodeId()); - cdictBlockref = calcDictBlockRef(getOwnNodeId()); - cdihBlockref = calcDihBlockRef(getOwnNodeId()); - clqhBlockref = calcLqhBlockRef(getOwnNodeId()); - ctcBlockref = calcTcBlockRef(getOwnNodeId()); - ccmvmiBlockref = numberToRef(CMVMI, getOwnNodeId()); + NdbBlocksRecPtr ndbBlocksPtr; ndbBlocksPtr.i = 0; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = clqhBlockref; + ndbBlocksPtr.p->blockref = DBLQH_REF; ndbBlocksPtr.i = 1; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = cdictBlockref; + ndbBlocksPtr.p->blockref = DBDICT_REF; ndbBlocksPtr.i = 2; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = calcTupBlockRef(getOwnNodeId()); + ndbBlocksPtr.p->blockref = DBTUP_REF; ndbBlocksPtr.i = 3; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = calcAccBlockRef(getOwnNodeId()); + ndbBlocksPtr.p->blockref = DBACC_REF; ndbBlocksPtr.i = 4; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = ctcBlockref; + ndbBlocksPtr.p->blockref = DBTC_REF; ndbBlocksPtr.i = 5; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = cdihBlockref; + ndbBlocksPtr.p->blockref = DBDIH_REF; sendSttorry(signal); return; } -/* -4.3 START PHASE 2 */ -/*###########################################################################*/ -// SEND A REGISTATION REQUEST TO QMGR AND WAIT FOR REPLY APPL_REGCONF OR -// APPL_REGREF COLLECT ALL OTHER NDB NODES -// AND THEIR STATES FIND OUT WHAT KIND OF START THIS NODE ARE GOING TO PERFORM -// IF THIS IS A SYSTEM OR INITIAL -// RESTART THEN FIND OUT WHO IS THE MASTER IF THIS NODE BECOME THE CNTR MASTER -// THEN COLLECT CNTR_MASTERREQ FROM -// ALL OTHER REGISTRATED CNTR THE MASTER WILL SEND BACK A CNTR_MASTERCONF WITH -// FINAL DECISSION ABOUT WHAT TYPE -// OF START AND WHICH NODES ARE APPROVED TO PARTICIPATE IN THE START IF THE -// RECEIVER OF CNTR_MASTERREQ HAVE A -// BETTER CHOICE OF MASTER THEN SEND CNTR_MASTERREF. NEW NODES ARE ALWAYS -// ALLOWED TO REGISTER, EVEN DURING -// RESTART BUT THEY WILL BE IGNORED UNTIL THE START HAVE FINISHED. -// SEND SIGNAL NDBSTTOR TO ALL BLOCKS, ACC, DICT, DIH, LQH, TC AND TUP -// SEND SIGNAL APPL_REGREQ TO QMGR IN THIS NODE AND WAIT FOR REPLY -// APPL_REGCONF OR APPL_REGREF */ -/*--------------------------------------------------------------------------*/ -/*******************************/ -/* READ_NODESREF */ -/*******************************/ void Ndbcntr::execREAD_NODESREF(Signal* signal) { jamEntry(); @@ -408,25 +349,6 @@ void Ndbcntr::execREAD_NODESREF(Signal* signal) return; }//Ndbcntr::execREAD_NODESREF() -/*******************************/ -/* APPL_REGREF */ -/*******************************/ -void Ndbcntr::execAPPL_REGREF(Signal* signal) -{ - jamEntry(); - systemErrorLab(signal); - return; -}//Ndbcntr::execAPPL_REGREF() - -/*******************************/ -/* CNTR_MASTERREF */ -/*******************************/ -void Ndbcntr::execCNTR_MASTERREF(Signal* signal) -{ - jamEntry(); - systemErrorLab(signal); - return; -}//Ndbcntr::execCNTR_MASTERREF() /*******************************/ /* NDB_STARTREF */ @@ -443,17 +365,11 @@ void Ndbcntr::execNDB_STARTREF(Signal* signal) /*******************************/ void Ndbcntr::startPhase2Lab(Signal* signal) { - cinternalStartphase = cstartPhase - 1; -/*--------------------------------------*/ -/* CASE: CSTART_PHASE = ZSTART_PHASE_2 */ -/*--------------------------------------*/ - cndbBlocksCount = 0; - cwaitContinuebFlag = ZFALSE; -/* NOT WAITING FOR SIGNAL CONTINUEB */ - - clastGci = 0; - signal->theData[0] = cownBlockref; - sendSignal(cdihBlockref, GSN_DIH_RESTARTREQ, signal, 1, JBB); + c_start.m_lastGci = 0; + c_start.m_lastGciNodeId = getOwnNodeId(); + + signal->theData[0] = reference(); + sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal, 1, JBB); return; }//Ndbcntr::startPhase2Lab() @@ -463,8 +379,8 @@ void Ndbcntr::startPhase2Lab(Signal* signal) void Ndbcntr::execDIH_RESTARTCONF(Signal* signal) { jamEntry(); - cmasterDihId = signal->theData[0]; - clastGci = signal->theData[1]; + //cmasterDihId = signal->theData[0]; + c_start.m_lastGci = signal->theData[1]; ctypeOfStart = NodeState::ST_SYSTEM_RESTART; ph2ALab(signal); return; @@ -488,370 +404,449 @@ void Ndbcntr::ph2ALab(Signal* signal) /* from QMGR */ /* READ_NODESREQ */ /******************************/ - signal->theData[0] = cownBlockref; - sendSignal(cqmgrBlockref, GSN_READ_NODESREQ, signal, 1, JBB); + signal->theData[0] = reference(); + sendSignal(QMGR_REF, GSN_READ_NODESREQ, signal, 1, JBB); return; }//Ndbcntr::ph2ALab() +inline +Uint64 +setTimeout(Uint64 time, Uint32 timeoutValue){ + if(timeoutValue == 0) + return ~0; + return time + timeoutValue; +} + /*******************************/ /* READ_NODESCONF */ /*******************************/ void Ndbcntr::execREAD_NODESCONF(Signal* signal) { jamEntry(); - ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0]; + const ReadNodesConf * readNodes = (ReadNodesConf *)&signal->theData[0]; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if(NodeBitmask::get(readNodes->allNodes, nodePtr.i)){ - jam(); - nodePtr.p->nodeDefined = ZTRUE; - } else { - jam(); - nodePtr.p->nodeDefined = ZFALSE; - }//if - }//for + cmasterNodeId = readNodes->masterNodeId; + cdynamicNodeId = readNodes->ndynamicId; + + /** + * All defined nodes... + */ + c_allDefinedNodes.assign(NdbNodeBitmask::Size, readNodes->allNodes); + c_clusterNodes.assign(NdbNodeBitmask::Size, readNodes->clusterNodes); - CfgBlockRecPtr cfgBlockPtr; + Uint32 to_1 = 30000; + Uint32 to_2 = 0; + Uint32 to_3 = 0; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + + ndbrequire(p != 0); + ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTIAL_TIMEOUT, &to_1); + ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTITION_TIMEOUT, &to_2); + ndb_mgm_get_int_parameter(p, CFG_DB_START_FAILURE_TIMEOUT, &to_3); + + c_start.m_startPartialTimeout = setTimeout(c_start.m_startTime, to_1); + c_start.m_startPartitionedTimeout = setTimeout(c_start.m_startTime, to_2); + c_start.m_startFailureTimeout = setTimeout(c_start.m_startTime, to_3); + + if(getNodeInfo(cmasterNodeId).m_version < MAKE_VERSION(3,5,0)){ + /** + * Old NDB running + */ + UpgradeStartup::sendCmAppChg(* this, signal, 0); // ADD + return; + } + + sendCntrStartReq(signal); - cfgBlockPtr.i = 0; - ptrAss(cfgBlockPtr, cfgBlockRec); - signal->theData[0] = cownBlockref; - signal->theData[1] = cfgBlockPtr.i; - sendSignal(ccmvmiBlockref, GSN_CMVMI_CFGREQ, signal, 2, JBB); return; } -/*******************************/ -/* CMVMI_CFGCONF */ -/*******************************/ -void Ndbcntr::execCMVMI_CFGCONF(Signal* signal) -{ - CfgBlockRecPtr cfgBlockPtr; +void +Ndbcntr::execCM_ADD_REP(Signal* signal){ + jamEntry(); + c_clusterNodes.set(signal->theData[0]); +} + +void +Ndbcntr::sendCntrStartReq(Signal * signal){ jamEntry(); - CmvmiCfgConf * const cfgConf = (CmvmiCfgConf *)&signal->theData[0]; + CntrStartReq * req = (CntrStartReq*)signal->getDataPtrSend(); + req->startType = ctypeOfStart; + req->lastGci = c_start.m_lastGci; + req->nodeId = getOwnNodeId(); + sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_START_REQ, + signal, CntrStartReq::SignalLength, JBB); +} - cfgBlockPtr.i = cfgConf->startPhase; - ptrCheckGuard(cfgBlockPtr, ZSIZE_CFG_BLOCK_REC, cfgBlockRec); - for(unsigned int i = 0; i<CmvmiCfgConf::NO_OF_WORDS; i++) - cfgBlockPtr.p->cfgData[i] = cfgConf->theData[i]; +void +Ndbcntr::execCNTR_START_REF(Signal * signal){ + jamEntry(); + const CntrStartRef * ref = (CntrStartRef*)signal->getDataPtr(); - if (cfgBlockPtr.i < 4) { + switch(ref->errorCode){ + case CntrStartRef::NotMaster: jam(); - cfgBlockPtr.i = cfgBlockPtr.i + 1; - signal->theData[0] = cownBlockref; - signal->theData[1] = cfgBlockPtr.i; - sendSignal(ccmvmiBlockref, GSN_CMVMI_CFGREQ, signal, 2, JBB); + cmasterNodeId = ref->masterNodeId; + sendCntrStartReq(signal); return; - } + } + ndbrequire(false); +} + +void +Ndbcntr::StartRecord::reset(){ + m_starting.clear(); + m_waiting.clear(); + m_withLog.clear(); + m_withoutLog.clear(); + m_lastGci = m_lastGciNodeId = 0; + m_startPartialTimeout = ~0; + m_startPartitionedTimeout = ~0; + m_startFailureTimeout = ~0; - jam(); + m_logNodesCount = 0; +} + +void +Ndbcntr::execCNTR_START_CONF(Signal * signal){ + jamEntry(); + const CntrStartConf * conf = (CntrStartConf*)signal->getDataPtr(); + + cnoStartNodes = conf->noStartNodes; + ctypeOfStart = (NodeState::StartType)conf->startType; + c_start.m_lastGci = conf->startGci; + cmasterNodeId = conf->masterNodeId; + NdbNodeBitmask tmp; + tmp.assign(NdbNodeBitmask::Size, conf->startedNodes); + c_startedNodes.bitOR(tmp); + c_start.m_starting.assign(NdbNodeBitmask::Size, conf->startingNodes); + ph2GLab(signal); + + UpgradeStartup::sendCmAppChg(* this, signal, 2); //START +} + +/** + * Tried with parallell nr, but it crashed in DIH + * so I turned it off, as I don't want to debug DIH now... + * Jonas 19/11-03 + * + * After trying for 2 hours, I gave up. + * DIH is not designed to support it, and + * it requires quite of lot of changes to + * make it work + * Jonas 5/12-03 + */ +#define PARALLELL_NR 0 - cfgBlockPtr.i = 0; - ptrAss(cfgBlockPtr, cfgBlockRec); +#if PARALLELL_NR +const bool parallellNR = true; +#else +const bool parallellNR = false; +#endif + +void +Ndbcntr::execCNTR_START_REP(Signal* signal){ + jamEntry(); + Uint32 nodeId = signal->theData[0]; + c_startedNodes.set(nodeId); + c_start.m_starting.clear(nodeId); - cdelayStart = cfgBlockPtr.p->cfgData[0]; + if(!c_start.m_starting.isclear()){ + jam(); + return; + } - signal->theData[0] = cownBlockref; - signal->theData[1] = strlen(ZNAME_OF_APPL) | (ZNAME_OF_APPL[0] << 8); - signal->theData[2] = ZNAME_OF_APPL[1] | (ZNAME_OF_APPL[2] << 8); - signal->theData[9] = ZAPPL_SUBTYPE; - signal->theData[10] = 0; //NDB_VERSION; - sendSignal(cqmgrBlockref, GSN_APPL_REGREQ, signal, 11, JBB); - return; /* WAIT FOR APPL_REGCONF */ -}//Ndbcntr::execCMVMI_CFGCONF() + if(cmasterNodeId != getOwnNodeId()){ + c_start.reset(); + return; + } -/*******************************/ -/* APPL_REGCONF */ -/*******************************/ -void Ndbcntr::execAPPL_REGCONF(Signal* signal) -{ - jamEntry(); - cqmgrConnectionP = signal->theData[0]; - cnoNdbNodes = signal->theData[1]; - if(ctypeOfStart == NodeState::ST_INITIAL_START){ - cmasterCandidateId = signal->theData[2]; - } else { - cmasterCandidateId = ZNIL; + if(c_start.m_waiting.isclear()){ + c_start.reset(); + return; } - nodePtr.i = getOwnNodeId(); - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); + startWaitingNodes(signal); +} + +void +Ndbcntr::execCNTR_START_REQ(Signal * signal){ + jamEntry(); + const CntrStartReq * req = (CntrStartReq*)signal->getDataPtr(); - /*----------------------------------------------------------------------*/ - /* CALCULATE HOW MANY NODES THAT WE NEED TO PERFORM A START. MAKE A */ - /* DECISION ABOUT WAITING FOR MORE NODES OR TO CONTINUE AT ONCE */ - /*----------------------------------------------------------------------*/ - nodePtr.p->state = ZADD; - nodePtr.p->ndbVersion = 0; //NDB_VERSION; - nodePtr.p->subType = ZAPPL_SUBTYPE; - nodePtr.p->dynamicId = signal->theData[3]; - // Save dynamic nodeid in global variable - cdynamicNodeId = nodePtr.p->dynamicId; - cnoRegNodes = cnoRegNodes + 1; - switch((NodeState::StartType)ctypeOfStart){ - case NodeState::ST_INITIAL_START: + const Uint32 nodeId = req->nodeId; + const Uint32 lastGci = req->lastGci; + const NodeState::StartType st = (NodeState::StartType)req->startType; + + if(cmasterNodeId == 0){ jam(); - cnoNeedNodes = cnoNdbNodes; - break; - case NodeState::ST_SYSTEM_RESTART: - if (cnoNdbNodes == 2) { - jam(); - /*--------------------------------------*/ - /* NEED > 50% OF ALL NODES. */ - /* WE WILL SEND CONTINUEB WHEN THE WE */ - /* RECEIVE THE FIRST APPL_CHANGEREP. */ - /*--------------------------------------*/ - cnoNeedNodes = 1; /* IF ONLY 2 NODES IN CLUSTER, 1 WILL DO*/ - } else { - jam(); - cnoNeedNodes = (cnoNdbNodes >> 1) + 1; - }//if - break; - case NodeState::ST_NODE_RESTART: - case NodeState::ST_INITIAL_NODE_RESTART: - break; - default: - ndbrequire(false); - }//if + // Has not completed READNODES yet + sendSignalWithDelay(reference(), GSN_CNTR_START_REQ, signal, 100, + signal->getLength()); + return; + } - /*--------------------------------------------------------------*/ - /* WE CAN COME HERE ALSO IN A NODE RESTART IF THE */ - /* REGISTRATION OF A RUNNING NODE HAPPENS TO ARRIVE BEFORE*/ - /* THE APPL_REGCONF SIGNAL. */ - /* IN THAT CASE CNO_NEED_NODES = ZNIL IF NOT NODE_STATE */ - /* SIGNAL HAS RETURNED THE PROPER VALUE. IN BOTH CASES WE */ - /* DO NOT NEED TO ASSIGN IT HERE. */ - /*--------------------------------------------------------------*/ - ph2CLab(signal); - return; -}//Ndbcntr::execAPPL_REGCONF() - -/*--------------------------------------------------------------*/ -/* CHECK THAT WE GOT ALL NODES REGISTRATED AS WE NEED FOR THIS */ -/* KIND OF START. WE ALWAYS END UP HERE AFTER HANDLING OF */ -/* APPL_CHANGEREP AND NODE_STATESCONF */ -/*--------------------------------------------------------------*/ -void Ndbcntr::ph2CLab(Signal* signal) -{ - NodeRecPtr ownNodePtr; - ownNodePtr.i = getOwnNodeId(); - ptrCheckGuard(ownNodePtr, MAX_NDB_NODES, nodeRec); - if (ownNodePtr.p->state != ZADD) { + if(cmasterNodeId != getOwnNodeId()){ jam(); + sendCntrStartRef(signal, nodeId, CntrStartRef::NotMaster); return; - }//if - switch (ctypeOfStart) { - case NodeState::ST_INITIAL_START: + } + + const NodeState & nodeState = getNodeState(); + switch(nodeState.startLevel){ + case NodeState::SL_NOTHING: + case NodeState::SL_CMVMI: jam(); - if (cnoRegNodes == cnoNeedNodes) { - jam(); - ph2ELab(signal); -/*******************************/ -/* ALL NODES ADDED */ -/*******************************/ - return; - }//if + ndbrequire(false); + case NodeState::SL_STARTING: + case NodeState::SL_STARTED: + break; + + case NodeState::SL_STOPPING_1: + case NodeState::SL_STOPPING_2: + case NodeState::SL_STOPPING_3: + case NodeState::SL_STOPPING_4: + jam(); + sendCntrStartRef(signal, nodeId, CntrStartRef::StopInProgress); + return; + } + + /** + * Am I starting (or started) + */ + const bool starting = (nodeState.startLevel != NodeState::SL_STARTED); + + c_start.m_waiting.set(nodeId); + switch(st){ + case NodeState::ST_INITIAL_START: + c_start.m_withoutLog.set(nodeId); break; case NodeState::ST_SYSTEM_RESTART: - ndbrequire(cnoRunNodes == 0); - if (cnoRegNodes == cnoNdbNodes) { + c_start.m_withLog.set(nodeId); + if(starting && lastGci > c_start.m_lastGci){ jam(); - /*******************************/ - /* ALL NODES ADDED */ - /*******************************/ - ph2ELab(signal); + CntrStartRef * ref = (CntrStartRef*)signal->getDataPtrSend(); + ref->errorCode = CntrStartRef::NotMaster; + ref->masterNodeId = nodeId; + NodeReceiverGroup rg (NDBCNTR, c_start.m_waiting); + sendSignal(rg, GSN_CNTR_START_REF, signal, + CntrStartRef::SignalLength, JBB); return; - }//if - if (cwaitContinuebFlag == ZFALSE) { - if (cnoRegNodes == cnoNeedNodes) { - jam(); - /****************************************/ - /* ENOUGH NODES ADDED, WAIT CDELAY_START*/ - /****************************************/ - cwaitContinuebFlag = ZTRUE; - /*******************************/ - /* A DELAY SIGNAL TO MYSELF */ - /*******************************/ - signal->theData[0] = ZCONTINUEB_1; - sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, - signal, cdelayStart * 1000, 1); - return; - }//if - }//if + } + if(starting){ + Uint32 i = c_start.m_logNodesCount++; + c_start.m_logNodes[i].m_nodeId = nodeId; + c_start.m_logNodes[i].m_lastGci = req->lastGci; + } break; case NodeState::ST_NODE_RESTART: case NodeState::ST_INITIAL_NODE_RESTART: - jam(); - if (cnoNeedNodes <= cnoRunNodes) { - /*----------------------------------------------*/ - /* GOT ALL RUNNING NODES */ - /* " =< " :NODES MAY HAVE FINISHED A NODERESTART*/ - /* WHILE WE WERE WAITING FOR NODE_STATESCONF */ - /*----------------------------------------------*/ - if (cnoRegNodes != (cnoRunNodes + 1)) { - jam(); - systemErrorLab(signal); - return; - }//if - getStartNodes(signal); - cwaitContinuebFlag = ZFALSE; - cstartProgressFlag = ZTRUE; - /*--------------------------------------------------------------*/ - /* IF SOMEONE ELSE IS PERFORMING NODERESTART THEN WE GOT A REF */ - /* AND WE HAVE TO MAKE A NEW NODE_STATESREQ */ - /*--------------------------------------------------------------*/ - sendCntrMasterreq(signal); - }//if - break; - default: - jam(); - systemErrorLab(signal); - return; - break; - }//switch - /*--------------------------------------------------------------*/ - /* WAIT FOR THE CONTINUEB SIGNAL */ - /* AND / OR MORE NODES TO REGISTER */ - /*--------------------------------------------------------------*/ - return; -}//Ndbcntr::ph2CLab() + case NodeState::ST_ILLEGAL_TYPE: + ndbrequire(false); + } -/*******************************/ -/* CONTINUEB */ -/*******************************/ -/*--------------------------------------------------------------*/ -/* WE COME HERE ONLY IN SYSTEM RESTARTS AND INITIAL START. FOR */ -/* INITIAL START WE HAVE ALREADY CALCULATED THE MASTER. FOR */ -/* SYSTEM RESTART WE NEED TO PERFORM A VOTING SCHEME TO AGREE */ -/* ON A COMMON MASTER. WE GET OUR VOTE FROM DIH AND THE RESTART */ -/* INFORMATION IN DIH. */ -/*--------------------------------------------------------------*/ -void Ndbcntr::ph2ELab(Signal* signal) -{ - cwaitContinuebFlag = ZFALSE; -/*--------------------------------------*/ -/* JMP TO THIS WHEN ENOUGH NO OF */ -/* NODES ADDED */ -/*--------------------------------------*/ -/*--------------------------------------*/ -/* IGNORE CONTINUEB SIGNAL */ -/* CONTINUEB SIGNALS WILL EXIT AT */ -/* SIGNAL RECEPTION */ -/*--------------------------------------*/ - if (cnoRegNodes >= cnoNeedNodes) { + const bool startInProgress = !c_start.m_starting.isclear(); + + if((starting && startInProgress) || (startInProgress && !parallellNR)){ jam(); - getStartNodes(signal); - if (ctypeOfStart == NodeState::ST_INITIAL_START) { - if (cmasterCandidateId != getOwnNodeId()) { - jam(); -/*--------------------------------------*/ -/* THIS NODE IS NOT THE MASTER */ -/* DON'T SEND ANY MORE CNTR_MASTERREQ */ -/* VOTE FOR MASTER */ -/*--------------------------------------*/ - cstartProgressFlag = ZTRUE; - sendCntrMasterreq(signal); - resetStartVariables(signal); - } else { - jam(); - masterreq020Lab(signal); - }//if - } else if (ctypeOfStart == NodeState::ST_SYSTEM_RESTART) { - jam(); -/*--------------------------------------------------------------*/ -/* WE START THE SELECTION OF MASTER PROCESS. IF WE HAVE NOT */ -/* COMPLETED THIS BEFORE THE TIME OUT WE WILL TRY A NEW RESTART.*/ -/*--------------------------------------------------------------*/ - cwaitContinuebFlag = ZTRUE; - cstartProgressFlag = ZVOTING; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->state == ZADD) { - jam(); - signal->theData[0] = getOwnNodeId(); - signal->theData[1] = cmasterDihId; - signal->theData[2] = clastGci; - sendSignal(nodePtr.p->cntrBlockref, GSN_VOTE_MASTERORD, - signal, 3, JBB); - }//if - }//for - } else { - jam(); - systemErrorLab(signal); - }//if + // We're already starting together with a bunch of nodes + // Let this node wait... + return; + } + + if(starting){ + trySystemRestart(signal); } else { - jam(); -/*--------------------------------------------------------------*/ -/* TOO FEW NODES TO START */ -/* WE HAVE WAITED FOR THE GIVEN TIME OUT AND NOT ENOUGH NODES */ -/* HAS REGISTERED. WE WILL CRASH AND RENEW THE ATTEMPT TO START */ -/* THE SYSTEM. */ -/*--------------------------------------------------------------*/ - systemErrorLab(signal); - }//if + startWaitingNodes(signal); + } + return; -}//Ndbcntr::ph2ELab() +} -/*******************************/ -/* MASTER NODE CONFIRMS REQ */ -/* CNTR_MASTERCONF */ -/*******************************/ -void Ndbcntr::execCNTR_MASTERCONF(Signal* signal) -{ +void +Ndbcntr::startWaitingNodes(Signal * signal){ + +#if ! PARALLELL_NR + const Uint32 nodeId = c_start.m_waiting.find(0); + const Uint32 Tref = calcNdbCntrBlockRef(nodeId); + ndbrequire(nodeId != c_start.m_waiting.NotFound); + + NodeState::StartType nrType = NodeState::ST_NODE_RESTART; + if(c_start.m_withoutLog.get(nodeId)){ + nrType = NodeState::ST_INITIAL_NODE_RESTART; + } + + /** + * Let node perform restart + */ + CntrStartConf * conf = (CntrStartConf*)signal->getDataPtrSend(); + conf->noStartNodes = 1; + conf->startType = nrType; + conf->startGci = ~0; // Not used + conf->masterNodeId = getOwnNodeId(); + BitmaskImpl::clear(NdbNodeBitmask::Size, conf->startingNodes); + BitmaskImpl::set(NdbNodeBitmask::Size, conf->startingNodes, nodeId); + c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes); + sendSignal(Tref, GSN_CNTR_START_CONF, signal, + CntrStartConf::SignalLength, JBB); + + c_start.m_waiting.clear(nodeId); + c_start.m_withLog.clear(nodeId); + c_start.m_withoutLog.clear(nodeId); + c_start.m_starting.set(nodeId); +#else + // Parallell nr + + c_start.m_starting = c_start.m_waiting; + c_start.m_waiting.clear(); + + CntrStartConf * conf = (CntrStartConf*)signal->getDataPtrSend(); + conf->noStartNodes = 1; + conf->startGci = ~0; // Not used + conf->masterNodeId = getOwnNodeId(); + c_start.m_starting.copyto(NdbNodeBitmask::Size, conf->startingNodes); + c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes); + + char buf[100]; + if(!c_start.m_withLog.isclear()){ + ndbout_c("Starting nodes w/ log: %s", c_start.m_withLog.getText(buf)); + + NodeReceiverGroup rg(NDBCNTR, c_start.m_withLog); + conf->startType = NodeState::ST_NODE_RESTART; + + sendSignal(rg, GSN_CNTR_START_CONF, signal, + CntrStartConf::SignalLength, JBB); + } + + if(!c_start.m_withoutLog.isclear()){ + ndbout_c("Starting nodes wo/ log: %s", c_start.m_withoutLog.getText(buf)); + NodeReceiverGroup rg(NDBCNTR, c_start.m_withoutLog); + conf->startType = NodeState::ST_INITIAL_NODE_RESTART; + + sendSignal(rg, GSN_CNTR_START_CONF, signal, + CntrStartConf::SignalLength, JBB); + } + + c_start.m_waiting.clear(); + c_start.m_withLog.clear(); + c_start.m_withoutLog.clear(); +#endif +} + +void +Ndbcntr::sendCntrStartRef(Signal * signal, + Uint32 nodeId, CntrStartRef::ErrorCode code){ + CntrStartRef * ref = (CntrStartRef*)signal->getDataPtrSend(); + ref->errorCode = code; + ref->masterNodeId = cmasterNodeId; + sendSignal(calcNdbCntrBlockRef(nodeId), GSN_CNTR_START_REF, signal, + CntrStartRef::SignalLength, JBB); +} + +CheckNodeGroups::Output +Ndbcntr::checkNodeGroups(Signal* signal, const NdbNodeBitmask & mask){ + CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0]; + sd->blockRef = reference(); + sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck; + sd->mask = mask; + EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal, + CheckNodeGroups::SignalLength); jamEntry(); + return (CheckNodeGroups::Output)sd->output; +} - CntrMasterConf * const cntrMasterConf = - (CntrMasterConf *)&signal->theData[0]; +bool +Ndbcntr::trySystemRestart(Signal* signal){ + /** + * System restart something + */ + const bool allNodes = c_start.m_waiting.equal(c_allDefinedNodes); + const bool allClusterNodes = c_start.m_waiting.equal(c_clusterNodes); + const Uint64 now = NdbTick_CurrentMillisecond(); - cnoStartNodes = cntrMasterConf->noStartNodes; - int index = 0; - unsigned i; - for (i = 1; i < MAX_NDB_NODES; i++) { + if(!allClusterNodes){ jam(); - if (NodeBitmask::get(cntrMasterConf->theNodes, i)) { - jam(); - cstartNodes[index] = i; - index++; - }//if - }//for - if (cnoStartNodes != index) { + return false; + } + + if(!allNodes && c_start.m_startPartialTimeout > now){ jam(); - systemErrorLab(signal); - }//if - ph2FLab(signal); - return; -}//Ndbcntr::execCNTR_MASTERCONF() + return false; + } -void Ndbcntr::ph2FLab(Signal* signal) -{ -/*--------------------------------------------------------------*/ -//The nodes have been selected and we now know which nodes are -// included in the system restart. We can reset wait for CONTINUEB -// flag to ensure system is not restarted when CONTINUEB after the -// delay. -/*--------------------------------------------------------------*/ - cmasterNodeId = cmasterCandidateId; - cwaitContinuebFlag = ZFALSE; - ph2GLab(signal); - return; -}//Ndbcntr::ph2FLab() + NodeState::StartType srType = NodeState::ST_SYSTEM_RESTART; + if(c_start.m_waiting.equal(c_start.m_withoutLog)){ + if(!allNodes){ + jam(); + return false; + } + srType = NodeState::ST_INITIAL_START; + c_start.m_starting = c_start.m_withoutLog; // Used for starting... + c_start.m_withoutLog.clear(); + } else { + + CheckNodeGroups::Output wLog = checkNodeGroups(signal, c_start.m_withLog); + + switch (wLog) { + case CheckNodeGroups::Win: + jam(); + break; + case CheckNodeGroups::Lose: + jam(); + // If we lose with all nodes, then we're in trouble + ndbrequire(!allNodes); + return false; + break; + case CheckNodeGroups::Partitioning: + jam(); + bool allowPartition = (c_start.m_startPartitionedTimeout != (Uint64)~0); + + if(allNodes){ + jam(); + if(allowPartition){ + jam(); + break; + } + ndbrequire(false); // All nodes -> partitioning, which is not allowed + } + + if(c_start.m_startPartitionedTimeout > now){ + jam(); + return false; + } + break; + } + + // For now only with the "logged"-ones. + // Let the others do node restart afterwards... + c_start.m_starting = c_start.m_withLog; + c_start.m_withLog.clear(); + } + + /** + * Okidoki, we try to start + */ + CntrStartConf * conf = (CntrStartConf*)signal->getDataPtr(); + conf->noStartNodes = c_start.m_starting.count(); + conf->startType = srType; + conf->startGci = c_start.m_lastGci; + conf->masterNodeId = c_start.m_lastGciNodeId; + c_start.m_starting.copyto(NdbNodeBitmask::Size, conf->startingNodes); + c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes); + + ndbrequire(c_start.m_lastGciNodeId == getOwnNodeId()); + + NodeReceiverGroup rg(NDBCNTR, c_start.m_starting); + sendSignal(rg, GSN_CNTR_START_CONF, signal, CntrStartConf::SignalLength,JBB); + + c_start.m_waiting.bitANDC(c_start.m_starting); + + return true; +} -/*--------------------------------------*/ -/* RECEIVED CNTR_MASTERCONF */ -/*--------------------------------------*/ -/*******************************/ -/* NDB_STTORRY */ -/*******************************/ -/*---------------------------------------------------------------------------*/ -// NOW WE CAN START NDB START PHASE 1. IN THIS PHASE ALL BLOCKS -// (EXCEPT DIH THAT INITIALISED WHEN -// RECEIVING DIH_RESTARTREQ) WILL INITIALISE THEIR DATA, COMMON VARIABLES, -// LINKED LISTS AND RECORD VARIABLES. -/*---------------------------------------------------------------------------*/ void Ndbcntr::ph2GLab(Signal* signal) { if (cndbBlocksCount < ZNO_NDB_BLOCKS) { @@ -879,11 +874,6 @@ void Ndbcntr::ph2GLab(Signal* signal) /*******************************/ void Ndbcntr::startPhase3Lab(Signal* signal) { - cinternalStartphase = cstartPhase - 1; -/*--------------------------------------*/ -/* CASE: CSTART_PHASE = ZSTART_PHASE_3 */ -/*--------------------------------------*/ - cndbBlocksCount = 0; ph3ALab(signal); return; }//Ndbcntr::startPhase3Lab() @@ -893,29 +883,12 @@ void Ndbcntr::startPhase3Lab(Signal* signal) /*******************************/ void Ndbcntr::ph3ALab(Signal* signal) { - Uint16 tnoStartNodes; - if (cndbBlocksCount < ZNO_NDB_BLOCKS) { jam(); sendNdbSttor(signal); return; }//if -/*******************************/ -/*< APPL_STARTREG <*/ -/*******************************/ - if (ctypeOfStart == NodeState::ST_NODE_RESTART) { - jam(); - tnoStartNodes = 1; - } else if (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART) { - jam(); - tnoStartNodes = 1; - } else { - jam(); - tnoStartNodes = cnoStartNodes; - }//if - signal->theData[0] = cqmgrConnectionP; - signal->theData[1] = tnoStartNodes; - sendSignal(cqmgrBlockref, GSN_APPL_STARTREG, signal, 2, JBB); + sendSttorry(signal); return; }//Ndbcntr::ph3ALab() @@ -933,49 +906,12 @@ void Ndbcntr::ph3ALab(Signal* signal) /*******************************/ void Ndbcntr::startPhase4Lab(Signal* signal) { - cinternalStartphase = cstartPhase - 1; -/*--------------------------------------*/ -/* CASE: CSTART_PHASE = ZSTART_PHASE_4 */ -/*--------------------------------------*/ - cndbBlocksCount = 0; - cnoWaitrep = 0; - if (capplStartconfFlag != ZTRUE) { - jam(); -/*------------------------------------------------------*/ -/* HAVE WE ALREADY RECEIVED APPL_STARTCONF */ -/*------------------------------------------------------*/ - return; - }//if ph4ALab(signal); - return; }//Ndbcntr::startPhase4Lab() -/*******************************/ -/* APPL_STARTCONF */ -/*******************************/ -void Ndbcntr::execAPPL_STARTCONF(Signal* signal) -{ - jamEntry(); - if (cstartPhase == ZSTART_PHASE_4) { - jam(); - ph4ALab(signal); - return; - } else { - jam(); - capplStartconfFlag = ZTRUE; -//------------------------------------------------ -/* FLAG WILL BE CHECKED WHEN WE RECEIVED STTOR */ -/* SIGNAL MAY BE RECEIVED IN STARTPHASE 3 */ -//------------------------------------------------ - return; - }//if -}//Ndbcntr::execAPPL_STARTCONF() void Ndbcntr::ph4ALab(Signal* signal) { - nodePtr.i = getOwnNodeId(); - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - nodePtr.p->state = ZSTART; ph4BLab(signal); return; }//Ndbcntr::ph4ALab() @@ -1014,6 +950,7 @@ void Ndbcntr::waitpoint41Lab(Signal* signal) cnoWaitrep++; if (cnoWaitrep == cnoStartNodes) { jam(); + cnoWaitrep = 0; /*---------------------------------------------------------------------------*/ // NDB_STARTREQ STARTS UP ALL SET UP OF DISTRIBUTION INFORMATION IN DIH AND // DICT. AFTER SETTING UP THIS @@ -1025,9 +962,9 @@ void Ndbcntr::waitpoint41Lab(Signal* signal) // 3) EXECUTING THE FRAGMENT REDO LOG FROM ONE OR SEVERAL NODES TO // RESTORE THE RESTART CONFIGURATION OF DATA IN NDB CLUSTER. /*---------------------------------------------------------------------------*/ - signal->theData[0] = cownBlockref; + signal->theData[0] = reference(); signal->theData[1] = ctypeOfStart; - sendSignal(cdihBlockref, GSN_NDB_STARTREQ, signal, 2, JBB); + sendSignal(DBDIH_REF, GSN_NDB_STARTREQ, signal, 2, JBB); }//if } else { jam(); @@ -1037,11 +974,10 @@ void Ndbcntr::waitpoint41Lab(Signal* signal) /* SLAVES WONT DO ANYTHING UNTIL THEY */ /* RECEIVE A WAIT REPORT FROM THE MASTER*/ /*--------------------------------------*/ - nodePtr.i = cmasterNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); signal->theData[0] = getOwnNodeId(); signal->theData[1] = ZWAITPOINT_4_1; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); + sendSignal(calcNdbCntrBlockRef(cmasterNodeId), + GSN_CNTR_WAITREP, signal, 2, JBB); }//if return; }//Ndbcntr::waitpoint41Lab() @@ -1052,23 +988,11 @@ void Ndbcntr::waitpoint41Lab(Signal* signal) void Ndbcntr::execNDB_STARTCONF(Signal* signal) { jamEntry(); - UintR guard0; - UintR Ttemp1; - guard0 = cnoStartNodes - 1; - arrGuard(guard0, MAX_NDB_NODES); - for (Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) { - jam(); - if (cstartNodes[Ttemp1] != getOwnNodeId()) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = getOwnNodeId(); - signal->theData[1] = ZWAITPOINT_4_2; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); - }//if - }//for - sendSttorry(signal); + NodeReceiverGroup rg(NDBCNTR, c_start.m_starting); + signal->theData[0] = getOwnNodeId(); + signal->theData[1] = ZWAITPOINT_4_2; + sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB); return; }//Ndbcntr::execNDB_STARTCONF() @@ -1084,9 +1008,6 @@ void Ndbcntr::execNDB_STARTCONF(Signal* signal) /*******************************/ void Ndbcntr::startPhase5Lab(Signal* signal) { - cinternalStartphase = cstartPhase - 1; - cndbBlocksCount = 0; - cnoWaitrep = 0; ph5ALab(signal); return; }//Ndbcntr::startPhase5Lab() @@ -1147,16 +1068,17 @@ void Ndbcntr::ph5ALab(Signal* signal) // SEND NDB START PHASE 5 IN NODE RESTARTS TO COPY DATA TO THE NEWLY // STARTED NODE. /*----------------------------------------------------------------------*/ - req->senderRef = cownBlockref; + req->senderRef = reference(); req->nodeId = getOwnNodeId(); req->internalStartPhase = cinternalStartphase; req->typeOfStart = ctypeOfStart; req->masterNodeId = cmasterNodeId; + //#define TRACE_STTOR #ifdef TRACE_STTOR ndbout_c("sending NDB_STTOR(%d) to DIH", cinternalStartphase); #endif - sendSignal(cdihBlockref, GSN_NDB_STTOR, signal, + sendSignal(DBDIH_REF, GSN_NDB_STTOR, signal, NdbSttor::SignalLength, JBB); return; case NodeState::ST_INITIAL_START: @@ -1170,11 +1092,10 @@ void Ndbcntr::ph5ALab(Signal* signal) /* RECEIVE A WAIT REPORT FROM THE MASTER*/ /* WHEN THE MASTER HAS FINISHED HIS WORK*/ /*--------------------------------------*/ - nodePtr.i = cmasterNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); signal->theData[0] = getOwnNodeId(); signal->theData[1] = ZWAITPOINT_5_2; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); + sendSignal(calcNdbCntrBlockRef(cmasterNodeId), + GSN_CNTR_WAITREP, signal, 2, JBB); return; default: ndbrequire(false); @@ -1198,8 +1119,10 @@ void Ndbcntr::waitpoint52Lab(Signal* signal) /*--------------------------------------*/ if (cnoWaitrep == cnoStartNodes) { jam(); + cnoWaitrep = 0; + NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend(); - req->senderRef = cownBlockref; + req->senderRef = reference(); req->nodeId = getOwnNodeId(); req->internalStartPhase = cinternalStartphase; req->typeOfStart = ctypeOfStart; @@ -1207,7 +1130,7 @@ void Ndbcntr::waitpoint52Lab(Signal* signal) #ifdef TRACE_STTOR ndbout_c("sending NDB_STTOR(%d) to DIH", cinternalStartphase); #endif - sendSignal(cdihBlockref, GSN_NDB_STTOR, signal, + sendSignal(DBDIH_REF, GSN_NDB_STTOR, signal, NdbSttor::SignalLength, JBB); }//if return; @@ -1218,28 +1141,19 @@ void Ndbcntr::waitpoint52Lab(Signal* signal) /*******************************/ void Ndbcntr::ph6ALab(Signal* signal) { - UintR guard0; - UintR Ttemp1; - if ((ctypeOfStart == NodeState::ST_NODE_RESTART) || (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) { jam(); waitpoint51Lab(signal); return; }//if - guard0 = cnoStartNodes - 1; - arrGuard(guard0, MAX_NDB_NODES); - for (Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) { - jam(); - if (cstartNodes[Ttemp1] != getOwnNodeId()) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = getOwnNodeId(); - signal->theData[1] = ZWAITPOINT_5_1; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); - }//if - }//for + + NodeReceiverGroup rg(NDBCNTR, c_start.m_starting); + rg.m_nodes.clear(getOwnNodeId()); + signal->theData[0] = getOwnNodeId(); + signal->theData[1] = ZWAITPOINT_5_1; + sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB); + waitpoint51Lab(signal); return; }//Ndbcntr::ph6ALab() @@ -1283,28 +1197,18 @@ void Ndbcntr::waitpoint61Lab(Signal* signal) cnoWaitrep6++; if (cnoWaitrep6 == cnoStartNodes) { jam(); - Uint32 guard0 = cnoStartNodes - 1; - arrGuard(guard0, MAX_NDB_NODES); - for (Uint32 Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) { - jam(); - if (cstartNodes[Ttemp1] != getOwnNodeId()) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = getOwnNodeId(); - signal->theData[1] = ZWAITPOINT_6_2; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); - } - } + NodeReceiverGroup rg(NDBCNTR, c_start.m_starting); + rg.m_nodes.clear(getOwnNodeId()); + signal->theData[0] = getOwnNodeId(); + signal->theData[1] = ZWAITPOINT_6_2; + sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB); sendSttorry(signal); } } else { jam(); - nodePtr.i = cmasterNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); signal->theData[0] = getOwnNodeId(); signal->theData[1] = ZWAITPOINT_6_1; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); + sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_WAITREP, signal, 2, JBB); } } @@ -1339,28 +1243,18 @@ void Ndbcntr::waitpoint71Lab(Signal* signal) cnoWaitrep7++; if (cnoWaitrep7 == cnoStartNodes) { jam(); - Uint32 guard0 = cnoStartNodes - 1; - arrGuard(guard0, MAX_NDB_NODES); - for (Uint32 Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) { - jam(); - if (cstartNodes[Ttemp1] != getOwnNodeId()) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = getOwnNodeId(); - signal->theData[1] = ZWAITPOINT_7_2; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); - } - } + NodeReceiverGroup rg(NDBCNTR, c_start.m_starting); + rg.m_nodes.clear(getOwnNodeId()); + signal->theData[0] = getOwnNodeId(); + signal->theData[1] = ZWAITPOINT_7_2; + sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB); sendSttorry(signal); } } else { jam(); - nodePtr.i = cmasterNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); signal->theData[0] = getOwnNodeId(); signal->theData[1] = ZWAITPOINT_7_1; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); + sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_WAITREP, signal, 2, JBB); } } @@ -1378,315 +1272,11 @@ void Ndbcntr::ph8ALab(Signal* signal) // NODES WHICH PERFORM A NODE RESTART NEEDS TO GET THE DYNAMIC ID'S // OF THE OTHER NODES HERE. /*---------------------------------------------------------------------------*/ - signal->theData[0] = cqmgrConnectionP; - sendSignal(cqmgrBlockref, GSN_APPL_RUN, signal, 1, JBB); - nodePtr.i = getOwnNodeId(); - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - nodePtr.p->state = ZRUN; - cnoRunNodes = cnoRunNodes + 1; sendSttorry(signal); - cstartProgressFlag = ZFALSE; - ctypeOfStart = (NodeState::StartType)ZSYSTEM_RUN; resetStartVariables(signal); return; }//Ndbcntr::ph8BLab() -/* -4.7 HANDLE GLOBAL EVENTS, NOT BOUNDED TO INITIALSTART OR SYSTEM RESTART */ -/*#######################################################################*/ -/*******************************/ -/* APPL_CHANGEREP */ -/*******************************/ -void Ndbcntr::execAPPL_CHANGEREP(Signal* signal) -{ - jamEntry(); - Uint16 TapplEvent = signal->theData[0]; - Uint16 TapplVersion = signal->theData[1]; - Uint16 TapplNodeId = signal->theData[2]; - Uint16 TapplSubType = signal->theData[3]; - - nodePtr.i = TapplNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - nodePtr.p->subType = TapplSubType; - nodePtr.p->ndbVersion = TapplVersion; - nodePtr.p->dynamicId = signal->theData[4]; - - switch (TapplEvent) { - case ZADD: -/*----------------------------*/ -/* ADD A NEW NDB NODE TO FILE */ -/*----------------------------*/ - if (nodePtr.p->state == ZREMOVE) { - jam(); - if (cnoRegNodes == cnoNdbNodes) { - jam(); -/*----------------------------------------------*/ -/* DON'T ACCEPT MORE NODES THAN SYSFILE.CFG SPEC*/ -/*----------------------------------------------*/ - systemErrorLab(signal); - return; - }//if - nodePtr.p->state = ZADD; - cnoRegNodes = cnoRegNodes + 1; - } else { - jam(); - systemErrorLab(signal); - return; - }//if - if (cstartProgressFlag == ZFALSE) { -/*----------------------------------------------*/ -/* FLAG = TRUE WHEN CNTR_MASTERREQ IS SENT */ -/*----------------------------------------------*/ - switch (ctypeOfStart) { - case NodeState::ST_INITIAL_START: - case NodeState::ST_SYSTEM_RESTART: - jam(); - ph2CLab(signal); -/*----------------------------------------------*/ -/* CHECK IF READY TO MAKE A CNTR_MASTERREQ */ -/*----------------------------------------------*/ - break; - case NodeState::ST_NODE_RESTART: - case NodeState::ST_INITIAL_NODE_RESTART: - jam(); -/*------------------------------------------------------------------------*/ -/* THIS SHOULD NEVER OCCUR SINCE WE HAVE ALREADY BEEN ALLOWED TO */ -/* START OUR NODE. THE NEXT NODE CANNOT START UNTIL WE ARE FINISHED */ -/*------------------------------------------------------------------------*/ - systemErrorLab(signal); - break; - case ZSYSTEM_RUN: - jam(); - /*empty*/; - break; - default: - jam(); -/*------------------------------------------------------------------------*/ -/* NO PARTICULAR ACTION IS NEEDED. THE NODE WILL PERFORM A NODE */ -/* RESTART BUT NO ACTION IS NEEDED AT THIS STAGE IN THE RESTART. */ -/*------------------------------------------------------------------------*/ - systemErrorLab(signal); - break; - }//switch - } else { - jam(); -/*--------------------------------------------------------------------------*/ -// WHEN A RESTART IS IN PROGRESS THERE IS A POSSIBILITY THAT A NODE -// REGISTER AND -// THINKS THAT HE WOULD BE THE MASTER (LOWER NODE ID) BUT THE OTHER NODE IS -// ALREADY RUNNING THE RESTART. THIS WILL BE DETECTED WHEN HE ATTEMPTS A -// CNTR_MASTERREQ AND RECEIVES A REFUSE SIGNAL IN RETURN. THIS WILL CAUSE HIM -// TO CRASH. IF HE ATTEMPTS TO JOIN AS A NON-MASTER HE WILL WAIT FOR THE MASTER. -// IN THIS CASE IT IS BETTER TO SHOT HIM DOWN. FOR SAFETY REASONS WE WILL ALWAYS -// SHOT HIM DOWN. -/*--------------------------------------------------------------------------*/ - const BlockReference tblockref = calcNdbCntrBlockRef(nodePtr.i); - - SystemError * const sysErr = (SystemError*)&signal->theData[0]; - sysErr->errorCode = SystemError::StartInProgressError; - sysErr->errorRef = reference(); - sendSignal(tblockref, GSN_SYSTEM_ERROR, signal, SystemError::SignalLength, JBA); - }//if - break; - case ZSTART: - jam(); - if (nodePtr.p->state != ZADD) { - jam(); - systemErrorLab(signal); - return; - }//if - nodePtr.p->state = ZSTART; - break; - case ZRUN: - if (nodePtr.p->state == ZREMOVE) { - jam(); - cnoRegNodes = cnoRegNodes + 1; - } else { - jam(); - if (nodePtr.p->state != ZSTART) { - jam(); -/*----------------------------------------------*/ -/* STATE ZADD OR ZRUN -> ZRUN NOT ALLOWED */ -/*----------------------------------------------*/ - systemErrorLab(signal); - return; - }//if - }//if - cnoRunNodes = cnoRunNodes + 1; - nodePtr.p->state = ZRUN; - switch (ctypeOfStart) { - case NodeState::ST_INITIAL_START: - jam(); - detectNoderestart(signal); - if (ctypeOfStart == NodeState::ST_NODE_RESTART) { - jam(); -/*--------------------------------------------------------------------------*/ -/* WE DISCOVERED THAT WE ARE TRYING TO PERFORM A INITIAL START WHEN THERE */ -/* ARE ALREADY RUNNING NODES. THIS MEANS THAT THE NODE HAS CLEANED THE */ -/* FILE SYSTEM AND CONTAINS NO DATA. THIS IS AN INITIAL NODE RESTART WHICH */ -/* IS NECESSARY TO START A NODE THAT HAS BEEN TAKEN OVER. */ -/*--------------------------------------------------------------------------*/ - ctypeOfStart = NodeState::ST_INITIAL_NODE_RESTART; - }//if - break; - case NodeState::ST_SYSTEM_RESTART: - jam(); - detectNoderestart(signal); -/*----------------------------------------------*/ -/* SHOULD THIS NODE PERFORM A NODE RESTART? */ -/* THEN CHANGE CTYPE_OF_START TO NodeState::ST_NODE_RESTART */ -/* AND SEND NODE_STATESREQ. */ -/* WAIT FOR NODE_STATESCONF. */ -/*----------------------------------------------*/ - break; - case NodeState::ST_NODE_RESTART: - case NodeState::ST_INITIAL_NODE_RESTART: - jam(); -/*----------------------------------------------*/ -/* IF WE ARE WAITING FOR NODE_STATESCONF, THIS */ -/* JUMP WILL EXIT BECAUSE CNO_NEED_NODES = ZNIL */ -/* UNTIL WE RECEIVE NODE_STATESCONF */ -/*----------------------------------------------*/ - ph2CLab(signal); - break; - case ZSYSTEM_RUN: - jam(); - break; - default: - jam(); - systemErrorLab(signal); - break; - }//switch - break; - default: - jam(); - systemErrorLab(signal); - break; - }//switch - return; -}//Ndbcntr::execAPPL_CHANGEREP() - -/*--------------------------------------------------------------------------*/ -// A NODE HAS ADDED HAS VOTE ON WHICH MASTER IS TO BE CHOOSEN IN A SYSTEM -// RESTART. WHEN ALL VOTES HAVE -// BEEN ADDED THEN WE ARE PREPARED TO CHOOSE MASTER AND CONTINUE WITH THE -// RESTART PROCESSING. -/*--------------------------------------------------------------------------*/ - -/*******************************/ -/* VOT_MASTERORD */ -/*******************************/ -void Ndbcntr::execVOTE_MASTERORD(Signal* signal) -{ - jamEntry(); - nodePtr.i = signal->theData[0]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - UintR TmasterCandidateId = signal->theData[1]; - UintR TlastGci = signal->theData[2]; - if (ctypeOfStart != NodeState::ST_SYSTEM_RESTART) { - jam(); - progError(__LINE__, - ERR_SR_RESTARTCONFLICT, - "One ore more nodes probably requested an initial SR"); - return; - }//if - cmasterVoters = cmasterVoters + 1; - if (cmasterVoters == 1) { - jam(); - cmasterCurrentId = TmasterCandidateId; - cmasterLastGci = TlastGci; - } else { - if (cmasterLastGci < TlastGci) { - jam(); - cmasterCurrentId = TmasterCandidateId; - cmasterLastGci = TlastGci; - } else if (cmasterLastGci == TlastGci) { - jam(); - if (cmasterCurrentId != TmasterCandidateId) { - jam(); - systemErrorLab(signal); - return; - }//if - }//if - }//if - if (cstartProgressFlag == ZVOTING) { -/*--------------------------------------------------------------------------*/ -// UNLESS START PROGRESS FLAG IS SET TO VOTING WE HAVE NOT YET REACHED A -// STATE WHERE WE ARE READY TO -// PROCEED WITH THE SYSTEM RESTART. OUR OWN NOTE HAVE AT LEAST NOT BEEN -// CAST INTO THE BALLOT YET. -/*--------------------------------------------------------------------------*/ - if (cmasterVoters == cnoRegNodes) { - cmasterCandidateId = cmasterCurrentId; - if (cmasterCandidateId == getOwnNodeId()) { - jam(); - masterreq020Lab(signal); - return; - } else { - jam(); - cstartProgressFlag = ZTRUE; - sendCntrMasterreq(signal); - resetStartVariables(signal); - }//if - }//if - }//if - return; -}//Ndbcntr::execVOTE_MASTERORD() - -/*******************************/ -/* CNTR_MASTERREQ */ -/*******************************/ -void Ndbcntr::execCNTR_MASTERREQ(Signal* signal) -{ - Uint16 ttypeOfStart; - - jamEntry(); - - CntrMasterReq * const cntrMasterReq = - (CntrMasterReq *)&signal->theData[0]; - -//----------------------------------------------- -// cntrMasterReq->userBlockRef NOT USED -//----------------------------------------------- - Uint16 TuserNodeId = cntrMasterReq->userNodeId; - ttypeOfStart = cntrMasterReq->typeOfStart; - Uint16 TnoRestartNodes = cntrMasterReq->noRestartNodes; - int index = 0; - unsigned i; - for (i = 1; i < MAX_NDB_NODES; i++) { - jam(); - if (NodeBitmask::get(cntrMasterReq->theNodes, i)) { - jam(); - cstartNodes[index] = i; - index++; - }//if - }//for - if (TnoRestartNodes != index) { - jam(); - systemErrorLab(signal); - }//if - switch (ttypeOfStart) { - case NodeState::ST_INITIAL_START: - case NodeState::ST_SYSTEM_RESTART: - jam(); -//-------------------------------- -/* ELECTION OF MASTER AT */ -/* INITIAL OR SYSTEM RESTART */ -//-------------------------------- - masterreq010Lab(signal, TnoRestartNodes, TuserNodeId); - break; - case NodeState::ST_NODE_RESTART: - case NodeState::ST_INITIAL_NODE_RESTART: - jam(); - masterreq030Lab(signal, TnoRestartNodes, TuserNodeId); - break; - default: - jam(); - systemErrorLab(signal); - break; - }//switch -}//Ndbcntr::execCNTR_MASTERREQ() - /*******************************/ /* CNTR_WAITREP */ /*******************************/ @@ -1736,243 +1326,102 @@ void Ndbcntr::execCNTR_WAITREP(Signal* signal) }//switch }//Ndbcntr::execCNTR_WAITREP() -/* -4.7.4 MASTERREQ_010 ( CASE: INITIALSTART OR SYSTEMRESTART ) */ -/*--------------------------------------------------------------------------*/ -// ELECTION OF MASTER AND ELECTION OF PARTICIPANTS IN START. SENDER OF -// CNTR_MASTERREQ THINKS THAT THIS NODE -// SHOULD BE THE MASTER. WE CAN'T MAKE A DECISION ABOUT WHO THE MASTER -// SHOULD BE UNTIL TIMELIMIT HAS EXPIRED AND -// THAT AT LEAST CNO_NEED_NODES ARE ZADD IN NODE_PTR_REC. IF THIS NODE IS -// MASTER THEN MAKE SURE THAT ALL NODES IN -// THE CLUSTER COMES TO AN AGREEMENT ABOUT A SUBSET OF NODES THAT SATISFIES -// THE NUMBER CNO_NEED_NODES. THERE IS -// A POSSIBILITY THAT THE RECEIVER OF CNTR_MASTERREQ DOESN'T HAS CHOOSEN -// A MASTER, THEN THE RECEIVER CAN'T -// EITHER CONFIRM OR REFUSE JUST STORE THE VOTES OF THE CLUSTERMEMBERS. -// IF THIS NODE BECOME AWARE OF THAT ANOTHER NODE IS MASTER THEN CHECK IF -// ANYONE HAS VOTED (SENT CNTR_MASTERREQ) */ -// AND THEN SEND THEM CNTR_MASTERREF BACK. -/*--------------------------------------------------------------------------*/ -void Ndbcntr::masterreq010Lab(Signal* signal, - Uint16 TnoRestartNodes, - Uint16 TuserNodeId) -{ - UintR guard0; - UintR Ttemp1; - - nodePtr.i = TuserNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - if (cstartProgressFlag == ZTRUE) { - jam(); -/*--------------------------------------*/ -/* RESTART ALREADY IN PROGRESS */ -/*--------------------------------------*/ - if (ctypeOfStart == NodeState::ST_INITIAL_START) { - jam(); - systemErrorLab(signal); - return; - }//if - signal->theData[0] = cownBlockref; - signal->theData[1] = getOwnNodeId(); - signal->theData[2] = ZSTART_IN_PROGRESS_ERROR; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREF, signal, 3, JBB); - return; - }//if - cnoVoters = cnoVoters + 1; - nodePtr.p->voter = ZTRUE; - guard0 = TnoRestartNodes - 1; - arrGuard(guard0, MAX_NDB_NODES); - for (Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - nodePtr.p->votes = nodePtr.p->votes + 1; - }//for - masterreq020Lab(signal); - return; -}//Ndbcntr::masterreq010Lab() - -/*----------------------------------------------------------------------*/ -/* WHEN WE JUST WANT TO CHECK OUR VOTES IT IS POSSIBLE TO JUMP TO THIS */ -/* LABEL. IF WE HAVEN'T RECEIVED ANY VOTES SINCE OUR LASTCHECK WE WILL */ -/* JUST PERFORM AN EXIT */ -/*----------------------------------------------------------------------*/ -void Ndbcntr::masterreq020Lab(Signal* signal) -{ - if (cmasterCandidateId == ZNIL) { - jam(); -/*--------------------------------------*/ -/* MASTER UNKNOWN */ -/*--------------------------------------*/ - return; - } else if (cmasterCandidateId == getOwnNodeId()) { - jam(); -/*--------------------------------------*/ -/* SATISFIED WHEN WE HAVE AS MANY VOTERS*/ -/* AS RESTARTNODES - 1, DIFFERENT NODES?*/ -/* <- CNO_START_NODES, ALL NODES AGREED */ -/* ON THESE CNO_START_NODES */ -/*--------------------------------------*/ - if ((cnoStartNodes - 1) == cnoVoters) { - chooseRestartNodes(signal); - if (cnoStartNodes >= cnoNeedNodes) { - jam(); - cstartProgressFlag = ZTRUE; -/*--------------------------------------*/ -/* DON'T SEND ANY MORE CNTR_MASTERREQ */ -/*--------------------------------------*/ - replyMasterconfToAll(signal); -/*--------------------------------------*/ -/* SEND CONF TO ALL PASSED REQ */ -/* DON'T SEND ANYTHING TO REJECTED NODES*/ -/* BLOCK THEM UNTIL SYSTEM IS RUNNING */ -/* CONTINUE RESTART */ -/*--------------------------------------*/ - ph2FLab(signal); - } else { - jam(); - systemErrorLab(signal); - }//if - }//if - } else { - jam(); -/*----------------------------------------------------------------------*/ -/* WE RECEIVED A REQUEST TO A MASTER WHILE NOT BEING MASTER. THIS */ -/* MUST BE AN ERROR INDICATION. WE CRASH. */ -/*----------------------------------------------------------------------*/ - systemErrorLab(signal); - }//if - return; /* WAIT FOR MORE CNTR_MASTERREQ */ -}//Ndbcntr::masterreq020Lab() - -void Ndbcntr::masterreq030Lab(Signal* signal, - Uint16 TnoRestartNodes, - Uint16 TuserNodeId) -{ - UintR TretCode; - if (cmasterNodeId == getOwnNodeId()) { - jam(); - TretCode = checkNodelist(signal, TnoRestartNodes); - nodePtr.i = TuserNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - if (TretCode == 1) { - jam(); -/*******************************************************<*/ -/* CSTART_NODES IS OVERWRITTEN IN RECEIVING BLOCK, */ -/* SO WE MUST SEND CNTR_MASTERCONF TO THE SAME */ -/* CSTART_NODES AS WE RECEIVED IN CNTR_MASTERREQ */ -/*******************************************************<*/ - - CntrMasterConf * const cntrMasterConf = - (CntrMasterConf *)&signal->theData[0]; - NodeBitmask::clear(cntrMasterConf->theNodes); - for (int i = 0; i < TnoRestartNodes; i++){ - jam(); - UintR Tnode = cstartNodes[i]; - arrGuard(Tnode, MAX_NDB_NODES); - NodeBitmask::set(cntrMasterConf->theNodes, Tnode); - }//for - cntrMasterConf->noStartNodes = TnoRestartNodes; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERCONF, - signal, CntrMasterConf::SignalLength, JBB); - } else { - jam(); - signal->theData[0] = cownBlockref; - signal->theData[1] = getOwnNodeId(); - signal->theData[2] = ZTOO_FEW_NODES; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREF, signal, 3, JBB); - }//if - } else { - jam(); - nodePtr.i = TuserNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = cownBlockref; - signal->theData[1] = getOwnNodeId(); - signal->theData[2] = ZNOT_MASTER; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREF, signal, 3, JBB); - }//if - return; -}//Ndbcntr::masterreq030Lab() - /*******************************/ /* NODE_FAILREP */ /*******************************/ void Ndbcntr::execNODE_FAILREP(Signal* signal) { - UintR TfailureNr; - UintR TnoOfNodes; - UintR TreadNodes[MAX_NDB_NODES]; - jamEntry(); + const NodeFailRep * nodeFail = (NodeFailRep *)&signal->theData[0]; + NdbNodeBitmask allFailed; + allFailed.assign(NdbNodeBitmask::Size, nodeFail->theNodes); + + NdbNodeBitmask failedStarted = c_startedNodes; + NdbNodeBitmask failedStarting = c_start.m_starting; + NdbNodeBitmask failedWaiting = c_start.m_waiting; + + failedStarted.bitAND(allFailed); + failedStarting.bitAND(allFailed); + failedWaiting.bitAND(allFailed); + + const bool tMasterFailed = allFailed.get(cmasterNodeId); + const bool tStarted = !failedStarted.isclear(); + const bool tStarting = !failedStarting.isclear(); + const bool tWaiting = !failedWaiting.isclear(); + + if(tMasterFailed){ + jam(); + /** + * If master has failed choose qmgr president as master + */ + cmasterNodeId = nodeFail->masterNodeId; + } + + /** + * Clear node bitmasks from failed nodes + */ + c_start.m_starting.bitANDC(allFailed); + c_start.m_waiting.bitANDC(allFailed); + c_start.m_withLog.bitANDC(allFailed); + c_start.m_withoutLog.bitANDC(allFailed); + c_clusterNodes.bitANDC(allFailed); + c_startedNodes.bitANDC(allFailed); + const NodeState & st = getNodeState(); if(st.startLevel == st.SL_STARTING){ - if(!st.getNodeRestartInProgress()){ + jam(); + + const Uint32 phase = st.starting.startPhase; + + const bool tStartConf = (phase > 2) || (phase == 2 && cndbBlocksCount > 0); + + if(tMasterFailed){ progError(__LINE__, ERR_SR_OTHERNODEFAILED, - "Unhandled node failure during system restart"); + "Unhandled node failure during restart"); + } + + if(tStartConf && tStarting){ + // One of other starting nodes has crashed... + progError(__LINE__, + ERR_SR_OTHERNODEFAILED, + "Unhandled node failure of starting node during restart"); } - } - - { - NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0]; - TfailureNr = nodeFail->failNo; - TnoOfNodes = nodeFail->noOfNodes; - unsigned index = 0; - unsigned i; - for (i = 0; i < MAX_NDB_NODES; i++) { - jam(); - if (NodeBitmask::get(nodeFail->theNodes, i)) { - jam(); - TreadNodes[index] = i; - index++; - ndbrequire(getOwnNodeId() != i); - }//if + if(tStartConf && tStarted){ + // One of other started nodes has crashed... + progError(__LINE__, + ERR_SR_OTHERNODEFAILED, + "Unhandled node failure of started node during restart"); + } + + Uint32 nodeId = 0; + while(!allFailed.isclear()){ + nodeId = allFailed.find(nodeId + 1); + allFailed.clear(nodeId); + signal->theData[0] = nodeId; + sendSignal(QMGR_REF, GSN_NDB_FAILCONF, signal, 1, JBB); }//for - ndbrequire(TnoOfNodes == index); + + return; } - for (Uint32 i = 0; i < TnoOfNodes; i++) { - jam(); - nodePtr.i = TreadNodes[i]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = EventReport::NODE_FAILREP; - signal->theData[1] = nodePtr.i; - signal->theData[2] = nodePtr.p->state; - sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB); - if (nodePtr.p->state != ZREMOVE) { - jam(); - deleteNode(signal); - }//if - }//for + ndbrequire(!allFailed.get(getOwnNodeId())); -/*******************************/ -/*< NODE_FAILREP <*/ -/*******************************/ - NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0]; - - nodeFail->failNo = TfailureNr; - nodeFail->masterNodeId = cmasterNodeId; + NodeFailRep * rep = (NodeFailRep *)&signal->theData[0]; + rep->masterNodeId = cmasterNodeId; - nodeFail->noOfNodes = TnoOfNodes; - NodeBitmask::clear(nodeFail->theNodes); - for (unsigned i = 0; i < TnoOfNodes; i++) { - jam(); - NodeBitmask::set(nodeFail->theNodes, TreadNodes[i]); - }//for - - sendSignal(ctcBlockref, GSN_NODE_FAILREP, signal, + sendSignal(DBTC_REF, GSN_NODE_FAILREP, signal, NodeFailRep::SignalLength, JBB); - sendSignal(clqhBlockref, GSN_NODE_FAILREP, signal, + sendSignal(DBLQH_REF, GSN_NODE_FAILREP, signal, NodeFailRep::SignalLength, JBB); - sendSignal(cdihBlockref, GSN_NODE_FAILREP, signal, + sendSignal(DBDIH_REF, GSN_NODE_FAILREP, signal, NodeFailRep::SignalLength, JBB); - sendSignal(cdictBlockref, GSN_NODE_FAILREP, signal, + sendSignal(DBDICT_REF, GSN_NODE_FAILREP, signal, NodeFailRep::SignalLength, JBB); sendSignal(BACKUP_REF, GSN_NODE_FAILREP, signal, @@ -1983,80 +1432,25 @@ void Ndbcntr::execNODE_FAILREP(Signal* signal) sendSignal(GREP_REF, GSN_NODE_FAILREP, signal, NodeFailRep::SignalLength, JBB); - return; -}//Ndbcntr::execNODE_FAILREP() -/*******************************/ -/* NODE_STATESCONF */ -/*******************************/ -void Ndbcntr::execNODE_STATESCONF(Signal* signal) -{ - jamEntry(); - cmasterCandidateId = signal->theData[0]; - cnoNeedNodes = signal->theData[1]; -/*----------------------------------------------------------------------*/ -// Now that we have knowledge of how many nodes are needed we will call -// ph2CLab to ensure that node restart continues if we already received -// all APPL_CHANGEREP signals. -/*----------------------------------------------------------------------*/ - ph2CLab(signal); - return; -}//Ndbcntr::execNODE_STATESCONF() - -/*******************************/ -/* NODE_STATESREF */ -/*******************************/ -void Ndbcntr::execNODE_STATESREF(Signal* signal) -{ - jamEntry(); - systemErrorLab(signal); - return; -}//Ndbcntr::execNODE_STATESREF() + Uint32 nodeId = 0; + while(!allFailed.isclear()){ + nodeId = allFailed.find(nodeId + 1); + allFailed.clear(nodeId); + signal->theData[0] = EventReport::NODE_FAILREP; + signal->theData[1] = nodeId; + signal->theData[2] = 0; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB); + }//for -/*******************************/ -/* NODE_STATESREQ */ -/*******************************/ -void Ndbcntr::execNODE_STATESREQ(Signal* signal) -{ - UintR TnoNeedNodes = 0; - NodeRecPtr TNodePtr; - jamEntry(); - BlockReference TuserBlockref = signal->theData[0]; -/*----------------------------------------------------------------------*/ -// IF WE ARE RUNNING, WE WILL ANSWER THIS SIGNAL WITH THE AMOUNT OF NODES -// THAT ARE IN THE RUN STATE OR START STATE. -/*----------------------------------------------------------------------*/ - TNodePtr.i = getOwnNodeId(); - ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRec); - if (TNodePtr.p->state == ZRUN) { - jam(); - for (TNodePtr.i = 1; TNodePtr.i < MAX_NDB_NODES; TNodePtr.i++) { - jam(); - ptrAss(TNodePtr, nodeRec); - if ((TNodePtr.p->state == ZRUN) || - (TNodePtr.p->state == ZSTART)) { - jam(); - TnoNeedNodes++; - }//if - }//for - signal->theData[0] = cmasterNodeId; - signal->theData[1] = TnoNeedNodes; - sendSignal(TuserBlockref, GSN_NODE_STATESCONF, signal, 2, JBB); - } else { - jam(); - signal->theData[0] = ZERROR_NOT_RUNNING; - sendSignal(TuserBlockref, GSN_NODE_STATESREF, signal, 1, JBB); - }//if return; -}//Ndbcntr::execNODE_STATESREQ() +}//Ndbcntr::execNODE_FAILREP() /*******************************/ /* READ_NODESREQ */ /*******************************/ void Ndbcntr::execREAD_NODESREQ(Signal* signal) { - UintR TnoNodes = 0; - NodeRecPtr TNodePtr; jamEntry(); /*----------------------------------------------------------------------*/ @@ -2067,59 +1461,36 @@ void Ndbcntr::execREAD_NODESREQ(Signal* signal) BlockReference TuserBlockref = signal->theData[0]; ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0]; - if (cstartPhase > ZSTART_PHASE_2) { - ndbrequire(cstartProgressFlag == ZTRUE); - - NodeBitmask::clear(readNodes->allNodes); - NodeBitmask::clear(readNodes->inactiveNodes); - - /** - * Add started nodes - */ - for (int i = 0; i < cnoStartNodes; i++){ - jam(); - TNodePtr.i = cstartNodes[i]; - ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRec); - - NodeBitmask::set(readNodes->allNodes, TNodePtr.i); - readNodes->setVersionId(TNodePtr.i, TNodePtr.p->ndbVersion, - readNodes->theVersionIds); - TnoNodes++; - }//for - - /** - * Sometimes add myself - */ - if ((ctypeOfStart == NodeState::ST_NODE_RESTART) || - (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) { - jam(); - - NodeBitmask::set(readNodes->allNodes, getOwnNodeId()); - readNodes->setVersionId(getOwnNodeId(), NDB_VERSION, - readNodes->theVersionIds); - TnoNodes++; - }//if - /** - * Check all nodes which are defined but not already added - */ - for (TNodePtr.i = 1; TNodePtr.i < MAX_NDB_NODES; TNodePtr.i++) { - jam(); - ptrAss(TNodePtr, nodeRec); - if ((TNodePtr.p->nodeDefined == ZTRUE) && - (NodeBitmask::get(readNodes->allNodes, TNodePtr.i) == false)){ - jam(); + /** + * Prepare inactiveNodes bitmask. + * The concept as such is by the way pretty useless. + * It makes parallell starts more or less impossible... + */ + NdbNodeBitmask tmp1; + tmp1.bitOR(c_startedNodes); + if(!getNodeState().getNodeRestartInProgress()){ + tmp1.bitOR(c_start.m_starting); + } else { + tmp1.set(getOwnNodeId()); + } - NodeBitmask::set(readNodes->allNodes, TNodePtr.i); - NodeBitmask::set(readNodes->inactiveNodes, TNodePtr.i); - readNodes->setVersionId(TNodePtr.i, NDB_VERSION, - readNodes->theVersionIds); - - TnoNodes++; - }//if - }//for - - readNodes->noOfNodes = TnoNodes; - readNodes->masterNodeId = cmasterNodeId; + NdbNodeBitmask tmp2; + tmp2.bitOR(c_allDefinedNodes); + tmp2.bitANDC(tmp1); + /** + * Fill in return signal + */ + tmp2.copyto(NdbNodeBitmask::Size, readNodes->inactiveNodes); + c_allDefinedNodes.copyto(NdbNodeBitmask::Size, readNodes->allNodes); + c_clusterNodes.copyto(NdbNodeBitmask::Size, readNodes->clusterNodes); + c_startedNodes.copyto(NdbNodeBitmask::Size, readNodes->startedNodes); + c_start.m_starting.copyto(NdbNodeBitmask::Size, readNodes->startingNodes); + + readNodes->noOfNodes = c_allDefinedNodes.count(); + readNodes->masterNodeId = cmasterNodeId; + readNodes->ndynamicId = cdynamicNodeId; + if (cstartPhase > ZSTART_PHASE_2) { + jam(); sendSignal(TuserBlockref, GSN_READ_NODESCONF, signal, ReadNodesConf::SignalLength, JBB); @@ -2237,8 +1608,8 @@ void Ndbcntr::startInsertTransactions(Signal* signal) ckey = 1; ctransidPhase = ZTRUE; - signal->theData[1] = cownBlockref; - sendSignal(ctcBlockref, GSN_TCSEIZEREQ, signal, 2, JBB); + signal->theData[1] = reference(); + sendSignal(DBTC_REF, GSN_TCSEIZEREQ, signal, 2, JBB); return; }//Ndbcntr::startInsertTransactions() @@ -2296,7 +1667,7 @@ void Ndbcntr::crSystab7Lab(Signal* signal) tcKeyReq->requestInfo = reqInfo; tcKeyReq->tableSchemaVersion = ZSYSTAB_VERSION; tcKeyReq->transId1 = 0; - tcKeyReq->transId2 = 0; + tcKeyReq->transId2 = ckey; //------------------------------------------------------------- // There is no optional part in this TCKEYREQ. There is one @@ -2312,7 +1683,7 @@ void Ndbcntr::crSystab7Lab(Signal* signal) AttributeHeader::init(&tAIDataPtr[2], 1, 2); tAIDataPtr[3] = (tkey << 16); tAIDataPtr[4] = 1; - sendSignal(ctcBlockref, GSN_TCKEYREQ, signal, + sendSignal(DBTC_REF, GSN_TCKEYREQ, signal, TcKeyReq::StaticLength + 6, JBB); }//for ckey = ckey + RowsPerCommit; @@ -2335,7 +1706,7 @@ void Ndbcntr::execTCKEYCONF(Signal* signal) Uint32 transId2 = keyConf->transId2; signal->theData[0] = transId1; signal->theData[1] = transId2; - sendSignal(ctcBlockref, GSN_TC_COMMIT_ACK, signal, 2, JBB); + sendSignal(DBTC_REF, GSN_TC_COMMIT_ACK, signal, 2, JBB); }//if cresponses = cresponses + TcKeyConf::getNoOfOperations(confInfo); @@ -2363,8 +1734,8 @@ void Ndbcntr::crSystab8Lab(Signal* signal) return; }//if signal->theData[0] = ctcConnectionP; - signal->theData[1] = cownBlockref; - sendSignal(ctcBlockref, GSN_TCRELEASEREQ, signal, 2, JBB); + signal->theData[1] = reference(); + sendSignal(DBTC_REF, GSN_TCRELEASEREQ, signal, 2, JBB); return; }//Ndbcntr::crSystab8Lab() @@ -2380,8 +1751,8 @@ void Ndbcntr::execTCRELEASECONF(Signal* signal) void Ndbcntr::crSystab9Lab(Signal* signal) { - signal->theData[1] = cownBlockref; - sendSignalWithDelay(cdihBlockref, GSN_GETGCIREQ, signal, 100, 2); + signal->theData[1] = reference(); + sendSignalWithDelay(DBDIH_REF, GSN_GETGCIREQ, signal, 100, 2); return; }//Ndbcntr::crSystab9Lab() @@ -2435,309 +1806,28 @@ void Ndbcntr::execTCSEIZEREF(Signal* signal) return; }//Ndbcntr::execTCSEIZEREF() -/* -4.10 SUBROUTINES */ -/*##########################################################################*/ -/* -4.10.1 CHECK_NODELIST */ -/*---------------------------------------------------------------------------*/ -/*CHECK THAT ALL THE NEW NODE HAS DETECTED ALL RUNNING NODES */ -/*INPUT: CSTART_NODES */ -/* TNO_RESTART_NODES */ -/* TUSER_NODE_ID */ -/*RET: CNODE_RESTART */ -/*---------------------------------------------------------------------------*/ -UintR Ndbcntr::checkNodelist(Signal* signal, Uint16 TnoRestartNodes) -{ - UintR guard1; - UintR Ttemp1; - - if (cnoRunNodes == TnoRestartNodes) { - jam(); - guard1 = TnoRestartNodes - 1; - arrGuard(guard1, MAX_NDB_NODES); - for (Ttemp1 = 0; Ttemp1 <= guard1; Ttemp1++) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - if (nodePtr.p->state != ZRUN) { - jam(); - return 0; - }//if - }//for - return 1; - }//if - return 0; -}//Ndbcntr::checkNodelist() - -/*---------------------------------------------------------------------------*/ -// SELECT NODES THAT ARE IN THE STATE TO PERFORM A INITIALSTART OR -// SYSTEMRESTART. -// THIS SUBROUTINE CAN ONLY BE INVOKED BY THE MASTER NODE. -// TO BE CHOOSEN A NODE NEED AS MANY VOTES AS THERE ARE VOTERS, AND OF -// COURSE THE NODE HAS TO BE KNOWN BY THE -// MASTER -// INPUT: NODE_REC -// CNO_NEED_NODES -// RETURN:CNO_START_NODES -// CSTART_NODES -/*---------------------------------------------------------------------------*/ -void Ndbcntr::chooseRestartNodes(Signal* signal) -{ - cnoStartNodes = 0; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->votes == cnoVoters) { - jam(); - if (nodePtr.p->state == ZADD) { - jam(); - arrGuard(cnoStartNodes, MAX_NDB_NODES); - cstartNodes[cnoStartNodes] = nodePtr.i; - cnoStartNodes++; - }//if - } else { - jam(); - if (nodePtr.p->votes > 0) { - jam(); - systemErrorLab(signal); - return; - }//if - }//if - }//for -}//Ndbcntr::chooseRestartNodes() - -/* -4.10.6 DELETE_NODE */ -/*---------------------------------------------------------------------------*/ -// INPUT: NODE_PTR -/*---------------------------------------------------------------------------*/ -void Ndbcntr::deleteNode(Signal* signal) -{ - UintR tminDynamicId; - - if (nodePtr.p->state == ZRUN) { - jam(); - cnoRunNodes = cnoRunNodes - 1; - }//if - nodePtr.p->state = ZREMOVE; - nodePtr.p->votes = 0; - nodePtr.p->voter = ZFALSE; - cnoRegNodes--; - if (nodePtr.i == cmasterNodeId) { - jam(); - cmasterNodeId = ZNIL; -/*---------------------------------------------------------------------------*/ -// IF MASTER HAVE CRASHED WE NEED TO SELECT A NEW MASTER. -/*---------------------------------------------------------------------------*/ - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->state == ZRUN) { - if (cmasterNodeId == ZNIL) { - jam(); - cmasterNodeId = nodePtr.i; - tminDynamicId = nodePtr.p->dynamicId; - } else { - jam(); - if (nodePtr.p->dynamicId < tminDynamicId) { - jam(); - cmasterNodeId = nodePtr.i; - tminDynamicId = nodePtr.p->dynamicId; - }//if - }//if - }//if - }//for - }//if -}//Ndbcntr::deleteNode() - -/*---------------------------------------------------------------------------*/ -// A NEW NODE TRIES TO DETECT A NODE RESTART. NodeState::ST_NODE_RESTART IS A POSSIBLE -// STATE ONLY WHEN THE SYSTEM IS RUNNING. -// IF THE SYSTEM IS RUNNING THEN -// CTYPE_OF_START = NodeState::ST_SYSTEM_RESTART UNTIL THE FIRST NODE HAS REGISTERED. -// IF SYSTEM IS */ -// RUNNING THE FIRST NODE TO REGISTER WILL BE ZRUN AND CTYPE_OF_START -// WILL BE CHANGED */ -// TO NodeState::ST_NODE_RESTART AT PH_2C. WHEN A NodeState::ST_NODE_RESTART IS DETECTED THE NEW NODE -// HAS TO SEND */ -// A CNTR_MASTERREQ TO THE MASTER -/*---------------------------------------------------------------------------*/ -void Ndbcntr::detectNoderestart(Signal* signal) -{ - NodeRecPtr ownNodePtr; - ownNodePtr.i = getOwnNodeId(); - ptrCheckGuard(ownNodePtr, MAX_NDB_NODES, nodeRec); - if (ownNodePtr.p->state != ZADD) { - if (ownNodePtr.p->state != ZREMOVE) { - jam(); - return; - }//if - }//if - ctypeOfStart = NodeState::ST_NODE_RESTART; -/*----------------------------------------------*/ -/* THIS NODE WILL PERFORM A NODE RESTART */ -/* REQUEST OF ALL NODES STATES IN SYSTEM */ -// The purpose of this signal is to ensure that -// the starting node knows when it has received -// all APPL_CHANGEREP signals and thus can continue -// to the next step of the node restart. Thus we -// need to know the amount of nodes that are in the -// RUN state and in the START state (more than one -// node can be copying data simultaneously in the -// cluster. -/*----------------------------------------------*/ - signal->theData[0] = cownBlockref; - sendSignal(nodePtr.p->cntrBlockref, GSN_NODE_STATESREQ, signal, 1, JBB); - cnoNeedNodes = ZNIL; -/*---------------------------------*/ -/* PREVENT TO SEND NODE_STATESREQ */ -/*---------------------------------------------------------------------------*/ -/* WE NEED TO WATCH THE NODE RESTART WITH A TIME OUT TO NOT WAIT FOR EVER. */ -/*---------------------------------------------------------------------------*/ - cwaitContinuebFlag = ZTRUE; - signal->theData[0] = ZCONTINUEB_1; - sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 3 * 1000, 1); -}//Ndbcntr::detectNoderestart() - -/*---------------------------------------------------------------------------*/ -// SCAN NODE_REC FOR APPROPRIATE NODES FOR A START. -// SYSTEMRESTART AND INITALSTART DEMANDS NODES OF STATE ZADD. -// NODERESTART DEMANDS NODE OF THE STATE ZRUN. -// INPUT: CTYPE_OF_START, NODE_REC -// RETURN: CSTART_NODES(), CNO_START_NODES, CMASTER_CANDIDATE_ID -// (SYSTEMRESTART AND INITALSTART) -/*---------------------------------------------------------------------------*/ -void Ndbcntr::getStartNodes(Signal* signal) -{ - UintR Ttemp1; - if ((ctypeOfStart == NodeState::ST_NODE_RESTART) || - (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) { - jam(); - Ttemp1 = ZRUN; - } else { - jam(); -/*---------------------------------*/ -/* SYSTEM RESTART AND INITIAL START*/ -/*---------------------------------*/ - Ttemp1 = ZADD; - }//if - cnoStartNodes = 0; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->state == Ttemp1) { - jam(); - cstartNodes[cnoStartNodes] = nodePtr.i;/*OVERWRITTEN AT CNTR_MASTERCONF*/ - cnoStartNodes++; - }//if - }//for -}//Ndbcntr::getStartNodes() /*---------------------------------------------------------------------------*/ /*INITIALIZE VARIABLES AND RECORDS */ /*---------------------------------------------------------------------------*/ void Ndbcntr::initData(Signal* signal) { - cmasterNodeId = ZNIL; - cmasterCandidateId = ZNIL; - cmasterVoters = 0; - cstartProgressFlag = ZFALSE; - capplStartconfFlag = ZFALSE; - cnoVoters = 0; + c_start.reset(); + cmasterNodeId = 0; cnoStartNodes = 0; - for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - ptrAss(nodePtr, nodeRec); - nodePtr.p->cntrBlockref = calcNdbCntrBlockRef(nodePtr.i); - nodePtr.p->state = ZREMOVE; - nodePtr.p->dynamicId = 0; - nodePtr.p->votes = 0; /* USED BY MASTER */ - nodePtr.p->voter = ZFALSE; /* USED BY MASTER */ - nodePtr.p->masterReq = ZFALSE; /* USED BY MASTER */ - }//for + cnoWaitrep = 0; }//Ndbcntr::initData() -/*---------------------------------------------------------------------------*/ -// THE MASTER NODE HAS CHOOSEN THE NODES WHO WERE QUALIFIED TO -// PARTICIPATE IN A INITIALSTART OR SYSTEMRESTART. -// THIS SUBROTINE SENDS A CNTR_MASTERCONF TO THESE NODES -/*---------------------------------------------------------------------------*/ -void Ndbcntr::replyMasterconfToAll(Signal* signal) -{ - if (cnoStartNodes > 1) { - /** - * Construct a MasterConf signal - */ - - CntrMasterConf * const cntrMasterConf = - (CntrMasterConf *)&signal->theData[0]; - NodeBitmask::clear(cntrMasterConf->theNodes); - - cntrMasterConf->noStartNodes = cnoStartNodes; - - for(int i = 0; i<cnoStartNodes; i++) - NodeBitmask::set(cntrMasterConf->theNodes, cstartNodes[i]); - - /** - * Then distribute it to everyone but myself - */ - for(int i = 0; i<cnoStartNodes; i++){ - const NodeId nodeId = cstartNodes[i]; - if(nodeId != getOwnNodeId()){ - sendSignal(numberToRef(number(), nodeId), - GSN_CNTR_MASTERCONF, - signal, CntrMasterConf::SignalLength, JBB); - } - } - } -}//Ndbcntr::replyMasterconfToAll() /*---------------------------------------------------------------------------*/ /*RESET VARIABLES USED DURING THE START */ /*---------------------------------------------------------------------------*/ void Ndbcntr::resetStartVariables(Signal* signal) { - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - ptrAss(nodePtr, nodeRec); - nodePtr.p->votes = 0; - nodePtr.p->voter = ZFALSE; - nodePtr.p->masterReq = ZFALSE; - }//for - cnoVoters = 0; cnoStartNodes = 0; cnoWaitrep6 = cnoWaitrep7 = 0; }//Ndbcntr::resetStartVariables() -/*---------------------------------------------------------------------------*/ -// SENDER OF THIS SIGNAL HAS CHOOSEN A MASTER NODE AND SENDS A REQUEST -// TO THE MASTER_CANDIDATE AS AN VOTE FOR -// THE MASTER. THE SIGNAL ALSO INCLUDES VOTES FOR NODES WHICH SENDER -// THINKS SHOULD PARTICIPATE IN THE START. -// INPUT: CNO_START_NODES -// CSTART_NODES -/*---------------------------------------------------------------------------*/ -void Ndbcntr::sendCntrMasterreq(Signal* signal) -{ - nodePtr.i = cmasterCandidateId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); -/*--------------------------------------------------------------*/ -/* O:INITIALSTART, 1:SYSTEMRESTART (ELECTION OF MASTER) */ -/* 2:NODE RESTART (SENDER NODE NOT INCLUDED IN CSTART_NODES) */ -/*--------------------------------------------------------------*/ - CntrMasterReq * const cntrMasterReq = (CntrMasterReq*)&signal->theData[0]; - NodeBitmask::clear(cntrMasterReq->theNodes); - for (int i = 0; i < cnoStartNodes; i++){ - jam(); - UintR Tnode = cstartNodes[i]; - arrGuard(Tnode, MAX_NDB_NODES); - NodeBitmask::set(cntrMasterReq->theNodes, Tnode); - }//for - cntrMasterReq->userBlockRef = cownBlockref; - cntrMasterReq->userNodeId = getOwnNodeId(); - cntrMasterReq->typeOfStart = ctypeOfStart; - cntrMasterReq->noRestartNodes = cnoStartNodes; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREQ, - signal, CntrMasterReq::SignalLength, JBB); -}//Ndbcntr::sendCntrMasterreq() /*---------------------------------------------------------------------------*/ // SEND THE SIGNAL @@ -2745,25 +1835,24 @@ void Ndbcntr::sendCntrMasterreq(Signal* signal) /*---------------------------------------------------------------------------*/ void Ndbcntr::sendNdbSttor(Signal* signal) { - CfgBlockRecPtr cfgBlockPtr; NdbBlocksRecPtr ndbBlocksPtr; ndbBlocksPtr.i = cndbBlocksCount; ptrCheckGuard(ndbBlocksPtr, ZSIZE_NDB_BLOCKS_REC, ndbBlocksRec); - cfgBlockPtr.i = cinternalStartphase; - ptrCheckGuard(cfgBlockPtr, ZSIZE_CFG_BLOCK_REC, cfgBlockRec); + NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend(); - req->senderRef = cownBlockref; + req->senderRef = reference(); req->nodeId = getOwnNodeId(); req->internalStartPhase = cinternalStartphase; req->typeOfStart = ctypeOfStart; req->masterNodeId = cmasterNodeId; for (int i = 0; i < 16; i++) { - req->config[i] = cfgBlockPtr.p->cfgData[i]; + // Garbage + req->config[i] = 0x88776655; + //cfgBlockPtr.p->cfgData[i]; } - //#define TRACE_STTOR //#define MAX_STARTPHASE 2 #ifdef TRACE_STTOR ndbout_c("sending NDB_STTOR(%d) to %s", @@ -2779,9 +1868,6 @@ void Ndbcntr::sendNdbSttor(Signal* signal) /*---------------------------------------------------------------------------*/ void Ndbcntr::sendSttorry(Signal* signal) { - signal->theData[0] = csignalKey; - signal->theData[1] = 3; - signal->theData[2] = 2; signal->theData[3] = ZSTART_PHASE_1; signal->theData[4] = ZSTART_PHASE_2; signal->theData[5] = ZSTART_PHASE_3; @@ -2801,9 +1887,8 @@ Ndbcntr::execDUMP_STATE_ORD(Signal* signal) DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0]; if(signal->theData[0] == 13){ infoEvent("Cntr: cstartPhase = %d, cinternalStartphase = %d, block = %d", - cstartPhase, cinternalStartphase, cndbBlocksCount); - infoEvent("Cntr: cmasterNodeId = %d, cmasterCandidateId = %d", - cmasterNodeId, cmasterCandidateId); + cstartPhase, cinternalStartphase, cndbBlocksCount); + infoEvent("Cntr: cmasterNodeId = %d", cmasterNodeId); } if (dumpState->args[0] == DumpStateOrd::NdbcntrTestStopOnError){ @@ -2823,6 +1908,7 @@ Ndbcntr::execDUMP_STATE_ORD(Signal* signal) }//Ndbcntr::execDUMP_STATE_ORD() void Ndbcntr::execSET_VAR_REQ(Signal* signal) { +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); @@ -2835,6 +1921,7 @@ void Ndbcntr::execSET_VAR_REQ(Signal* signal) { default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); }// switch +#endif }//Ndbcntr::execSET_VAR_REQ() void Ndbcntr::updateNodeState(Signal* signal, const NodeState& newState) const{ @@ -2947,7 +2034,7 @@ Ndbcntr::execSTOP_REQ(Signal* signal){ } updateNodeState(signal, newState); signal->theData[0] = ZSHUTDOWN; - sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 1); + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1); } void @@ -2991,14 +2078,9 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){ /** * Check if I can survive me stopping */ - NodeBitmask ndbMask; ndbMask.clear(); - NodeRecPtr aPtr; - for(aPtr.i = 1; aPtr.i < MAX_NDB_NODES; aPtr.i++){ - ptrAss(aPtr, cntr.nodeRec); - if(aPtr.i != cntr.getOwnNodeId() && aPtr.p->state == ZRUN){ - ndbMask.set(aPtr.i); - } - } + NodeBitmask ndbMask; + ndbMask.assign(cntr.c_startedNodes); + ndbMask.clear(cntr.getOwnNodeId()); CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0]; sd->blockRef = cntr.reference(); @@ -3194,7 +2276,7 @@ void Ndbcntr::execSTOP_ME_CONF(Signal* signal){ c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond(); signal->theData[0] = ZSHUTDOWN; - sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 1); + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1); } void @@ -3255,6 +2337,11 @@ void Ndbcntr::execSTTORRY(Signal* signal){ c_missra.execSTTORRY(signal); } +void Ndbcntr::execREAD_CONFIG_CONF(Signal* signal){ + jamEntry(); + c_missra.execREAD_CONFIG_CONF(signal); +} + void Ndbcntr::execSTART_ORD(Signal* signal){ jamEntry(); ndbrequire(NO_OF_BLOCKS == ALL_BLOCKS_SZ); @@ -3299,7 +2386,38 @@ void Ndbcntr::Missra::execSTART_ORD(Signal* signal){ signal->theData[0] = EventReport::NDBStartStarted; signal->theData[1] = NDB_VERSION; cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + + currentBlockIndex = 0; + sendNextREAD_CONFIG_REQ(signal); +} + +void Ndbcntr::Missra::sendNextREAD_CONFIG_REQ(Signal* signal){ + + if(currentBlockIndex < ALL_BLOCKS_SZ){ + jam(); + + ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtrSend(); + req->senderData = 0; + req->senderRef = cntr.reference(); + req->noOfParameters = 0; + + const BlockReference ref = ALL_BLOCKS[currentBlockIndex].Ref; + +#if 0 + ndbout_c("sending READ_CONFIG_REQ to %s(ref=%x index=%d)", + getBlockName( refToBlock(ref)), + ref, + currentBlockIndex); +#endif + + cntr.sendSignal(ref, GSN_READ_CONFIG_REQ, signal, + ReadConfigReq::SignalLength, JBB); + return; + } + /** + * Finished... + */ currentStartPhase = 0; for(Uint32 i = 0; i<NO_OF_BLOCKS; i++){ if(ALL_BLOCKS[i].NextSP < currentStartPhase) @@ -3307,10 +2425,19 @@ void Ndbcntr::Missra::execSTART_ORD(Signal* signal){ } currentBlockIndex = 0; - sendNextSTTOR(signal); } +void Ndbcntr::Missra::execREAD_CONFIG_CONF(Signal* signal){ + const ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtr(); + + const Uint32 ref = conf->senderRef; + ndbrequire(refToBlock(ALL_BLOCKS[currentBlockIndex].Ref) == refToBlock(ref)); + + currentBlockIndex++; + sendNextREAD_CONFIG_REQ(signal); +} + void Ndbcntr::Missra::execSTTORRY(Signal* signal){ const BlockReference ref = signal->senderBlockRef(); ndbrequire(refToBlock(ref) == refToBlock(ALL_BLOCKS[currentBlockIndex].Ref)); @@ -3365,8 +2492,8 @@ void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){ currentBlockIndex); #endif - cntr.sendSignal(ref, GSN_STTOR, - signal, 8, JBB); + cntr.sendSignal(ref, GSN_STTOR, signal, 8, JBB); + return; } } @@ -3391,4 +2518,136 @@ void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){ NodeState newState(NodeState::SL_STARTED); cntr.updateNodeState(signal, newState); + + /** + * Backward + */ + UpgradeStartup::sendCmAppChg(cntr, signal, 3); //RUN + + NdbNodeBitmask nodes = cntr.c_clusterNodes; + Uint32 node = 0; + while((node = nodes.find(node+1)) != NdbNodeBitmask::NotFound){ + if(cntr.getNodeInfo(node).m_version < MAKE_VERSION(3,5,0)){ + nodes.clear(node); + } + } + + NodeReceiverGroup rg(NDBCNTR, nodes); + signal->theData[0] = cntr.getOwnNodeId(); + cntr.sendSignal(rg, GSN_CNTR_START_REP, signal, 1, JBB); +} + +/** + * Backward compatible code + */ +void +UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){ + + signal->theData[0] = startLevel; + signal->theData[1] = cntr.getOwnNodeId(); + signal->theData[2] = 3 | ('N' << 8); + signal->theData[3] = 'D' | ('B' << 8); + signal->theData[4] = 0; + signal->theData[5] = 0; + signal->theData[6] = 0; + signal->theData[7] = 0; + signal->theData[8] = 0; + signal->theData[9] = 0; + signal->theData[10] = 0; + signal->theData[11] = 0; + + NdbNodeBitmask nodes = cntr.c_clusterNodes; + nodes.clear(cntr.getOwnNodeId()); + Uint32 node = 0; + while((node = nodes.find(node+1)) != NdbNodeBitmask::NotFound){ + if(cntr.getNodeInfo(node).m_version < MAKE_VERSION(3,5,0)){ + cntr.sendSignal(cntr.calcQmgrBlockRef(node), + GSN_CM_APPCHG, signal, 12, JBB); + } else { + cntr.c_startedNodes.set(node); // Fake started + } + } +} + +void +UpgradeStartup::execCM_APPCHG(SimulatedBlock & block, Signal* signal){ + Uint32 state = signal->theData[0]; + Uint32 nodeId = signal->theData[1]; + if(block.number() == QMGR){ + Ndbcntr& cntr = * (Ndbcntr*)globalData.getBlock(CNTR); + switch(state){ + case 0: // ZADD + break; + case 2: // ZSTART + break; + case 3: // ZRUN{ + cntr.c_startedNodes.set(nodeId); + + Uint32 recv = cntr.c_startedNodes.count(); + Uint32 cnt = cntr.c_clusterNodes.count(); + if(recv + 1 == cnt){ //+1 == own node + /** + * Check master + */ + sendCntrMasterReq(cntr, signal, 0); + } + return; + } + } + block.progError(0,0); +} + +void +UpgradeStartup::sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n){ + Uint32 node = cntr.c_startedNodes.find(n); + if(node != NdbNodeBitmask::NotFound && + (node == cntr.getOwnNodeId() || + cntr.getNodeInfo(node).m_version >= MAKE_VERSION(3,5,0))){ + node = cntr.c_startedNodes.find(node+1); + } + + if(node == NdbNodeBitmask::NotFound){ + cntr.progError(0,0); + } + + CntrMasterReq * const cntrMasterReq = (CntrMasterReq*)&signal->theData[0]; + cntr.c_clusterNodes.copyto(NdbNodeBitmask::Size, cntrMasterReq->theNodes); + NdbNodeBitmask::clear(cntrMasterReq->theNodes, cntr.getOwnNodeId()); + cntrMasterReq->userBlockRef = 0; + cntrMasterReq->userNodeId = cntr.getOwnNodeId(); + cntrMasterReq->typeOfStart = NodeState::ST_INITIAL_NODE_RESTART; + cntrMasterReq->noRestartNodes = cntr.c_clusterNodes.count() - 1; + cntr.sendSignal(cntr.calcNdbCntrBlockRef(node), GSN_CNTR_MASTERREQ, + signal, CntrMasterReq::SignalLength, JBB); +} + +void +UpgradeStartup::execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal){ + Uint32 gsn = signal->header.theVerId_signalNumber; + Uint32 node = refToNode(signal->getSendersBlockRef()); + if(block.number() == CNTR){ + Ndbcntr& cntr = (Ndbcntr&)block; + switch(gsn){ + case GSN_CNTR_MASTERREF: + sendCntrMasterReq(cntr, signal, node + 1); + return; + break; + case GSN_CNTR_MASTERCONF:{ + CntrStartConf* conf = (CntrStartConf*)signal->getDataPtrSend(); + conf->startGci = 0; + conf->masterNodeId = node; + conf->noStartNodes = 1; + conf->startType = NodeState::ST_INITIAL_NODE_RESTART; + NodeBitmask mask; + mask.clear(); + mask.copyto(NdbNodeBitmask::Size, conf->startedNodes); + mask.clear(); + mask.set(cntr.getOwnNodeId()); + mask.copyto(NdbNodeBitmask::Size, conf->startingNodes); + cntr.execCNTR_START_CONF(signal); + return; + } + } + } + block.progError(0,0); } diff --git a/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp b/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp index 36322ffad1e..c763d3b4786 100644 --- a/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp +++ b/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp @@ -60,10 +60,11 @@ Ndbfs::Ndbfs(const Configuration & conf) : theFileSystemPath = conf.fileSystemPath(); theRequestPool = new Pool<Request>; - const Properties * p = conf.getOwnProperties(); + const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator(); ndbrequire(p != 0); - ndbrequire(p->get("MaxNoOfOpenFiles", &m_maxFiles)); + m_maxOpenedFiles = 40; + //ndb_mgm_get_int_parameter(p, CFG_DB_MAX_OPEN_FILES, &m_maxFiles); // Create idle AsyncFiles Uint32 noIdleFiles = 16; diff --git a/ndb/src/kernel/blocks/qmgr/Qmgr.hpp b/ndb/src/kernel/blocks/qmgr/Qmgr.hpp index 7d2abd34ebe..0ff7cea6d9f 100644 --- a/ndb/src/kernel/blocks/qmgr/Qmgr.hpp +++ b/ndb/src/kernel/blocks/qmgr/Qmgr.hpp @@ -22,6 +22,8 @@ #include <NdbTick.h> #include <SimulatedBlock.hpp> #include <NodeBitmask.hpp> +#include <SignalCounter.hpp> + #include <signaldata/EventReport.hpp> #include <signaldata/ArbitSignalData.hpp> #include <signaldata/CmRegSignalData.hpp> @@ -33,24 +35,10 @@ #ifdef QMGR_C #define NO_REG_APP 1 -/* Boolean flags --------------------------------*/ -#define ZNULL 0xfffe /* Delay values, ms -----------------------------*/ #define ZDELAY_REGREQ 1000 -/* Phase of QMGR node ------------------------*/ -#define ZINIT 1 /* All nodes start in phase INIT */ -#define ZWAITING 2 /* Node is connecting to cluster */ -#define ZRUNNING 3 /* Node is running in the cluster */ -#define ZBLOCKED 4 /* Node is blocked from the cluster */ -#define ZWAIT_PRESIDENT 5 -#define ZDEAD 6 -#define ZAPI_ACTIVE 7 /* API IS RUNNING IN NODE */ -#define ZFAIL_CLOSING 8 /* API/NDB IS DISCONNECTING */ -#define ZPREPARE_FAIL 9 /* PREPARATION FOR FAILURE */ -#define ZAPI_INACTIVE 10 /* Inactive API */ - /* Type of refuse in CM_NODEINFOREF -------------*/ #define ZNOT_RUNNING 0 @@ -100,18 +88,40 @@ public: WAITING_FOR_FAILCONF2 = 2, WAITING_FOR_NDB_FAILCONF = 3 }; + + enum Phase { + ZINIT = 1, /* All nodes start in phase INIT */ + ZSTARTING = 2, /* Node is connecting to cluster */ + ZRUNNING = 3, /* Node is running in the cluster */ + ZPREPARE_FAIL = 4, /* PREPARATION FOR FAILURE */ + ZFAIL_CLOSING = 5, /* API/NDB IS DISCONNECTING */ + ZAPI_ACTIVE = 6, /* API IS RUNNING IN NODE */ + ZAPI_INACTIVE = 7 /* Inactive API */ + }; + + struct StartRecord { + void reset(){ m_startKey++; m_startNode = 0;} + Uint32 m_startKey; + Uint32 m_startNode; + Uint64 m_startTimeout; + + Uint32 m_gsn; + SignalCounter m_nodes; + } c_start; + + NdbNodeBitmask c_definedNodes; // DB nodes in config + NdbNodeBitmask c_clusterNodes; // DB nodes in cluster + NodeBitmask c_connectedNodes; // All kinds of connected nodes + Uint32 c_maxDynamicId; // Records struct NodeRec { UintR ndynamicId; - UintR phase; + Phase phase; UintR alarmCount; - bool m_connected; QmgrState sendPrepFailReqStatus; QmgrState sendCommitFailReqStatus; - QmgrState sendCmAddPrepStatus; - QmgrState sendCmAddCommitStatus; QmgrState sendPresToStatus; FailState failState; BlockReference rcv[2]; // remember which failconf we have received @@ -122,18 +132,6 @@ public: typedef Ptr<NodeRec> NodeRecPtr; - struct RegApp { - NdbNodeBitmask m_runNodes; - char name[15 + 1]; - UintR noofapps; - UintR noofpending; - BlockReference blockref; - Uint16 version; - Uint16 activity; - }; - - typedef Ptr<RegApp> RegAppPtr; - enum ArbitState { ARBIT_NULL = 0, ARBIT_INIT = 1, // create new ticket @@ -191,7 +189,6 @@ private: void execCM_HEARTBEAT(Signal* signal); void execCM_ADD(Signal* signal); void execCM_ACKADD(Signal* signal); - void execCM_APPCHG(Signal* signal); void execCM_REGREQ(Signal* signal); void execCM_REGCONF(Signal* signal); void execCM_REGREF(Signal* signal); @@ -214,10 +211,6 @@ private: void execCONNECT_REP(Signal* signal); void execNDB_FAILCONF(Signal* signal); void execSTTOR(Signal* signal); - void execAPPL_REGREQ(Signal* signal); - void execAPPL_STARTREG(Signal* signal); - void execAPPL_RUN(Signal* signal); - void execCM_INIT(Signal* signal); void execCM_INFOCONF(Signal* signal); void execCLOSE_COMCONF(Signal* signal); void execAPI_REGREQ(Signal* signal); @@ -242,53 +235,31 @@ private: // Statement blocks void node_failed(Signal* signal, Uint16 aFailedNode); void checkStartInterface(Signal* signal); - void applchangerep(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion); - void cmappAdd(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion); - void cmappStart(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion); void failReport(Signal* signal, Uint16 aFailedNode, UintR aSendFailRep, FailRep::FailCause failCause); void findNeighbours(Signal* signal); Uint16 translateDynamicIdToNodeId(Signal* signal, UintR TdynamicId); - UintR getDynamicId(Signal* signal); + void initData(Signal* signal); - void prepareAdd(Signal* signal, Uint16 addNode); - void sendappchg(Signal* signal, UintR aRegApp, Uint16 aNode); void sendCloseComReq(Signal* signal, BlockReference TBRef, Uint16 TfailNo); void sendPrepFailReq(Signal* signal, Uint16 aNode); void sendApiFailReq(Signal* signal, Uint16 aFailedNode); void sendApiRegRef(Signal*, Uint32 ref, ApiRegRef::ErrorCode); // Generated statement blocks + void startphase1(Signal* signal); void electionWon(); void cmInfoconf010Lab(Signal* signal); void apiHbHandlingLab(Signal* signal); void timerHandlingLab(Signal* signal); void hbReceivedLab(Signal* signal); - void cmAdd010Lab(Signal* signal); - void cmAckadd010Lab(Signal* signal); - void cmAppchg010Lab(Signal* signal); void sendCmRegrefLab(Signal* signal, BlockReference ref, CmRegRef::ErrorCode); void systemErrorBecauseOtherNodeFailed(Signal* signal, NodeId); void systemErrorLab(Signal* signal, const char* message = NULL); - void cmRegref010Lab(Signal* signal); - void cmNodeinforeq010Lab(Signal* signal); - void cmNodeinfoconf010Lab(Signal* signal); void prepFailReqLab(Signal* signal); void prepFailConfLab(Signal* signal); void prepFailRefLab(Signal* signal); @@ -300,13 +271,10 @@ private: void presToConfLab(Signal* signal); void sendSttorryLab(Signal* signal); void sttor020Lab(Signal* signal); - void applRegreq010Lab(Signal* signal); - void applStartreg010Lab(Signal* signal); - void applRun010Lab(Signal* signal); - void cmInit010Lab(Signal* signal); void closeComConfLab(Signal* signal); void apiRegReqLab(Signal* signal); - void regreqTimelimitLab(Signal* signal, UintR callTime); + void regreqTimeLimitLab(Signal* signal); + void regreqTimeMasterLimitLab(Signal* signal); void cmRegreq010Lab(Signal* signal); void cmRegconf010Lab(Signal* signal); void sttor010Lab(Signal* signal); @@ -347,6 +315,12 @@ private: bool checkAPIVersion(NodeId, Uint32 nodeVersion, Uint32 ownVersion) const; bool checkNDBVersion(NodeId, Uint32 nodeVersion, Uint32 ownVersion) const; + void cmAddPrepare(Signal* signal, NodeRecPtr nodePtr, const NodeRec* self); + void sendCmAckAdd(Signal *, Uint32 nodeId, CmAdd::RequestType); + void joinedCluster(Signal* signal, NodeRecPtr nodePtr); + void sendCmRegReq(Signal * signal, Uint32 nodeId); + void sendCmNodeInfoReq(Signal* signal, Uint32 nodeId, const NodeRec * self); + private: void sendPrepFailReqRef(Signal* signal, Uint32 dstBlockRef, @@ -364,7 +338,6 @@ private: /**** Common stored variables ****/ NodeRec *nodeRec; - RegApp * regApp; ArbitRec arbitRec; /* Block references ------------------------------*/ @@ -377,27 +350,17 @@ private: /* Counters --------------------------------------*/ Uint16 cnoOfNodes; /* Static node counter */ - Uint16 cclustersize; /* Currently not used */ /* Status flags ----------------------------------*/ - Uint16 cstartseq; /* Marks what startseq we are in according to - STTOR */ + Uint32 c_restartPartialTimeout; - Uint16 cpresidentBusy; /* Only used by the president, ZTRUE / ZFALSE */ - Uint16 cacceptRegreq; /* Used by president, ZTRUE / ZFALSE */ - Uint16 cwaitContinuebPhase1; - Uint16 cwaitContinuebPhase2; Uint16 creadyDistCom; - - UintR cstartNo; Uint16 c_regReqReqSent; Uint16 c_regReqReqRecv; Uint64 c_stopElectionTime; Uint16 cpresidentCandidate; Uint16 cdelayRegreq; Uint16 cpresidentAlive; - Uint16 csignalkey; - Uint16 cstartNode; Uint16 cnoFailedNodes; Uint16 cnoPrepFailedNodes; Uint16 cnoCommitFailedNodes; @@ -410,7 +373,6 @@ private: UintR cfailureNr; QmgrState ctoStatus; - UintR ccm_infoconfCounter; UintR cLqhTimeSignalCount; bool cHbSent; NDB_TICKS clatestTransactionCheck; @@ -421,68 +383,10 @@ private: class Timer hb_api_timer; - UintR cnodemask[NdbNodeBitmask::Size]; Uint16 cfailedNodes[MAX_NDB_NODES]; Uint16 cprepFailedNodes[MAX_NDB_NODES]; Uint16 ccommitFailedNodes[MAX_NDB_NODES]; - /***************************************************************************/ - /* RECORD NODE_REC: The NodeList contains information about all other nodes - * in the cluster. - * Member variables: - * NTYPE [ ZACTIVE, - * ZPASSIVE, Marks the level of activity the - * node will show in the cluster. - * ZLISTENER ] - * PHASE [ ZINIT, = Initial face, before node is added - * to cluster - * ZWAITING, = Node is added to the cluster and - * ready to run - * ZRUNNING, = Node is up and running. - * ZBLOCKED = Node is not in the cluster - * ZAPI_ACTIVE = Node has an active application - * ZFAIL_CLOSING = Node is disconnecting - * ZDEAD ] = Node has been declared as dead - * ALARM_COUNT No of times an alarm has been sent before it is - * acknowledged - ***************************************************************************/ - /************************************************************************* - * RECORD REG_APP: The REG_APP record is used to store information about - * each registered application running on the current node. - * Member variables: - * BLOCKREF Reference of application block to receive cluster - * signals - * PTR Not used today but may be used by appl. in future - * NAME Unique name of application, max 15 char. long - * SUBTYPE Provided as a mechanism for applications to have - * more than one type running in the same application - * ring. i.e. NDB & NDB-API - * VERSION Version no. of application. Two different versions - * will be handled as different applications. - * TYPE [ ZACTIVE, - * ZPASSIVE, - * ZLISTENER ] Type of member in the cluster - * ACTIVITY [ ZADD, Application has been registered on - * node. - * ZSTART, Application is ready to start - * running distributed. - * ZRUN, Application is running actively. - * ZDELETE ] Application is beeing removed from - * the node. - * HBDELAY Delay time for periodic intervalls. - * STATUS Heartbeat status, indicates if app is responding - * to HBREQ. - * RUNNODES() If value is ZTRUE -> app. is also running on the - * indexed node. - * NOOFAPPS No. of applications left to register themselves as - * ready to start, STATUS = ZSTART before we can send - * APPL_STARTCONF. - * NOOFPENDING No. of apps that have registered themselfs as ready - * to start before this app has. We need this since - * we set NOOFAPPS when we receive the local - * APPL_START. NOOFPENDING is subtracted from NOOFAPPS - * when NOOFAPPS is set. - **************************************************************************/ - }; + #endif diff --git a/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp b/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp index ffc1448548d..b0f1088779c 100644 --- a/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp +++ b/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp @@ -18,7 +18,6 @@ #define QMGR_C #include "Qmgr.hpp" -#include <Configuration.hpp> #define DEBUG(x) { ndbout << "Qmgr::" << x << endl; } @@ -29,10 +28,13 @@ void Qmgr::initData() // Records with constant sizes nodeRec = new NodeRec[MAX_NODES]; - regApp = new RegApp[NO_REG_APP]; - cclustersize = 0; cnoCommitFailedNodes = 0; + c_maxDynamicId = 0; + c_clusterNodes.clear(); + + Uint32 hbDBAPI = 500; + setHbApiDelay(hbDBAPI); }//Qmgr::initData() void Qmgr::initRecords() @@ -52,7 +54,6 @@ Qmgr::Qmgr(const class Configuration & conf) addRecSignal(GSN_CM_HEARTBEAT, &Qmgr::execCM_HEARTBEAT); addRecSignal(GSN_CM_ADD, &Qmgr::execCM_ADD); addRecSignal(GSN_CM_ACKADD, &Qmgr::execCM_ACKADD); - addRecSignal(GSN_CM_APPCHG, &Qmgr::execCM_APPCHG); addRecSignal(GSN_CM_REGREQ, &Qmgr::execCM_REGREQ); addRecSignal(GSN_CM_REGCONF, &Qmgr::execCM_REGCONF); addRecSignal(GSN_CM_REGREF, &Qmgr::execCM_REGREF); @@ -67,16 +68,11 @@ Qmgr::Qmgr(const class Configuration & conf) addRecSignal(GSN_FAIL_REP, &Qmgr::execFAIL_REP); addRecSignal(GSN_PRES_TOREQ, &Qmgr::execPRES_TOREQ); addRecSignal(GSN_PRES_TOCONF, &Qmgr::execPRES_TOCONF); - addRecSignal(GSN_CM_INFOCONF, &Qmgr::execCM_INFOCONF); // Received signals addRecSignal(GSN_CONNECT_REP, &Qmgr::execCONNECT_REP); addRecSignal(GSN_NDB_FAILCONF, &Qmgr::execNDB_FAILCONF); addRecSignal(GSN_STTOR, &Qmgr::execSTTOR); - addRecSignal(GSN_APPL_REGREQ, &Qmgr::execAPPL_REGREQ); - addRecSignal(GSN_APPL_STARTREG, &Qmgr::execAPPL_STARTREG); - addRecSignal(GSN_APPL_RUN, &Qmgr::execAPPL_RUN); - addRecSignal(GSN_CM_INIT, &Qmgr::execCM_INIT); addRecSignal(GSN_CLOSE_COMCONF, &Qmgr::execCLOSE_COMCONF); addRecSignal(GSN_API_REGREQ, &Qmgr::execAPI_REGREQ); addRecSignal(GSN_API_VERSION_REQ, &Qmgr::execAPI_VERSION_REQ); @@ -86,7 +82,6 @@ Qmgr::Qmgr(const class Configuration & conf) addRecSignal(GSN_SET_VAR_REQ, &Qmgr::execSET_VAR_REQ); // Arbitration signals - addRecSignal(GSN_ARBIT_CFG, &Qmgr::execARBIT_CFG); addRecSignal(GSN_ARBIT_PREPREQ, &Qmgr::execARBIT_PREPREQ); addRecSignal(GSN_ARBIT_PREPCONF, &Qmgr::execARBIT_PREPCONF); addRecSignal(GSN_ARBIT_PREPREF, &Qmgr::execARBIT_PREPREF); @@ -97,18 +92,11 @@ Qmgr::Qmgr(const class Configuration & conf) addRecSignal(GSN_ARBIT_STOPREP, &Qmgr::execARBIT_STOPREP); initData(); - - const ClusterConfiguration::ClusterData & clusterConf = - theConfiguration.clusterConfigurationData() ; - setHbDelay(clusterConf.ispValues[0][2]); //cmInit->heartbeatDbDb); - setHbApiDelay(clusterConf.ispValues[0][3]); //;cmInit->heartbeatDbApi); - setArbitTimeout(clusterConf.ispValues[0][5]); //cmInit->arbitTimeout); }//Qmgr::Qmgr() Qmgr::~Qmgr() { delete []nodeRec; - delete []regApp; }//Qmgr::~Qmgr() diff --git a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp index 0f82f8def6f..ac29614bc70 100644 --- a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp +++ b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp @@ -20,7 +20,6 @@ #include <pc.hpp> #include <NdbTick.h> #include <signaldata/EventReport.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/StartOrd.hpp> #include <signaldata/CmInit.hpp> #include <signaldata/CloseComReqConf.hpp> @@ -42,6 +41,20 @@ #include <NdbOut.hpp> #endif +//#define DEBUG_QMGR_START +#ifdef DEBUG_QMGR_START +#include <DebuggerNames.hpp> +#define DEBUG(x) ndbout << "QMGR " << __LINE__ << ": " << x << endl +#define DEBUG_START(gsn, node, msg) DEBUG(getSignalName(gsn) << " to: " << node << " - " << msg) +#define DEBUG_START2(gsn, rg, msg) { char nodes[255]; DEBUG(getSignalName(gsn) << " to: " << rg.m_nodes.getText(nodes) << " - " << msg); } +#define DEBUG_START3(signal, msg) DEBUG(getSignalName(signal->header.theVerId_signalNumber) << " from " << refToNode(signal->getSendersBlockRef()) << " - " << msg); +#else +#define DEBUG(x) +#define DEBUG_START(gsn, node, msg) +#define DEBUG_START2(gsn, rg, msg) +#define DEBUG_START3(signal, msg) +#endif + // Signal entries and statement blocks /* 4 P R O G R A M */ /*******************************/ @@ -72,32 +85,27 @@ void Qmgr::execCM_NODEINFOREF(Signal* signal) /*******************************/ void Qmgr::execCONTINUEB(Signal* signal) { - UintR tdata0; - UintR tcontinuebType; - jamEntry(); - tcontinuebType = signal->theData[0]; - tdata0 = signal->theData[1]; + const Uint32 tcontinuebType = signal->theData[0]; + const Uint32 tdata0 = signal->theData[1]; + const Uint32 tdata1 = signal->theData[2]; switch (tcontinuebType) { case ZREGREQ_TIMELIMIT: jam(); - if (cstartNo == tdata0) { + if (c_start.m_startKey != tdata0 || c_start.m_startNode != tdata1) { jam(); - regreqTimelimitLab(signal, signal->theData[2]); return; - } + }//if + regreqTimeLimitLab(signal); break; case ZREGREQ_MASTER_TIMELIMIT: jam(); - if (cstartNo != tdata0) { + if (c_start.m_startKey != tdata0 || c_start.m_startNode != tdata1) { jam(); return; }//if - if (cpresidentBusy != ZTRUE) { - jam(); - return; - }//if - failReportLab(signal, cstartNode, FailRep::ZSTART_IN_REGREQ); + //regreqMasterTimeLimitLab(signal); + failReportLab(signal, c_start.m_startNode, FailRep::ZSTART_IN_REGREQ); return; break; case ZTIMER_HANDLING: @@ -173,15 +181,23 @@ void Qmgr::execPRES_TOREQ(Signal* signal) void Qmgr::execSTTOR(Signal* signal) { jamEntry(); - cstartseq = signal->theData[1]; - csignalkey = signal->theData[6]; - if (cstartseq == 1) { - jam(); + + switch(signal->theData[1]){ + case 1: initData(signal); + startphase1(signal); + return; + case 7: + cactivateApiCheck = 1; + /** + * Start arbitration thread. This could be done as soon as + * we have all nodes (or a winning majority). + */ + if (cpresident == getOwnNodeId()) + handleArbitStart(signal); + break; } - setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION; - sendSttorryLab(signal); return; }//Qmgr::execSTTOR() @@ -191,85 +207,32 @@ void Qmgr::sendSttorryLab(Signal* signal) /****************************<*/ /*< STTORRY <*/ /****************************<*/ - signal->theData[0] = csignalkey; - signal->theData[1] = 3; - signal->theData[2] = 2; - signal->theData[3] = 2; + signal->theData[3] = 7; signal->theData[4] = 255; sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB); return; }//Qmgr::sendSttorryLab() -/* -4.2.2 CM_INIT */ -/**-------------------------------------------------------------------------- - * This signal is sent by the CLUSTERCTRL block. - * It initiates the QMGR and provides needed info about the - * cluster configuration (read from file). - * - * The signal starts all QMGR functions. - * It is possible to register applications before this but the QMGR will - * not be active before the registration face is complete. - * - * The CM_INIT will result in a one CM_NODEINFOREQ for each ndb node. - * We will also send a CONTINUEB to ourselves as a timelimit. - * If anyone sends a REF, CONF or a ( REQ with a lower NODENO than us ) during - * this time, we are not the president . - *--------------------------------------------------------------------------*/ -/*******************************/ -/* CM_INIT */ -/*******************************/ -void Qmgr::execCM_INIT(Signal* signal) +void Qmgr::startphase1(Signal* signal) { jamEntry(); - CmInit * const cmInit = (CmInit *)&signal->theData[0]; - - for(unsigned int i = 0; i<NdbNodeBitmask::Size; i++) - cnodemask[i] = cmInit->allNdbNodes[i]; - - cnoOfNodes = 0; - setHbDelay(cmInit->heartbeatDbDb); - setHbApiDelay(cmInit->heartbeatDbApi); - setArbitTimeout(cmInit->arbitTimeout); - arbitRec.state = ARBIT_NULL; // start state for all nodes - arbitRec.apiMask[0].clear(); // prepare for ARBIT_CFG NodeRecPtr nodePtr; - for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (NdbNodeBitmask::get(cnodemask, nodePtr.i)) { - jam(); - - nodePtr.p->blockRef = calcQmgrBlockRef(nodePtr.i); - nodePtr.p->phase = ZINIT; /* Not added to cluster */ - cnoOfNodes = cnoOfNodes + 1; /* Should never be changed after this loop. */ - ndbrequire(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB); - } else { - jam(); - nodePtr.p->phase = ZBLOCKED; - }//if - }//for - for (nodePtr.i = MAX_NDB_NODES; nodePtr.i < MAX_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - nodePtr.p->phase = ZBLOCKED; - }//for - nodePtr.i = getOwnNodeId(); ptrAss(nodePtr, nodeRec); - nodePtr.p->phase = ZINIT; - nodePtr.p->m_connected = true; + nodePtr.p->phase = ZSTARTING; + nodePtr.p->blockRef = reference(); + c_connectedNodes.set(nodePtr.i); - /****************************<*/ - /*< CM_INFOREQ <*/ - /****************************<*/ - signal->theData[0] = reference(); - signal->theData[1] = getOwnNodeId(); - sendSignal(CMVMI_REF, GSN_CM_INFOREQ, signal, 2, JBB); + signal->theData[0] = 0; // no answer + signal->theData[1] = 0; // no id + signal->theData[2] = NodeInfo::DB; + sendSignal(CMVMI_REF, GSN_OPEN_COMREQ, signal, 3, JBB); + + execCM_INFOCONF(signal); return; -}//Qmgr::execCM_INIT() +} void Qmgr::setHbDelay(UintR aHbDelay) { @@ -293,11 +256,46 @@ void Qmgr::setArbitTimeout(UintR aArbitTimeout) void Qmgr::execCONNECT_REP(Signal* signal) { - NodeRecPtr connectNodePtr; - connectNodePtr.i = signal->theData[0]; - ptrCheckGuard(connectNodePtr, MAX_NODES, nodeRec); - connectNodePtr.p->m_connected = true; + const Uint32 nodeId = signal->theData[0]; + c_connectedNodes.set(nodeId); + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrCheckGuard(nodePtr, MAX_NODES, nodeRec); + switch(nodePtr.p->phase){ + case ZSTARTING: + jam(); + break; + case ZRUNNING: + case ZPREPARE_FAIL: + case ZFAIL_CLOSING: + jam(); + return; + case ZINIT: + ndbrequire(false); + case ZAPI_ACTIVE: + case ZAPI_INACTIVE: + return; + } + + if(!c_start.m_nodes.isWaitingFor(nodeId)){ + jam(); + return; + } + + switch(c_start.m_gsn){ + case GSN_CM_REGREQ: + jam(); + sendCmRegReq(signal, nodeId); + return; + case GSN_CM_NODEINFOREQ:{ + jam(); + sendCmNodeInfoReq(signal, nodeId, nodePtr.p); + return; + } + default: + return; + } return; }//Qmgr::execCONNECT_REP() @@ -310,25 +308,22 @@ void Qmgr::execCM_INFOCONF(Signal* signal) cpresidentCandidate = getOwnNodeId(); cpresidentAlive = ZFALSE; c_stopElectionTime = NdbTick_CurrentMillisecond(); - c_stopElectionTime += 30000; // 30s + c_stopElectionTime += c_restartPartialTimeout; cmInfoconf010Lab(signal); -#if 0 - /*****************************************************/ - /* Allow the CLUSTER CONTROL to send STTORRY */ - /* CM_RUN */ - /* so we can receive APPL_REGREQ from applications. */ - /*****************************************************/ - signal->theData[0] = 0; - sendSignal(CMVMI_REF, GSN_CM_RUN, signal, 1, JBB); -#endif return; }//Qmgr::execCM_INFOCONF() void Qmgr::cmInfoconf010Lab(Signal* signal) { + c_start.m_startKey = 0; + c_start.m_startNode = getOwnNodeId(); + c_start.m_nodes.clearWaitingFor(); + c_start.m_gsn = GSN_CM_REGREQ; + NodeRecPtr nodePtr; c_regReqReqSent = c_regReqReqRecv = 0; + cnoOfNodes = 0; for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { jam(); ptrAss(nodePtr, nodeRec); @@ -336,19 +331,15 @@ void Qmgr::cmInfoconf010Lab(Signal* signal) if(getNodeInfo(nodePtr.i).getType() != NodeInfo::DB) continue; - if(!nodePtr.p->m_connected) + c_start.m_nodes.setWaitingFor(nodePtr.i); + cnoOfNodes++; + + if(!c_connectedNodes.get(nodePtr.i)) continue; - c_regReqReqSent++; - CmRegReq * const cmRegReq = (CmRegReq *)&signal->theData[0]; - cmRegReq->blockRef = reference(); - cmRegReq->nodeId = getOwnNodeId(); - cmRegReq->version = NDB_VERSION; - sendSignal(nodePtr.p->blockRef, GSN_CM_REGREQ, signal, - CmRegReq::SignalLength, JBB); + sendCmRegReq(signal, nodePtr.i); } - cstartNo = cstartNo + 1; - + //---------------------------------------- /* Wait for a while. When it returns */ /* we will check if we got any CM_REGREF*/ @@ -356,14 +347,26 @@ void Qmgr::cmInfoconf010Lab(Signal* signal) /* own). */ //---------------------------------------- signal->theData[0] = ZREGREQ_TIMELIMIT; - signal->theData[1] = cstartNo; - signal->theData[2] = 0; - sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 3 * cdelayRegreq, 3); - cwaitContinuebPhase1 = ZTRUE; + signal->theData[1] = c_start.m_startKey; + signal->theData[2] = c_start.m_startNode; + sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 3000, 3); + creadyDistCom = ZTRUE; return; }//Qmgr::cmInfoconf010Lab() +void +Qmgr::sendCmRegReq(Signal * signal, Uint32 nodeId){ + c_regReqReqSent++; + CmRegReq * const cmRegReq = (CmRegReq *)&signal->theData[0]; + cmRegReq->blockRef = reference(); + cmRegReq->nodeId = getOwnNodeId(); + cmRegReq->version = NDB_VERSION; + const Uint32 ref = calcQmgrBlockRef(nodeId); + sendSignal(ref, GSN_CM_REGREQ, signal, CmRegReq::SignalLength, JBB); + DEBUG_START(GSN_CM_REGREQ, nodeId, ""); +} + /* 4.4.11 CM_REGREQ */ /**-------------------------------------------------------------------------- @@ -403,6 +406,8 @@ void Qmgr::cmInfoconf010Lab(Signal* signal) /*******************************/ void Qmgr::execCM_REGREQ(Signal* signal) { + DEBUG_START3(signal, ""); + NodeRecPtr addNodePtr; jamEntry(); @@ -451,27 +456,15 @@ void Qmgr::execCM_REGREQ(Signal* signal) return; }//if - if (cpresidentBusy == ZTRUE) { + if (c_start.m_startNode != 0){ jam(); /** - * President busy by adding another node + * President busy by adding another node */ sendCmRegrefLab(signal, Tblockref, CmRegRef::ZBUSY_PRESIDENT); return; }//if - if (cacceptRegreq == ZFALSE && - getNodeState().startLevel != NodeState::SL_STARTING) { - jam(); - /** - * These checks are really confusing! - * The variables that is being checked are probably not - * set in the correct places. - */ - sendCmRegrefLab(signal, Tblockref, CmRegRef::ZBUSY); - return; - }//if - if (ctoStatus == Q_ACTIVE) { jam(); /** @@ -481,7 +474,7 @@ void Qmgr::execCM_REGREQ(Signal* signal) return; }//if - if (addNodePtr.p->phase == ZBLOCKED) { + if (getNodeInfo(addNodePtr.i).m_type != NodeInfo::DB) { jam(); /** * The new node is not in config file @@ -489,9 +482,11 @@ void Qmgr::execCM_REGREQ(Signal* signal) sendCmRegrefLab(signal, Tblockref, CmRegRef::ZNOT_IN_CFG); return; } - - if (addNodePtr.p->phase != ZINIT) { + + Phase phase = addNodePtr.p->phase; + if (phase != ZINIT){ jam(); + DEBUG("phase = " << phase); sendCmRegrefLab(signal, Tblockref, CmRegRef::ZNOT_DEAD); return; }//if @@ -506,45 +501,56 @@ void Qmgr::execCM_REGREQ(Signal* signal) * THE SIGNAL ARRIVES. IF IT HAS CHANGED THEN WE SIMPLY IGNORE * THE TIMED SIGNAL. */ - cpresidentBusy = ZTRUE; /** - * Indicates that we are busy with node start/restart and do - * not accept another start until this node is up and running - * (cpresidentBusy is released a little too early to use for this - * purpose). + * Update start record */ - cacceptRegreq = ZFALSE; - cstartNo = cstartNo + 1; - cstartNode = addNodePtr.i; - signal->theData[0] = ZREGREQ_MASTER_TIMELIMIT; - signal->theData[1] = cstartNo; - sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 30000, 2); - UintR TdynId = getDynamicId(signal); /* <- CDYNAMIC_ID */ - prepareAdd(signal, addNodePtr.i); - setNodeInfo(addNodePtr.i).m_version = startingVersion; - + c_start.m_startKey++; + c_start.m_startNode = addNodePtr.i; + /** - * Send "prepare for adding a new node" to all - * running nodes in cluster + the new node. - * Give permission to the new node to join the - * cluster + * Assign dynamic id */ - /*******************************/ - /*< CM_REGCONF <*/ - /*******************************/ + UintR TdynId = ++c_maxDynamicId; + setNodeInfo(addNodePtr.i).m_version = startingVersion; + addNodePtr.p->ndynamicId = TdynId; + /** + * Reply with CM_REGCONF + */ CmRegConf * const cmRegConf = (CmRegConf *)&signal->theData[0]; - cmRegConf->presidentBlockRef = reference(); cmRegConf->presidentNodeId = getOwnNodeId(); cmRegConf->presidentVersion = getNodeInfo(getOwnNodeId()).m_version; cmRegConf->dynamicId = TdynId; - for(unsigned int i = 0; i<NdbNodeBitmask::Size; i++) - cmRegConf->allNdbNodes[i] = cnodemask[i]; - + c_clusterNodes.copyto(NdbNodeBitmask::Size, cmRegConf->allNdbNodes); sendSignal(Tblockref, GSN_CM_REGCONF, signal, CmRegConf::SignalLength, JBB); + DEBUG_START(GSN_CM_REGCONF, refToNode(Tblockref), ""); + + /** + * Send CmAdd to all nodes (including starting) + */ + c_start.m_nodes = c_clusterNodes; + c_start.m_nodes.setWaitingFor(addNodePtr.i); + c_start.m_gsn = GSN_CM_ADD; + + NodeReceiverGroup rg(QMGR, c_start.m_nodes); + CmAdd * const cmAdd = (CmAdd*)signal->getDataPtrSend(); + cmAdd->requestType = CmAdd::Prepare; + cmAdd->startingNodeId = addNodePtr.i; + cmAdd->startingVersion = startingVersion; + sendSignal(rg, GSN_CM_ADD, signal, CmAdd::SignalLength, JBA); + DEBUG_START2(GSN_CM_ADD, rg, "Prepare"); + + /** + * Set timer + */ + return; + signal->theData[0] = ZREGREQ_MASTER_TIMELIMIT; + signal->theData[1] = c_start.m_startKey; + sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 30000, 2); + return; }//Qmgr::execCM_REGREQ() @@ -555,9 +561,10 @@ void Qmgr::sendCmRegrefLab(Signal* signal, BlockReference TBRef, ref->blockRef = reference(); ref->nodeId = getOwnNodeId(); ref->errorCode = Terror; - ref->presidentCandidate = cpresidentCandidate; + ref->presidentCandidate = (cpresident == ZNIL ? cpresidentCandidate : cpresident); sendSignal(TBRef, GSN_CM_REGREF, signal, CmRegRef::SignalLength, JBB); + DEBUG_START(GSN_CM_REGREF, refToNode(TBRef), ""); return; }//Qmgr::sendCmRegrefLab() @@ -575,14 +582,13 @@ void Qmgr::sendCmRegrefLab(Signal* signal, BlockReference TBRef, /*******************************/ void Qmgr::execCM_REGCONF(Signal* signal) { + DEBUG_START3(signal, ""); + NodeRecPtr myNodePtr; NodeRecPtr nodePtr; - NodeRecPtr presidentNodePtr; jamEntry(); - CmRegConf * const cmRegConf = (CmRegConf *)&signal->theData[0]; - cwaitContinuebPhase1 = ZFALSE; - cwaitContinuebPhase2 = ZTRUE; + const CmRegConf * const cmRegConf = (CmRegConf *)&signal->theData[0]; if (!ndbCompatible_ndb_ndb(NDB_VERSION, cmRegConf->presidentVersion)) { jam(); @@ -592,46 +598,12 @@ void Qmgr::execCM_REGCONF(Signal* signal) return; } - /** - * Check if all necessary connections has been established - */ - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - if (NodeBitmask::get(cmRegConf->allNdbNodes, nodePtr.i) == true){ - jam(); - ptrAss(nodePtr, nodeRec); - if (!nodePtr.p->m_connected) { - jam(); - - /** - * Missing connection - */ -#ifdef VM_TRACE - ndbout_c("Resending CM_REGCONF, node %d is not connected", nodePtr.i); - ndbout << " presidentBlockRef="<<cmRegConf->presidentBlockRef<<endl - << " presidentNodeId="<<cmRegConf->presidentNodeId<<endl - << " presidentVersion="<<cmRegConf->presidentVersion<<endl - << " dynamicId="<<cmRegConf->dynamicId<<endl; -#endif - for(unsigned int i = 0; i<NdbNodeBitmask::Size; i++) { - jam(); -#ifdef VM_TRACE - ndbout << " " << i << ": " - << hex << cmRegConf->allNdbNodes[i]<<endl; -#endif - } - sendSignalWithDelay(reference(), GSN_CM_REGCONF, signal, 100, - signal->getLength()); - return; - } - } - } - + cpdistref = cmRegConf->presidentBlockRef; cpresident = cmRegConf->presidentNodeId; UintR TdynamicId = cmRegConf->dynamicId; - for(unsigned int i = 0; i<NdbNodeBitmask::Size; i++) - cnodemask[i] = cmRegConf->allNdbNodes[i]; + c_maxDynamicId = TdynamicId; + c_clusterNodes.assign(NdbNodeBitmask::Size, cmRegConf->allNdbNodes); /*--------------------------------------------------------------*/ // Send this as an EVENT REPORT to inform about hearing about @@ -646,67 +618,40 @@ void Qmgr::execCM_REGCONF(Signal* signal) myNodePtr.i = getOwnNodeId(); ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); myNodePtr.p->ndynamicId = TdynamicId; - presidentNodePtr.i = cpresident; - ptrCheckGuard(presidentNodePtr, MAX_NDB_NODES, nodeRec); - cpdistref = presidentNodePtr.p->blockRef; - - CmNodeInfoReq * const req = (CmNodeInfoReq*)signal->getDataPtrSend(); - req->nodeId = getOwnNodeId(); - req->dynamicId = myNodePtr.p->ndynamicId; - req->version = getNodeInfo(getOwnNodeId()).m_version; for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { jam(); - if (NdbNodeBitmask::get(cnodemask, nodePtr.i) == true){ + if (c_clusterNodes.get(nodePtr.i)){ jam(); ptrAss(nodePtr, nodeRec); - switch(nodePtr.p->phase){ - case ZINIT: /* All nodes start in phase INIT */ - jam(); - break; - case ZWAITING: /* Node is connecting to cluster */ - jam(); - break; - case ZRUNNING: /* Node is running in the cluster */ - jam(); - break; - case ZBLOCKED: /* Node is blocked from the cluster */ - jam(); - break; - case ZWAIT_PRESIDENT: - jam(); - break; - case ZDEAD: - jam(); - break; - case ZAPI_ACTIVE: /* API IS RUNNING IN NODE */ - jam(); - break; - case ZFAIL_CLOSING: /* API/NDB IS DISCONNECTING */ - jam(); - break; - case ZPREPARE_FAIL: /* PREPARATION FOR FAILURE */ - jam(); - break; - case ZAPI_INACTIVE: /* Inactive API */ - jam(); - break; - default: + + ndbrequire(nodePtr.p->phase == ZINIT); + nodePtr.p->phase = ZRUNNING; + + if(c_connectedNodes.get(nodePtr.i)){ jam(); - ndbout << "phase="<<nodePtr.p->phase<<endl; - break; + sendCmNodeInfoReq(signal, nodePtr.i, myNodePtr.p); } - ndbrequire(nodePtr.p->phase == ZINIT); - ndbrequire(nodePtr.i != getOwnNodeId()); - nodePtr.p->phase = ZWAITING; - - sendSignal(nodePtr.p->blockRef, GSN_CM_NODEINFOREQ, - signal, CmNodeInfoReq::SignalLength, JBB); } } + + c_start.m_gsn = GSN_CM_NODEINFOREQ; + c_start.m_nodes = c_clusterNodes; + return; }//Qmgr::execCM_REGCONF() +void +Qmgr::sendCmNodeInfoReq(Signal* signal, Uint32 nodeId, const NodeRec * self){ + CmNodeInfoReq * const req = (CmNodeInfoReq*)signal->getDataPtrSend(); + req->nodeId = getOwnNodeId(); + req->dynamicId = self->ndynamicId; + req->version = getNodeInfo(getOwnNodeId()).m_version; + const Uint32 ref = calcQmgrBlockRef(nodeId); + sendSignal(ref,GSN_CM_NODEINFOREQ, signal, CmNodeInfoReq::SignalLength, JBB); + DEBUG_START(GSN_CM_NODEINFOREQ, nodeId, ""); +} + /* 4.4.11 CM_REGREF */ /**-------------------------------------------------------------------------- @@ -735,9 +680,11 @@ void Qmgr::execCM_REGREF(Signal* signal) UintR TrefuseReason = signal->theData[2]; Uint32 candidate = signal->theData[3]; + DEBUG_START3(signal, TrefuseReason); + if(candidate != cpresidentCandidate){ jam(); - c_regReqReqRecv = c_regReqReqSent + 1; + c_regReqReqRecv = ~0; } switch (TrefuseReason) { @@ -758,25 +705,16 @@ void Qmgr::execCM_REGREF(Signal* signal) break; case CmRegRef::ZNOT_DEAD: jam(); - if(TaddNodeno == getOwnNodeId() && cpresident == getOwnNodeId()){ - jam(); - cwaitContinuebPhase1 = ZFALSE; - cwaitContinuebPhase2 = ZFALSE; - return; - } progError(__LINE__, ERR_NODE_NOT_DEAD); break; case CmRegRef::ZELECTION: jam(); - if (cwaitContinuebPhase1 == ZFALSE) { - jam(); - signal->theData[3] = 1; - } else if (cpresidentCandidate > TaddNodeno) { + if (cpresidentCandidate > TaddNodeno) { jam(); -//---------------------------------------- -/* We may already have a candidate */ -/* choose the lowest nodeno */ -//---------------------------------------- + //---------------------------------------- + /* We may already have a candidate */ + /* choose the lowest nodeno */ + //---------------------------------------- signal->theData[3] = 2; cpresidentCandidate = TaddNodeno; } else { @@ -808,16 +746,19 @@ void Qmgr::execCM_REGREF(Signal* signal) if(cpresidentAlive == ZTRUE){ jam(); + DEBUG(""); return; } if(c_regReqReqSent != c_regReqReqRecv){ jam(); + DEBUG( c_regReqReqSent << " != " << c_regReqReqRecv); return; } if(cpresidentCandidate != getOwnNodeId()){ jam(); + DEBUG(""); return; } @@ -829,10 +770,8 @@ void Qmgr::execCM_REGREF(Signal* signal) jam(); electionWon(); -#if 1 - signal->theData[0] = 0; - sendSignal(CMVMI_REF, GSN_CM_RUN, signal, 1, JBB); -#endif + sendSttorryLab(signal); + /** * Start timer handling */ @@ -851,14 +790,18 @@ Qmgr::electionWon(){ ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); myNodePtr.p->phase = ZRUNNING; + cpdistref = reference(); - cclustersize = 1; cneighbourl = ZNIL; cneighbourh = ZNIL; myNodePtr.p->ndynamicId = 1; - + c_maxDynamicId = 1; + c_clusterNodes.clear(); + c_clusterNodes.set(getOwnNodeId()); + cpresidentAlive = ZTRUE; c_stopElectionTime = ~0; + c_start.reset(); } /* @@ -870,38 +813,11 @@ Qmgr::electionWon(){ /* CONTINUEB > SENDER: Own block, Own node */ /****************************>-------+INPUT : TCONTINUEB_TYPE */ /*--------------------------------------------------------------*/ -void Qmgr::regreqTimelimitLab(Signal* signal, UintR callTime) +void Qmgr::regreqTimeLimitLab(Signal* signal) { - if (cwaitContinuebPhase1 == ZFALSE) { - if (cwaitContinuebPhase2 == ZFALSE) { - jam(); - return; - } else { - jam(); - if (callTime < 10) { - /*-------------------------------------------------------------*/ - // We experienced a time-out of inclusion. Give it another few - // seconds before crashing. - /*-------------------------------------------------------------*/ - signal->theData[0] = ZREGREQ_TIMELIMIT; - signal->theData[1] = cstartNo; - signal->theData[2] = callTime + 1; - sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 3000, 3); - return; - }//if - /*-------------------------------------------------------------*/ - /* WE HAVE COME HERE BECAUSE THE INCLUSION SUFFERED FROM */ - /* TIME OUT. WE CRASH AND RESTART. */ - /*-------------------------------------------------------------*/ - systemErrorLab(signal); - return; - }//if - } else { - jam(); - cwaitContinuebPhase1 = ZFALSE; - }//if - - cmInfoconf010Lab(signal); + if(cpresident == ZNIL){ + cmInfoconf010Lab(signal); + } }//Qmgr::regreqTimelimitLab() /**--------------------------------------------------------------------------- @@ -917,32 +833,37 @@ void Qmgr::regreqTimelimitLab(Signal* signal, UintR callTime) /*******************************/ void Qmgr::execCM_NODEINFOCONF(Signal* signal) { - NodeRecPtr replyNodePtr; - NodeRecPtr nodePtr; + DEBUG_START3(signal, ""); + jamEntry(); CmNodeInfoConf * const conf = (CmNodeInfoConf*)signal->getDataPtr(); - replyNodePtr.i = conf->nodeId; - ptrCheckGuard(replyNodePtr, MAX_NDB_NODES, nodeRec); - replyNodePtr.p->ndynamicId = conf->dynamicId; - setNodeInfo(replyNodePtr.i).m_version = conf->version; - replyNodePtr.p->phase = ZRUNNING; - + const Uint32 nodeId = conf->nodeId; + const Uint32 dynamicId = conf->dynamicId; + const Uint32 version = conf->version; + + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrAss(nodePtr, nodeRec); + ndbrequire(nodePtr.p->phase == ZSTARTING); + ndbrequire(c_start.m_gsn = GSN_CM_NODEINFOREQ); + c_start.m_nodes.clearWaitingFor(nodeId); + /** - * A node in the cluster has replied nodeinfo about himself. - * He is already running in the cluster. + * Update node info */ - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { + NodeRecPtr replyNodePtr; + replyNodePtr.i = nodeId; + ptrCheckGuard(replyNodePtr, MAX_NDB_NODES, nodeRec); + replyNodePtr.p->ndynamicId = dynamicId; + replyNodePtr.p->blockRef = signal->getSendersBlockRef(); + setNodeInfo(replyNodePtr.i).m_version = version; + + if(!c_start.m_nodes.done()){ jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->phase == ZWAITING) { - if (nodePtr.i != getOwnNodeId()) { - jam(); - return; - }//if - }//if - }//for + return; + } /**********************************************<*/ /* Send an ack. back to the president. */ @@ -953,11 +874,7 @@ void Qmgr::execCM_NODEINFOCONF(Signal* signal) /* for CM_ADD (commit) from president to become */ /* a running node in the cluster. */ /**********************************************<*/ - CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); - cmAckAdd->requestType = CmAdd::Prepare; - cmAckAdd->senderNodeId = getOwnNodeId(); - cmAckAdd->startingNodeId = getOwnNodeId(); - sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); + sendCmAckAdd(signal, getOwnNodeId(), CmAdd::Prepare); return; }//Qmgr::execCM_NODEINFOCONF() @@ -970,59 +887,99 @@ void Qmgr::execCM_NODEINFOCONF(Signal* signal) /*******************************/ void Qmgr::execCM_NODEINFOREQ(Signal* signal) { - NodeRecPtr addNodePtr; - NodeRecPtr myNodePtr; jamEntry(); + const Uint32 Tblockref = signal->getSendersBlockRef(); + + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrAss(nodePtr, nodeRec); + if(nodePtr.p->phase != ZRUNNING){ + jam(); + signal->theData[0] = reference(); + signal->theData[1] = getOwnNodeId(); + signal->theData[2] = ZNOT_RUNNING; + sendSignal(Tblockref, GSN_CM_NODEINFOREF, signal, 3, JBB); + return; + } + + NodeRecPtr addNodePtr; CmNodeInfoReq * const req = (CmNodeInfoReq*)signal->getDataPtr(); addNodePtr.i = req->nodeId; ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec); addNodePtr.p->ndynamicId = req->dynamicId; + addNodePtr.p->blockRef = signal->getSendersBlockRef(); setNodeInfo(addNodePtr.i).m_version = req->version; - - const BlockReference Tblockref = signal->getSendersBlockRef(); + c_maxDynamicId = req->dynamicId; - myNodePtr.i = getOwnNodeId(); - ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); - if (myNodePtr.p->phase == ZRUNNING) { - if (addNodePtr.p->phase == ZWAITING) { - jam(); - /* President have prepared us */ - /****************************<*/ - /*< CM_NODEINFOCONF <*/ - /****************************<*/ - CmNodeInfoConf * const conf = (CmNodeInfoConf*)signal->getDataPtrSend(); - conf->nodeId = getOwnNodeId(); - conf->dynamicId = myNodePtr.p->ndynamicId; - conf->version = getNodeInfo(getOwnNodeId()).m_version; - sendSignal(Tblockref, GSN_CM_NODEINFOCONF, signal, - CmNodeInfoConf::SignalLength, JBB); - /****************************************/ - /* Send an ack. back to the president */ - /* CM_ACKADD */ - /****************************************/ - CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); - cmAckAdd->requestType = CmAdd::Prepare; - cmAckAdd->senderNodeId = getOwnNodeId(); - cmAckAdd->startingNodeId = addNodePtr.i; - sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); - } else { - jam(); - addNodePtr.p->phase = ZWAIT_PRESIDENT; - }//if - } else { - jam(); - /****************************<*/ - /*< CM_NODEINFOREF <*/ - /****************************<*/ - signal->theData[0] = myNodePtr.p->blockRef; - signal->theData[1] = myNodePtr.i; - signal->theData[2] = ZNOT_RUNNING; - sendSignal(Tblockref, GSN_CM_NODEINFOREF, signal, 3, JBB); - }//if - return; + cmAddPrepare(signal, addNodePtr, nodePtr.p); }//Qmgr::execCM_NODEINFOREQ() +void +Qmgr::cmAddPrepare(Signal* signal, NodeRecPtr nodePtr, const NodeRec * self){ + jam(); + + switch(nodePtr.p->phase){ + case ZINIT: + jam(); + nodePtr.p->phase = ZSTARTING; + return; + case ZFAIL_CLOSING: + jam(); +#ifdef VM_TRACE + ndbout_c("Enabling communication to CM_ADD node state=%d", + nodePtr.p->phase); +#endif + nodePtr.p->phase = ZSTARTING; + nodePtr.p->failState = NORMAL; + signal->theData[0] = 0; + signal->theData[1] = nodePtr.i; + sendSignal(CMVMI_REF, GSN_OPEN_COMREQ, signal, 2, JBA); + return; + case ZSTARTING: + break; + case ZRUNNING: + case ZPREPARE_FAIL: + case ZAPI_ACTIVE: + case ZAPI_INACTIVE: + ndbrequire(false); + } + + sendCmAckAdd(signal, nodePtr.i, CmAdd::Prepare); + + /* President have prepared us */ + CmNodeInfoConf * conf = (CmNodeInfoConf*)signal->getDataPtrSend(); + conf->nodeId = getOwnNodeId(); + conf->dynamicId = self->ndynamicId; + conf->version = getNodeInfo(getOwnNodeId()).m_version; + sendSignal(nodePtr.p->blockRef, GSN_CM_NODEINFOCONF, signal, + CmNodeInfoConf::SignalLength, JBB); + DEBUG_START(GSN_CM_NODEINFOCONF, refToNode(nodePtr.p->blockRef), ""); +} + +void +Qmgr::sendCmAckAdd(Signal * signal, Uint32 nodeId, CmAdd::RequestType type){ + + CmAckAdd * cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); + cmAckAdd->requestType = type; + cmAckAdd->startingNodeId = nodeId; + cmAckAdd->senderNodeId = getOwnNodeId(); + sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); + DEBUG_START(GSN_CM_ACKADD, cpresident, ""); + + switch(type){ + case CmAdd::Prepare: + return; + case CmAdd::AddCommit: + case CmAdd::CommitNew: + break; + } + + signal->theData[0] = nodeId; + EXECUTE_DIRECT(NDBCNTR, GSN_CM_ADD_REP, signal, 1); + jamEntry(); +} + /* 4.4.11 CM_ADD */ /**-------------------------------------------------------------------------- @@ -1040,156 +997,130 @@ void Qmgr::execCM_NODEINFOREQ(Signal* signal) void Qmgr::execCM_ADD(Signal* signal) { NodeRecPtr addNodePtr; - NodeRecPtr nodePtr; - NodeRecPtr myNodePtr; jamEntry(); + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); + CmAdd * const cmAdd = (CmAdd*)signal->getDataPtr(); const CmAdd::RequestType type = (CmAdd::RequestType)cmAdd->requestType; addNodePtr.i = cmAdd->startingNodeId; //const Uint32 startingVersion = cmAdd->startingVersion; ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec); - if(addNodePtr.p->phase == ZFAIL_CLOSING){ + DEBUG_START3(signal, type); + + if(nodePtr.p->phase == ZSTARTING){ jam(); -#ifdef VM_TRACE - ndbout_c("Enabling communication to CM_ADD node state=%d", - addNodePtr.p->phase); -#endif - addNodePtr.p->failState = NORMAL; - signal->theData[0] = 0; - signal->theData[1] = addNodePtr.i; - sendSignal(CMVMI_REF, GSN_OPEN_COMREQ, signal, 2, JBA); + /** + * We are joining... + */ + ndbrequire(addNodePtr.i == nodePtr.i); + switch(type){ + case CmAdd::Prepare: + ndbrequire(c_start.m_gsn = GSN_CM_NODEINFOREQ); + /** + * Wait for CM_NODEINFO_CONF + */ + return; + case CmAdd::CommitNew: + /** + * Tata. we're in the cluster + */ + joinedCluster(signal, addNodePtr); + return; + case CmAdd::AddCommit: + ndbrequire(false); + } } - + switch (type) { case CmAdd::Prepare: - jam(); - if (addNodePtr.i != getOwnNodeId()) { - jam(); - if (addNodePtr.p->phase == ZWAIT_PRESIDENT) { - jam(); - /****************************<*/ - /*< CM_NODEINFOCONF <*/ - /****************************<*/ - myNodePtr.i = getOwnNodeId(); - ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); - - CmNodeInfoConf * const conf = (CmNodeInfoConf*)signal->getDataPtrSend(); - conf->nodeId = getOwnNodeId(); - conf->dynamicId = myNodePtr.p->ndynamicId; - conf->version = getNodeInfo(getOwnNodeId()).m_version; - sendSignal(addNodePtr.p->blockRef, GSN_CM_NODEINFOCONF, signal, - CmNodeInfoConf::SignalLength, JBB); - /****************************<*/ - /* Send an ack. back to the president */ - /*< CM_ACKADD <*/ - /****************************<*/ - CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); - cmAckAdd->requestType = CmAdd::Prepare; - cmAckAdd->senderNodeId = getOwnNodeId(); - cmAckAdd->startingNodeId = addNodePtr.i; - sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); - }//if - // ----------------------------------------- - /* Wait for the new node's CM_NODEINFOREQ.*/ - // ----------------------------------------- - addNodePtr.p->phase = ZWAITING; - }//if + cmAddPrepare(signal, addNodePtr, nodePtr.p); break; case CmAdd::AddCommit:{ jam(); + ndbrequire(addNodePtr.p->phase == ZSTARTING); addNodePtr.p->phase = ZRUNNING; addNodePtr.p->alarmCount = 0; + c_clusterNodes.set(addNodePtr.i); findNeighbours(signal); - /**----------------------------------------------------------------------- + + /** * SEND A HEARTBEAT IMMEDIATELY TO DECREASE THE RISK THAT WE MISS EARLY * HEARTBEATS. - *-----------------------------------------------------------------------*/ + */ sendHeartbeat(signal); - /*-----------------------------------------------------------------------*/ - /* ENABLE COMMUNICATION WITH ALL BLOCKS WITH THE NEWLY ADDED NODE. */ - /*-----------------------------------------------------------------------*/ + + /** + * ENABLE COMMUNICATION WITH ALL BLOCKS WITH THE NEWLY ADDED NODE + */ signal->theData[0] = addNodePtr.i; sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA); - /****************************<*/ - /*< CM_ACKADD <*/ - /****************************<*/ - CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); - cmAckAdd->requestType = CmAdd::AddCommit; - cmAckAdd->senderNodeId = getOwnNodeId(); - cmAckAdd->startingNodeId = addNodePtr.i; - sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); + + sendCmAckAdd(signal, addNodePtr.i, CmAdd::AddCommit); + if(getOwnNodeId() != cpresident){ + jam(); + c_start.reset(); + } break; } - case CmAdd::CommitNew:{ + case CmAdd::CommitNew: jam(); - /*-----------------------------------------------------------------------*/ - /* WE HAVE BEEN INCLUDED IN THE CLUSTER WE CAN START BEING PART OF THE - * HEARTBEAT PROTOCOL AND WE WILL ALSO ENABLE COMMUNICATION WITH ALL - * NODES IN THE CLUSTER. - *-----------------------------------------------------------------------*/ - addNodePtr.p->phase = ZRUNNING; - addNodePtr.p->alarmCount = 0; - findNeighbours(signal); - /**----------------------------------------------------------------------- - * SEND A HEARTBEAT IMMEDIATELY TO DECREASE THE RISK THAT WE MISS EARLY - * HEARTBEATS. - *-----------------------------------------------------------------------*/ - sendHeartbeat(signal); - cwaitContinuebPhase2 = ZFALSE; - /**----------------------------------------------------------------------- - * ENABLE COMMUNICATION WITH ALL BLOCKS IN THE CURRENT CLUSTER AND SET - * THE NODES IN THE CLUSTER TO BE RUNNING. - *-----------------------------------------------------------------------*/ - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if ((nodePtr.p->phase == ZRUNNING) && - (nodePtr.i != getOwnNodeId())) { - /*-------------------------------------------------------------------*/ - // Enable full communication to all other nodes. Not really necessary - // to open communication to ourself. - /*-------------------------------------------------------------------*/ - jam(); - signal->theData[0] = nodePtr.i; - sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA); - }//if - }//for - - /****************************<*/ - /*< CM_ACKADD <*/ - /****************************<*/ - CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); - cmAckAdd->requestType = CmAdd::CommitNew; - cmAckAdd->senderNodeId = getOwnNodeId(); - cmAckAdd->startingNodeId = addNodePtr.i; - sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); - -#if 1 - /**********************************************<*/ - /* Allow the CLUSTER CONTROL to send STTORRY */ - /* so we can receive CM_REG from applications. */ - /**********************************************<*/ - signal->theData[0] = 0; - sendSignal(CMVMI_REF, GSN_CM_RUN, signal, 1, JBB); -#endif - - /** - * Start timer handling - */ - signal->theData[0] = ZTIMER_HANDLING; - sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 10, JBB); + ndbrequire(false); } - break; - default: - jam(); - /*empty*/; - break; - }//switch - return; + }//Qmgr::execCM_ADD() +void +Qmgr::joinedCluster(Signal* signal, NodeRecPtr nodePtr){ + /** + * WE HAVE BEEN INCLUDED IN THE CLUSTER WE CAN START BEING PART OF THE + * HEARTBEAT PROTOCOL AND WE WILL ALSO ENABLE COMMUNICATION WITH ALL + * NODES IN THE CLUSTER. + */ + nodePtr.p->phase = ZRUNNING; + nodePtr.p->alarmCount = 0; + findNeighbours(signal); + c_clusterNodes.set(nodePtr.i); + c_start.reset(); + + /** + * SEND A HEARTBEAT IMMEDIATELY TO DECREASE THE RISK + * THAT WE MISS EARLY HEARTBEATS. + */ + sendHeartbeat(signal); + + /** + * ENABLE COMMUNICATION WITH ALL BLOCKS IN THE CURRENT CLUSTER AND SET + * THE NODES IN THE CLUSTER TO BE RUNNING. + */ + for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { + jam(); + ptrAss(nodePtr, nodeRec); + if ((nodePtr.p->phase == ZRUNNING) && (nodePtr.i != getOwnNodeId())) { + /*-------------------------------------------------------------------*/ + // Enable full communication to all other nodes. Not really necessary + // to open communication to ourself. + /*-------------------------------------------------------------------*/ + jam(); + signal->theData[0] = nodePtr.i; + sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA); + }//if + }//for + + sendSttorryLab(signal); + + /** + * Start timer handling + */ + signal->theData[0] = ZTIMER_HANDLING; + sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 10, JBB); + + sendCmAckAdd(signal, getOwnNodeId(), CmAdd::CommitNew); +} + /* 4.10.7 CM_ACKADD - PRESIDENT IS RECEIVER - */ /*---------------------------------------------------------------------------*/ /* Entry point for an ack add signal. @@ -1198,7 +1129,6 @@ void Qmgr::execCM_ADD(Signal* signal) void Qmgr::execCM_ACKADD(Signal* signal) { NodeRecPtr addNodePtr; - NodeRecPtr nodePtr; NodeRecPtr senderNodePtr; jamEntry(); @@ -1206,109 +1136,86 @@ void Qmgr::execCM_ACKADD(Signal* signal) const CmAdd::RequestType type = (CmAdd::RequestType)cmAckAdd->requestType; addNodePtr.i = cmAckAdd->startingNodeId; senderNodePtr.i = cmAckAdd->senderNodeId; + + DEBUG_START3(signal, type); + if (cpresident != getOwnNodeId()) { jam(); /*-----------------------------------------------------------------------*/ /* IF WE ARE NOT PRESIDENT THEN WE SHOULD NOT RECEIVE THIS MESSAGE. */ /*------------------------------------------------------------_----------*/ + warningEvent("Received CM_ACKADD from %d president=%d", + senderNodePtr.i, cpresident); return; }//if - if (cpresidentBusy != ZTRUE) { - jam(); - /**---------------------------------------------------------------------- - * WE ARE PRESIDENT BUT WE ARE NOT BUSY ADDING ANY NODE. THUS WE MUST - * HAVE STOPPED THIS ADDING OF THIS NODE. - *----------------------------------------------------------------------*/ - return; - }//if - if (addNodePtr.i != cstartNode) { + + if (addNodePtr.i != c_start.m_startNode) { jam(); /*----------------------------------------------------------------------*/ /* THIS IS NOT THE STARTING NODE. WE ARE ACTIVE NOW WITH ANOTHER START. */ /*----------------------------------------------------------------------*/ + warningEvent("Received CM_ACKADD from %d with startNode=%d != own %d", + senderNodePtr.i, addNodePtr.i, c_start.m_startNode); return; }//if + + ndbrequire(c_start.m_gsn == GSN_CM_ADD); + c_start.m_nodes.clearWaitingFor(senderNodePtr.i); + if(!c_start.m_nodes.done()){ + jam(); + return; + } + switch (type) { case CmAdd::Prepare:{ jam(); - ptrCheckGuard(senderNodePtr, MAX_NDB_NODES, nodeRec); - senderNodePtr.p->sendCmAddPrepStatus = Q_NOT_ACTIVE; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - /* Check if all prepare are acknowledged*/ - if (nodePtr.p->sendCmAddPrepStatus == Q_ACTIVE) { - jam(); - return; /* Wait for more acknowledge's */ - }//if - }//for + /*----------------------------------------------------------------------*/ /* ALL RUNNING NODES HAVE PREPARED THE INCLUSION OF THIS NEW NODE. */ /*----------------------------------------------------------------------*/ + c_start.m_gsn = GSN_CM_ADD; + c_start.m_nodes = c_clusterNodes; + CmAdd * const cmAdd = (CmAdd*)signal->getDataPtrSend(); cmAdd->requestType = CmAdd::AddCommit; cmAdd->startingNodeId = addNodePtr.i; cmAdd->startingVersion = getNodeInfo(addNodePtr.i).m_version; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->phase == ZRUNNING) { - jam(); - sendSignal(nodePtr.p->blockRef, GSN_CM_ADD, signal, - CmAdd::SignalLength, JBA); - nodePtr.p->sendCmAddCommitStatus = Q_ACTIVE; - }//if - }//for + NodeReceiverGroup rg(QMGR, c_clusterNodes); + sendSignal(rg, GSN_CM_ADD, signal, CmAdd::SignalLength, JBA); + DEBUG_START2(GSN_CM_ADD, rg, "AddCommit"); return; - break; } case CmAdd::AddCommit:{ jam(); - ptrCheckGuard(senderNodePtr, MAX_NDB_NODES, nodeRec); - senderNodePtr.p->sendCmAddCommitStatus = Q_NOT_ACTIVE; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - /* Check to see if we need to wait for */ - if (nodePtr.p->sendCmAddCommitStatus == Q_ACTIVE) { - jam(); - /* any more ack. commit add. */ - return; /* Exit and continue waiting. */ - }//if - }//for + /****************************************/ /* Send commit to the new node so he */ /* will change PHASE into ZRUNNING */ /****************************************/ + c_start.m_gsn = GSN_CM_ADD; + c_start.m_nodes.clearWaitingFor(); + c_start.m_nodes.setWaitingFor(addNodePtr.i); + CmAdd * const cmAdd = (CmAdd*)signal->getDataPtrSend(); cmAdd->requestType = CmAdd::CommitNew; cmAdd->startingNodeId = addNodePtr.i; cmAdd->startingVersion = getNodeInfo(addNodePtr.i).m_version; - ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec); - sendSignal(addNodePtr.p->blockRef, GSN_CM_ADD, signal, + sendSignal(calcQmgrBlockRef(addNodePtr.i), GSN_CM_ADD, signal, CmAdd::SignalLength, JBA); - break; + DEBUG_START(GSN_CM_ADD, addNodePtr.i, "CommitNew"); + return; } case CmAdd::CommitNew: jam(); - /*----------------------------------------------------------------------*/ - /* Increment the amount of nodes in the cluster in waiting mode. */ - /* President now ready for more CM_REGREQ */ - /*----------------------------------------------------------------------*/ - cclustersize = cclustersize + 1; /** * Tell arbitration about new node. */ handleArbitNdbAdd(signal, addNodePtr.i); - cpresidentBusy = ZFALSE; - break; - default: - jam(); - /*empty*/; - break; + c_start.reset(); + return; }//switch - return; + ndbrequire(false); }//Qmgr::execCM_ACKADD() /**------------------------------------------------------------------------- @@ -1433,51 +1340,30 @@ void Qmgr::findNeighbours(Signal* signal) /*---------------------------------------------------------------------------*/ void Qmgr::initData(Signal* signal) { - RegAppPtr localRegAppptr; - - for (localRegAppptr.i = 0; - localRegAppptr.i < NO_REG_APP; localRegAppptr.i++) { - ptrAss(localRegAppptr, regApp); - localRegAppptr.p->version = 0; - localRegAppptr.p->blockref = 0; - memset(localRegAppptr.p->name, 0, sizeof(localRegAppptr.p->name)); - localRegAppptr.p->activity = ZREMOVE; - localRegAppptr.p->noofapps = 0; - localRegAppptr.p->noofpending = 0; - localRegAppptr.p->m_runNodes.clear(); - }//for - NodeRecPtr nodePtr; for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) { ptrAss(nodePtr, nodeRec); nodePtr.p->ndynamicId = 0; - /* Subr NEXT_DYNAMIC_ID will use this to find */ - /* a unique higher value than any of these */ - - /* Not in config file */ - nodePtr.p->phase = ZBLOCKED; + if(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB){ + nodePtr.p->phase = ZINIT; + c_definedNodes.set(nodePtr.i); + } else { + nodePtr.p->phase = ZAPI_INACTIVE; + } + nodePtr.p->alarmCount = 0; nodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE; nodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE; - nodePtr.p->sendCmAddPrepStatus = Q_NOT_ACTIVE; - nodePtr.p->sendCmAddCommitStatus = Q_NOT_ACTIVE; nodePtr.p->sendPresToStatus = Q_NOT_ACTIVE; - nodePtr.p->m_connected = false; nodePtr.p->failState = NORMAL; nodePtr.p->rcv[0] = 0; nodePtr.p->rcv[1] = 0; }//for - ccm_infoconfCounter = 0; cfailureNr = 1; ccommitFailureNr = 1; cprepareFailureNr = 1; cnoFailedNodes = 0; cnoPrepFailedNodes = 0; - cwaitContinuebPhase1 = ZFALSE; - cwaitContinuebPhase2 = ZFALSE; - cstartNo = 0; - cpresidentBusy = ZFALSE; - cacceptRegreq = ZTRUE; creadyDistCom = ZFALSE; cpresident = ZNIL; cpresidentCandidate = ZNIL; @@ -1496,55 +1382,58 @@ void Qmgr::initData(Signal* signal) // catch-all for missing initializations memset(&arbitRec, 0, sizeof(arbitRec)); -}//Qmgr::initData() -/* -4.10.7 PREPARE_ADD */ -/**-------------------------------------------------------------------------- - * President sends CM_ADD to prepare all running nodes to add a new node. - * Even the president node will get a CM_ADD (prepare). - * The new node will make REQs to all running nodes after it has received the - * CM_REGCONF. The president will just coordinate the adding of new nodes. - * The CM_ADD (prepare) is sent to the cluster before the CM_REGCONF signal - * to the new node. - * - * At the same time we will store all running nodes in CNODEMASK, - * which will be sent to the new node - * Scan the NODE_REC for all running nodes and create a nodemask where - * each bit represents a node. - * --------------------------------------------------------------------------*/ -void Qmgr::prepareAdd(Signal* signal, Uint16 anAddedNode) -{ - NodeRecPtr nodePtr; - NdbNodeBitmask::clear(cnodemask); + /** + * Timeouts + */ + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); - CmAdd * const cmAdd = (CmAdd*)signal->getDataPtrSend(); - cmAdd->requestType = CmAdd::Prepare; - cmAdd->startingNodeId = anAddedNode; - cmAdd->startingVersion = getNodeInfo(anAddedNode).m_version; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->phase == ZRUNNING) { - jam(); - /* We found a node to prepare. */ - NdbNodeBitmask::set(cnodemask, nodePtr.i); - sendSignal(nodePtr.p->blockRef, GSN_CM_ADD, signal, CmAdd::SignalLength, JBA); - nodePtr.p->sendCmAddPrepStatus = Q_ACTIVE; - }//if - }//for + Uint32 hbDBDB = 1500; + Uint32 hbDBAPI = 1500; + Uint32 arbitTimeout = 1000; + c_restartPartialTimeout = 30000; + ndb_mgm_get_int_parameter(p, CFG_DB_HEARTBEAT_INTERVAL, &hbDBDB); + ndb_mgm_get_int_parameter(p, CFG_DB_API_HEARTBEAT_INTERVAL, &hbDBAPI); + ndb_mgm_get_int_parameter(p, CFG_DB_ARBIT_TIMEOUT, &arbitTimeout); + ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTIAL_TIMEOUT, + &c_restartPartialTimeout); + if(c_restartPartialTimeout == 0){ + c_restartPartialTimeout = ~0; + } + + setHbDelay(hbDBDB); + setHbApiDelay(hbDBAPI); + setArbitTimeout(arbitTimeout); + + arbitRec.state = ARBIT_NULL; // start state for all nodes + arbitRec.apiMask[0].clear(); // prepare for ARBIT_CFG + + ArbitSignalData* const sd = (ArbitSignalData*)&signal->theData[0]; + for (unsigned rank = 1; rank <= 2; rank++) { + sd->sender = getOwnNodeId(); + sd->code = rank; + sd->node = 0; + sd->ticket.clear(); + sd->mask.clear(); + ndb_mgm_configuration_iterator * iter = + theConfiguration.getClusterConfigIterator(); + for (ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)) { + Uint32 tmp = 0; + if (ndb_mgm_get_int_parameter(iter, CFG_NODE_ARBIT_RANK, &tmp) == 0 && + tmp == rank){ + Uint32 nodeId = 0; + ndbrequire(!ndb_mgm_get_int_parameter(iter, CFG_NODE_ID, &nodeId)); + sd->mask.set(nodeId); + } + } + + execARBIT_CFG(signal); + } + setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION; +}//Qmgr::initData() - NodeRecPtr addNodePtr; - addNodePtr.i = anAddedNode; - ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec); - /*****************************< - * We send to the node to be added a CM_ADD as well. - * We want him to send an ack when he has - * received all CM_NODEINFOCONF. - */ - sendSignal(addNodePtr.p->blockRef, GSN_CM_ADD, signal, CmAdd::SignalLength, JBA); - addNodePtr.p->sendCmAddPrepStatus = Q_ACTIVE; -}//Qmgr::prepareAdd() /**--------------------------------------------------------------------------- * HERE WE RECEIVE THE JOB TABLE SIGNAL EVERY 10 MILLISECONDS. @@ -1695,22 +1584,23 @@ void Qmgr::apiHbHandlingLab(Signal* signal) NodeRecPtr TnodePtr; for (TnodePtr.i = 1; TnodePtr.i < MAX_NODES; TnodePtr.i++) { + const Uint32 nodeId = TnodePtr.i; ptrAss(TnodePtr, nodeRec); - const NodeInfo::NodeType type = getNodeInfo(TnodePtr.i).getType(); + const NodeInfo::NodeType type = getNodeInfo(nodeId).getType(); if(type == NodeInfo::DB) continue; if(type == NodeInfo::INVALID) continue; - if (TnodePtr.p->m_connected && TnodePtr.p->phase != ZAPI_INACTIVE){ + if (TnodePtr.p->phase == ZAPI_ACTIVE){ jam(); TnodePtr.p->alarmCount ++; - + if(TnodePtr.p->alarmCount > 2){ signal->theData[0] = EventReport::MissedHeartbeat; - signal->theData[1] = TnodePtr.i; + signal->theData[1] = nodeId; signal->theData[2] = TnodePtr.p->alarmCount - 1; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB); } @@ -1725,10 +1615,10 @@ void Qmgr::apiHbHandlingLab(Signal* signal) /* We call node_failed to release all connections for this api node */ /*------------------------------------------------------------------*/ signal->theData[0] = EventReport::DeadDueToHeartbeat; - signal->theData[1] = TnodePtr.i; + signal->theData[1] = nodeId; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); - node_failed(signal, TnodePtr.i); + node_failed(signal, nodeId); }//if }//if }//for @@ -1748,7 +1638,7 @@ void Qmgr::checkStartInterface(Signal* signal) if (nodePtr.p->phase == ZFAIL_CLOSING) { jam(); nodePtr.p->alarmCount = nodePtr.p->alarmCount + 1; - if (nodePtr.p->m_connected) { + if (c_connectedNodes.get(nodePtr.i)){ jam(); /*-------------------------------------------------------------------*/ // We need to ensure that the connection is not restored until it has @@ -1766,11 +1656,12 @@ void Qmgr::checkStartInterface(Signal* signal) nodePtr.p->failState = NORMAL; if (getNodeInfo(nodePtr.i).m_type != NodeInfo::DB){ jam(); - nodePtr.p->phase = ZBLOCKED; + nodePtr.p->phase = ZAPI_INACTIVE; } else { jam(); nodePtr.p->phase = ZINIT; }//if + nodePtr.p->alarmCount = 0; signal->theData[0] = 0; signal->theData[1] = nodePtr.i; @@ -1908,13 +1799,13 @@ void Qmgr::execNDB_FAILCONF(Signal* signal) for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) { jam(); ptrAss(nodePtr, nodeRec); - if ((nodePtr.p->phase == ZAPI_ACTIVE) && nodePtr.p->m_connected) { + if (nodePtr.p->phase == ZAPI_ACTIVE){ jam(); sendSignal(nodePtr.p->blockRef, GSN_NF_COMPLETEREP, signal, NFCompleteRep::SignalLength, JBA); }//if }//for - }//if + } return; }//Qmgr::execNDB_FAILCONF() @@ -1923,14 +1814,28 @@ void Qmgr::execNDB_FAILCONF(Signal* signal) /*******************************/ void Qmgr::execDISCONNECT_REP(Signal* signal) { + jamEntry(); const DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0]; - NodeRecPtr failedNodePtr; + const Uint32 nodeId = rep->nodeId; + c_connectedNodes.clear(nodeId); - jamEntry(); - failedNodePtr.i = rep->nodeId; - ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec); - failedNodePtr.p->m_connected = false; - node_failed(signal, failedNodePtr.i); + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrCheckGuard(nodePtr, MAX_NODES, nodeRec); + switch(nodePtr.p->phase){ + case ZRUNNING: + jam(); + break; + case ZINIT: + case ZSTARTING: + case ZPREPARE_FAIL: + case ZFAIL_CLOSING: + case ZAPI_ACTIVE: + case ZAPI_INACTIVE: + ndbrequire(false); + } + + node_failed(signal, nodeId); }//DISCONNECT_REP void Qmgr::node_failed(Signal* signal, Uint16 aFailedNode) @@ -1957,6 +1862,9 @@ void Qmgr::node_failed(Signal* signal, Uint16 aFailedNode) case ZFAIL_CLOSING: jam(); return; + case ZSTARTING: + c_start.reset(); + // Fall-through default: jam(); /*---------------------------------------------------------------------*/ @@ -1987,11 +1895,11 @@ void Qmgr::node_failed(Signal* signal, Uint16 aFailedNode) jam(); if (failedNodePtr.p->phase != ZFAIL_CLOSING){ jam(); - //-------------------------------------------------------------------------- + //------------------------------------------------------------------------- // The API was active and has now failed. We need to initiate API failure // handling. If the API had already failed then we can ignore this // discovery. - //-------------------------------------------------------------------------- + //------------------------------------------------------------------------- failedNodePtr.p->phase = ZFAIL_CLOSING; sendApiFailReq(signal, aFailedNode); @@ -2056,11 +1964,6 @@ void Qmgr::execAPI_REGREQ(Signal* signal) apiRegConf->qmgrRef = reference(); apiRegConf->apiHeartbeatFrequency = (chbApiDelay / 10); apiRegConf->version = NDB_VERSION; - - - // if(apiNodePtr.i == getNodeState.single. && NodeState::SL_MAINTENANCE) - // apiRegConf->nodeState = NodeState::SL_STARTED; - //else apiRegConf->nodeState = getNodeState(); { NodeRecPtr nodePtr; @@ -2079,7 +1982,7 @@ void Qmgr::execAPI_REGREQ(Signal* signal) if ((getNodeState().startLevel == NodeState::SL_STARTED || getNodeState().getSingleUserMode()) - && apiNodePtr.p->phase == ZBLOCKED) { + && apiNodePtr.p->phase == ZAPI_INACTIVE) { jam(); /**---------------------------------------------------------------------- * THE API NODE IS REGISTERING. WE WILL ACCEPT IT BY CHANGING STATE AND @@ -2186,15 +2089,6 @@ void Qmgr::failReportLab(Signal* signal, Uint16 aFailedNode, failReport(signal, failedNodePtr.i, (UintR)ZTRUE, aFailCause); if (cpresident == getOwnNodeId()) { jam(); - if (cpresidentBusy == ZTRUE) { - jam(); -/**------------------------------------------------------------------- -* ALL STARTING NODES ARE CRASHED WHEN AN ALIVE NODE FAILS DURING ITS -* START-UP. AS PRESIDENT OF THE CLUSTER IT IS OUR DUTY TO INFORM OTHERS -* ABOUT THIS. -*---------------------------------------------------------------------*/ - failReport(signal, cstartNode, (UintR)ZTRUE, FailRep::ZOTHER_NODE_WHEN_WE_START); - }//if if (ctoStatus == Q_NOT_ACTIVE) { jam(); /**-------------------------------------------------------------------- @@ -2525,9 +2419,7 @@ void Qmgr::execCOMMIT_FAILREQ(Signal* signal) return; }//if UintR guard0; - UintR Ti; UintR Tj; - RegAppPtr localRegAppptr; /** * Block commit until node failures has stabilized @@ -2547,37 +2439,19 @@ void Qmgr::execCOMMIT_FAILREQ(Signal* signal) * SIGNAL. WE CAN HEAR IT SEVERAL TIMES IF THE PRESIDENTS KEEP FAILING. *-----------------------------------------------------------------------*/ ccommitFailureNr = TfailureNr; - for (localRegAppptr.i = 0; - localRegAppptr.i < NO_REG_APP; localRegAppptr.i++) { + NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0]; + + nodeFail->failNo = ccommitFailureNr; + nodeFail->noOfNodes = cnoCommitFailedNodes; + nodeFail->masterNodeId = cpresident; + NodeBitmask::clear(nodeFail->theNodes); + for(unsigned i = 0; i < cnoCommitFailedNodes; i++) { jam(); - ptrAss(localRegAppptr, regApp); - if (localRegAppptr.p->activity != ZREMOVE) { - /*------------------------------------------------------------------*/ - // We need to remove the failed nodes from the set of running nodes - // in the registered application. - //------------------------------------------------------------------*/ - for (Ti = 0; Ti < cnoCommitFailedNodes; Ti++) { - jam(); - arrGuard(ccommitFailedNodes[Ti], MAX_NDB_NODES); - localRegAppptr.p->m_runNodes.clear(ccommitFailedNodes[Ti]); - }//for - /*------------------------------------------------------------------*/ - // Send a signal to the registered application to inform him of the - // node failure(s). - /*------------------------------------------------------------------*/ - NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0]; + NodeBitmask::set(nodeFail->theNodes, ccommitFailedNodes[i]); + }//if + sendSignal(NDBCNTR_REF, GSN_NODE_FAILREP, signal, + NodeFailRep::SignalLength, JBB); - nodeFail->failNo = ccommitFailureNr; - nodeFail->noOfNodes = cnoCommitFailedNodes; - NodeBitmask::clear(nodeFail->theNodes); - for(unsigned i = 0; i < cnoCommitFailedNodes; i++) { - jam(); - NodeBitmask::set(nodeFail->theNodes, ccommitFailedNodes[i]); - }//if - sendSignal(localRegAppptr.p->blockref, GSN_NODE_FAILREP, signal, - NodeFailRep::SignalLength, JBB); - }//if - }//for guard0 = cnoCommitFailedNodes - 1; arrGuard(guard0, MAX_NDB_NODES); /**-------------------------------------------------------------------- @@ -2591,6 +2465,7 @@ void Qmgr::execCOMMIT_FAILREQ(Signal* signal) nodePtr.p->phase = ZFAIL_CLOSING; nodePtr.p->failState = WAITING_FOR_NDB_FAILCONF; nodePtr.p->alarmCount = 0; + c_clusterNodes.clear(nodePtr.i); }//for /*----------------------------------------------------------------------*/ /* WE INFORM THE API'S WE HAVE CONNECTED ABOUT THE FAILED NODES. */ @@ -2753,226 +2628,31 @@ void Qmgr::execPRES_TOCONF(Signal* signal) /*--------------------------------------------------------------------------*/ void Qmgr::execREAD_NODESREQ(Signal* signal) { - NodeRecPtr nodePtr; - UintR TnoOfNodes = 0; + jamEntry(); + BlockReference TBref = signal->theData[0]; ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0]; - NodeBitmask::clear(readNodes->allNodes); - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (getNodeInfo(nodePtr.i).getType() == NodeInfo::DB){ - jam(); - TnoOfNodes++; - NodeBitmask::set(readNodes->allNodes, nodePtr.i); - }//if - }//for - readNodes->noOfNodes = TnoOfNodes; - sendSignal(TBref, GSN_READ_NODESCONF, signal, - ReadNodesConf::SignalLength, JBB); -}//Qmgr::execREAD_NODESREQ() -/*-------------------------------------------------------------------------- - * Signal from an application requesting to be monitored in the cluster. - * APPL_REGREQ can be entered at any time during the life of the QMGR. - * It can be entered any number of times. - * If QMGR is ZRUNNING a CM_APPCHG will be sent to all active nodes. - *---------------------------------------------------------------------------*/ -void Qmgr::execAPPL_REGREQ(Signal* signal) -{ NodeRecPtr nodePtr; - NodeRecPtr myNodePtr; - RegAppPtr lRegApptr; - char Tappname[16]; - jamEntry(); - BlockReference Tappref = signal->theData[0]; - Tappname[0] = signal->theData[1] >> 8; - Tappname[1] = signal->theData[2]; - Tappname[2] = signal->theData[2] >> 8; - Tappname[3] = signal->theData[3]; - Tappname[4] = signal->theData[3] >> 8; - Tappname[5] = signal->theData[4]; - Tappname[6] = signal->theData[4] >> 8; - Tappname[7] = signal->theData[5]; - Tappname[8] = signal->theData[5] >> 8; - Tappname[9] = signal->theData[6]; - Tappname[10] = signal->theData[6] >> 8; - Tappname[11] = signal->theData[7]; - Tappname[12] = signal->theData[7] >> 8; - Tappname[13] = signal->theData[8]; - Tappname[14] = signal->theData[8] >> 8; - Tappname[signal->theData[1] & 0xFF] = 0; - UintR Tversion = signal->theData[10]; - Uint16 Tnodeno = refToNode(Tappref); - if (Tnodeno == 0) { - jam(); - /* Fix for all not distributed applications. */ - Tnodeno = getOwnNodeId(); - }//if - if (getOwnNodeId() == Tnodeno) { - jam(); - /* Local application */ - UintR Tfound = RNIL; - for (lRegApptr.i = NO_REG_APP-1; (Uint16)~lRegApptr.i; lRegApptr.i--) { - jam(); - ptrAss(lRegApptr, regApp); - if (lRegApptr.p->activity == ZREMOVE) { - Tfound = lRegApptr.i; - break; - }//if - }//for - if (Tfound != RNIL) { - jam(); - /* If there was a slot available we */ - /* register the application */ - lRegApptr.i = Tfound; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - lRegApptr.p->blockref = Tappref; - strcpy(lRegApptr.p->name, Tappname); - lRegApptr.p->version = Tversion; - lRegApptr.p->activity = ZADD; - myNodePtr.i = getOwnNodeId(); - ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); - /****************************<*/ - /*< APPL_REGCONF <*/ - /****************************<*/ - signal->theData[0] = lRegApptr.i; - signal->theData[1] = cnoOfNodes; - signal->theData[2] = cpresident; - signal->theData[3] = myNodePtr.p->ndynamicId; - sendSignal(lRegApptr.p->blockref, GSN_APPL_REGCONF, signal, 4, JBB); - if (myNodePtr.p->phase == ZRUNNING) { - jam(); - /* Check to see if any further action */ - for (nodePtr.i = 1; - nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - /* is needed at this time */ - if (nodePtr.p->phase == ZRUNNING) { - jam(); - sendappchg(signal, lRegApptr.i, nodePtr.i); - }//if - }//for - }//if - } else { - jam(); - /****************************<*/ - /*< APPL_REGREF <*/ - /****************************<*/ - signal->theData[0] = ZERRTOOMANY; - sendSignal(Tappref, GSN_APPL_REGREF, signal, 1, JBB); - }//if - } else { - jam(); - /* TOO MANY REGISTERED APPLICATIONS */ - systemErrorLab(signal); - }//if - return; -}//Qmgr::execAPPL_REGREQ() - -/* -4.4.11 APPL_STARTREG */ -/**-------------------------------------------------------------------------- - * Signal from an application indicating that it is ready to start running - * distributed. If the application is running alone or if all other - * applications of the same kind already have registered as STARTING then - * APPL_STARTCONF will be sent to the application as soon as phase four of - * STTOR is reached. - *--------------------------------------------------------------------------*/ -/*******************************/ -/* APPL_STARTREG */ -/*******************************/ -void Qmgr::execAPPL_STARTREG(Signal* signal) -{ - RegAppPtr lRegApptr; - NodeRecPtr myNodePtr; - UintR TnodeId; - jamEntry(); - lRegApptr.i = signal->theData[0]; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - UintR Tcounter = signal->theData[1]; + nodePtr.i = getOwnNodeId(); + ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - lRegApptr.p->activity = ZSTART; - /* Application is ready to start. */ + NdbNodeBitmask tmp = c_definedNodes; + tmp.bitANDC(c_clusterNodes); - /* Calculate how many apps we wait for */ - lRegApptr.p->noofapps = (Tcounter - 1) - lRegApptr.p->noofpending; - /* send info to all other running nodes in the */ - myNodePtr.i = getOwnNodeId(); - ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); - /* cluster indicating the status change of the */ - if (myNodePtr.p->phase == ZRUNNING) { - /* application. */ - for (TnodeId = 1; TnodeId < MAX_NDB_NODES; TnodeId++) { - jam(); - if (lRegApptr.p->m_runNodes.get(TnodeId)){ - jam(); - sendappchg(signal, lRegApptr.i, TnodeId); - }//if - }//for - }//if - /****************************<*/ - /*< APPL_STARTCONF <*/ - /****************************<*/ - if (lRegApptr.p->noofapps == 0) { - jam(); - sendSignal(lRegApptr.p->blockref, GSN_APPL_STARTCONF, signal, 1, JBB); - }//if - return; -}//Qmgr::execAPPL_STARTREG() - -/* - 4.4.11 APPL_RUN */ -/*--------------------------------------------------------------------------*/ -/* Signal from an application announcing that it is running. */ -/*--------------------------------------------------------------------------*/ -/*******************************/ -/* APPL_RUN */ -/*******************************/ -void Qmgr::execAPPL_RUN(Signal* signal) -{ - RegAppPtr lRegApptr; - NodeRecPtr myNodePtr; - UintR TnodeId; - jamEntry(); - lRegApptr.i = signal->theData[0]; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - lRegApptr.p->activity = ZRUN; - /* Flag the application as running. */ - myNodePtr.i = getOwnNodeId(); - ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); - if (myNodePtr.p->phase == ZRUNNING) { - /* If we are running send the appl. status */ - for (TnodeId = 1; TnodeId < MAX_NDB_NODES; TnodeId++) { - jam(); - /* change to all other running nodes. */ - if (lRegApptr.p->m_runNodes.get(TnodeId)){ - jam(); - sendappchg(signal, lRegApptr.i, TnodeId); - }//if - }//for - }//if - /****************************<*/ - /*< CM_RUN <*/ - /****************************<*/ - /*---------------------------------------------------*/ - /* Inform the CLUSTER CONTROL of NDB started */ - /* so we can connect to API nodes. */ - /*---------------------------------------------------*/ - signal->theData[0] = 1; - sendSignal(CMVMI_REF, GSN_CM_RUN, signal, 1, JBB); - cactivateApiCheck = 1; - /** - * Start arbitration thread. This could be done as soon as - * we have all nodes (or a winning majority). - */ - if (cpresident == getOwnNodeId()) - handleArbitStart(signal); - return; -}//Qmgr::execAPPL_RUN() + readNodes->noOfNodes = c_definedNodes.count(); + readNodes->masterNodeId = cpresident; + readNodes->ndynamicId = nodePtr.p->ndynamicId; + c_definedNodes.copyto(NdbNodeBitmask::Size, readNodes->definedNodes); + c_clusterNodes.copyto(NdbNodeBitmask::Size, readNodes->clusterNodes); + tmp.copyto(NdbNodeBitmask::Size, readNodes->inactiveNodes); + NdbNodeBitmask::clear(readNodes->startingNodes); + NdbNodeBitmask::clear(readNodes->startedNodes); + sendSignal(TBref, GSN_READ_NODESCONF, signal, + ReadNodesConf::SignalLength, JBB); +}//Qmgr::execREAD_NODESREQ() void Qmgr::systemErrorBecauseOtherNodeFailed(Signal* signal, NodeId failedNodeId) { @@ -3003,234 +2683,6 @@ void Qmgr::systemErrorLab(Signal* signal, const char * message) return; }//Qmgr::systemErrorLab() -/* -4.4.11 CM_APPCHG */ -/*---------------------------------------------------------------------------*/ -/*Signal between two QMGRs used to announce any changes of state for an appl.*/ -/*---------------------------------------------------------------------------*/ -/*******************************/ -/* CM_APPCHG */ -/*******************************/ -void Qmgr::execCM_APPCHG(Signal* signal) -{ - RegAppPtr lRegApptr; - char Tappname[16]; - jamEntry(); - UintR Ttype = signal->theData[0]; - Uint16 Tnodeno = signal->theData[1]; - Tappname[0] = signal->theData[2] >> 8; - Tappname[1] = signal->theData[3]; - Tappname[2] = signal->theData[3] >> 8; - Tappname[3] = signal->theData[4]; - Tappname[4] = signal->theData[4] >> 8; - Tappname[5] = signal->theData[5]; - Tappname[6] = signal->theData[5] >> 8; - Tappname[7] = signal->theData[6]; - Tappname[8] = signal->theData[6] >> 8; - Tappname[9] = signal->theData[7]; - Tappname[10] = signal->theData[7] >> 8; - Tappname[11] = signal->theData[8]; - Tappname[12] = signal->theData[8] >> 8; - Tappname[13] = signal->theData[9]; - Tappname[14] = signal->theData[9] >> 8; - Tappname[signal->theData[2] & 0xFF] = 0; - UintR Tversion = signal->theData[11]; - switch (Ttype) { - case ZADD: - jam(); - /* A new application has started on the sending node */ - for (lRegApptr.i = NO_REG_APP-1; (Uint16)~lRegApptr.i; lRegApptr.i--) { - jam(); - /* We are hosting this application */ - ptrAss(lRegApptr, regApp); - if (strcmp(lRegApptr.p->name, Tappname) == 0) { - cmappAdd(signal, lRegApptr.i, Tnodeno, Ttype, Tversion); - }//if - }//for - break; - - case ZSTART: - jam(); - /* A registered application is ready to start on the sending node */ - for (lRegApptr.i = NO_REG_APP-1; (Uint16)~lRegApptr.i; lRegApptr.i--) { - jam(); - ptrAss(lRegApptr, regApp); - if (strcmp(lRegApptr.p->name, Tappname) == 0) { - cmappStart(signal, lRegApptr.i, Tnodeno, Ttype, Tversion); - }//if - }//for - break; - - case ZRUN: - /* A registered application on the sending node has started to run */ - jam(); - for (lRegApptr.i = NO_REG_APP-1; (Uint16)~lRegApptr.i; lRegApptr.i--) { - jam(); - ptrAss(lRegApptr, regApp); - if (strcmp(lRegApptr.p->name, Tappname) == 0) { - arrGuard(Tnodeno, MAX_NDB_NODES); - lRegApptr.p->m_runNodes.set(Tnodeno); - applchangerep(signal, lRegApptr.i, Tnodeno, Ttype, Tversion); - }//if - }//for - cacceptRegreq = ZTRUE; /* We can now start accepting new CM_REGREQ */ - /* since the new node is running */ - break; - - case ZREMOVE: - /* A registered application has been deleted on the sending node */ - jam(); - for (lRegApptr.i = NO_REG_APP-1; (Uint16)~lRegApptr.i; lRegApptr.i--) { - jam(); - ptrAss(lRegApptr, regApp); - if (strcmp(lRegApptr.p->name, Tappname) == 0) { - applchangerep(signal, lRegApptr.i, Tnodeno, Ttype, Tversion); - }//if - }//for - break; - - default: - jam(); - /*empty*/; - break; - }//switch - return; -}//Qmgr::execCM_APPCHG() - -/**-------------------------------------------------------------------------- - * INPUT REG_APPPTR - * TNODENO - *--------------------------------------------------------------------------*/ -void Qmgr::applchangerep(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion) -{ - RegAppPtr lRegApptr; - NodeRecPtr localNodePtr; - lRegApptr.i = aRegApp; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - if (lRegApptr.p->blockref != 0) { - jam(); - localNodePtr.i = aNode; - ptrCheckGuard(localNodePtr, MAX_NDB_NODES, nodeRec); - /****************************************/ - /* Send a report of changes on another */ - /* node to the local application */ - /****************************************/ - signal->theData[0] = aType; - signal->theData[1] = aVersion; - signal->theData[2] = localNodePtr.i; - signal->theData[4] = localNodePtr.p->ndynamicId; - sendSignal(lRegApptr.p->blockref, GSN_APPL_CHANGEREP, signal, 5, JBB); - }//if -}//Qmgr::applchangerep() - -/* - 4.10.7 CMAPP_ADD */ -/**-------------------------------------------------------------------------- - * We only map applications of the same version. We have the same application - * and version locally. - * INPUT REG_APPPTR - * TNODENO Sending node - * TVERSION Version of application - * OUTPUT REG_APPPTR, TNODENO ( not changed) - *---------------------------------------------------------------------------*/ -void Qmgr::cmappAdd(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion) -{ - RegAppPtr lRegApptr; - lRegApptr.i = aRegApp; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - if (lRegApptr.p->version == aVersion) { - jam(); - arrGuard(aNode, MAX_NDB_NODES); - if (lRegApptr.p->m_runNodes.get(aNode) == false){ - jam(); - /* Check if we already have added it. */ - /*-------------------------------------------------------*/ - /* Since we only add remote applications, if we also are */ - /* hosting them we need to send a reply indicating that */ - /* we also are hosting the application. */ - /*-------------------------------------------------------*/ - sendappchg(signal, lRegApptr.i, aNode); - lRegApptr.p->m_runNodes.set(aNode); - /*---------------------------------------*/ - /* Add the remote node to the the local */ - /* nodes memberlist. */ - /* Inform the local application of the */ - /* new application running remotely. */ - /*---------------------------------------*/ - applchangerep(signal, lRegApptr.i, aNode, aType, aVersion); - }//if - }//if -}//Qmgr::cmappAdd() - -/* -4.10.7 CMAPP_START */ -/**-------------------------------------------------------------------------- - * Inform the local application of the change in node state on the remote node - * INPUT REG_APPPTR - * OUTPUT - - *---------------------------------------------------------------------------*/ -void Qmgr::cmappStart(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion) -{ - RegAppPtr lRegApptr; - lRegApptr.i = aRegApp; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - if (lRegApptr.p->version == aVersion) { - applchangerep(signal, lRegApptr.i, aNode, aType, aVersion); - if (lRegApptr.p->activity == ZSTART) { - jam(); - //---------------------------------------- - /* If the local application is already */ - /* in START face then we do some checks.*/ - //---------------------------------------- - if (lRegApptr.p->noofapps > 0) { - jam(); - //---------------------------------------- - /* Check if we need to decrement the no */ - /* of apps. */ - /* This indicates how many startsignals */ - /* from apps remaining before we can */ - /* send a APPL_STARTCONF. */ - //---------------------------------------- - lRegApptr.p->noofapps--; - }//if - if (lRegApptr.p->noofapps == 0) { - jam(); - //---------------------------------------- - /* All applications have registered as */ - /* ready to start. */ - //---------------------------------------- - /****************************<*/ - /*< APPL_STARTCONF <*/ - /****************************<*/ - sendSignal(lRegApptr.p->blockref, GSN_APPL_STARTCONF, signal, 1, JBB); - }//if - } else { - jam(); - /**-------------------------------------------------------------------- - * Add the ready node to the nodes pending counter. - * This counter is used to see how many remote nodes that are waiting - * for this node to enter the start face. - * It is used when the appl. sends a APPL_STARTREG signal. - *---------------------------------------------------------------------*/ - if (lRegApptr.p->activity == ZADD) { - jam(); - lRegApptr.p->noofpending++; - }//if - }//if - }//if -}//Qmgr::cmappStart() /**--------------------------------------------------------------------------- * A FAILURE HAVE BEEN DISCOVERED ON A NODE. WE NEED TO CLEAR A @@ -3249,17 +2701,6 @@ void Qmgr::failReport(Signal* signal, failedNodePtr.i = aFailedNode; ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRec); - if (((cpresidentBusy == ZTRUE) || - (cacceptRegreq == ZFALSE)) && - (cstartNode == aFailedNode)) { - jam(); -/*----------------------------------------------------------------------*/ -// A node crashed keeping the president busy and that ensures that there -// is no acceptance of regreq's which is not acceptable after its crash. -/*----------------------------------------------------------------------*/ - cpresidentBusy = ZFALSE; - cacceptRegreq = ZTRUE; - }//if if (failedNodePtr.p->phase == ZRUNNING) { jam(); /* WE ALSO NEED TO ADD HERE SOME CODE THAT GETS OUR NEW NEIGHBOURS. */ @@ -3278,8 +2719,6 @@ void Qmgr::failReport(Signal* signal, }//if }//if failedNodePtr.p->phase = ZPREPARE_FAIL; - failedNodePtr.p->sendCmAddPrepStatus = Q_NOT_ACTIVE; - failedNodePtr.p->sendCmAddCommitStatus = Q_NOT_ACTIVE; failedNodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE; failedNodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE; failedNodePtr.p->sendPresToStatus = Q_NOT_ACTIVE; @@ -3412,74 +2851,6 @@ Uint16 Qmgr::translateDynamicIdToNodeId(Signal* signal, UintR TdynamicId) return TtdiNodeId; }//Qmgr::translateDynamicIdToNodeId() - -/* -4.10.7 GET_DYNAMIC_ID */ -/**-------------------------------------------------------------------------- - * FIND THE CLOSEST HIGHER DYNAMIC ID AMONG THE RUNNING NODES. ADD ONE TO - * THAT VALUE AND WE HAVE CREATED A NEW, UNIQUE AND HIGHER DYNAMIC VALUE THAN - * ANYONE ELSE IN THE CLUSTER.THIS WAY WE DON'T HAVE TO KEEP TRACK OF VARIABLE - * THAT HOLDS THE LAST USED DYNAMIC ID, ESPECIALLY WE DON'T NEED TO INFORM - * ANY VICE PRESIDENTS ABOUT THAT DYNAMIC VARIABLE. - * INPUT - - * RET CDYNAMIC_ID USED AS A TEMPORARY VARIABLE TO PASS THE VALUE TO THE - * CALLER OF THIS SUBROUTINE - *---------------------------------------------------------------------------*/ -UintR Qmgr::getDynamicId(Signal* signal) -{ - NodeRecPtr nodePtr; - UintR TdynamicId = 0; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->phase == ZRUNNING) { - if (nodePtr.p->ndynamicId > TdynamicId) { - jam(); - TdynamicId = nodePtr.p->ndynamicId; - }//if - }//if - }//for - TdynamicId++; - return TdynamicId; -}//Qmgr::getDynamicId() - -/* -4.10.7 SENDAPPCHG */ -/*---------------------------------------------------------------------------*/ -/* We only send changes to external nodes. */ -/* INPUT: TNODENO */ -/* REG_APPPTR */ -/*---------------------------------------------------------------------------*/ -void Qmgr::sendappchg(Signal* signal, UintR aRegApp, Uint16 aNode) -{ - NodeRecPtr localNodePtr; - RegAppPtr lRegApptr; - if (aNode != getOwnNodeId()) { - jam(); - localNodePtr.i = aNode; - ptrCheckGuard(localNodePtr, MAX_NDB_NODES, nodeRec); - lRegApptr.i = aRegApp; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - /****************************************/ - /* Signal any application changes to */ - /* the receiving node */ - /****************************************/ - signal->theData[0] = lRegApptr.p->activity; - signal->theData[1] = getOwnNodeId(); - signal->theData[2] = strlen(lRegApptr.p->name)|(lRegApptr.p->name[0] << 8); - signal->theData[3] = lRegApptr.p->name[1] | (lRegApptr.p->name[2] << 8); - signal->theData[4] = lRegApptr.p->name[3] | (lRegApptr.p->name[4] << 8); - signal->theData[5] = lRegApptr.p->name[5] | (lRegApptr.p->name[6] << 8); - signal->theData[6] = lRegApptr.p->name[7] | (lRegApptr.p->name[8] << 8); - signal->theData[7] = lRegApptr.p->name[9] | (lRegApptr.p->name[10] << 8); - signal->theData[8] = lRegApptr.p->name[11] | (lRegApptr.p->name[12] << 8); - signal->theData[9] = lRegApptr.p->name[13] | (lRegApptr.p->name[14] << 8); - signal->theData[10] = 0; - signal->theData[11] = lRegApptr.p->version; - sendSignal(localNodePtr.p->blockRef, GSN_CM_APPCHG, signal, 12, JBA); - }//if -}//Qmgr::sendappchg() - /**-------------------------------------------------------------------------- * WHEN RECEIVING PREPARE FAILURE REQUEST WE WILL IMMEDIATELY CLOSE * COMMUNICATION WITH ALL THOSE NODES. @@ -4450,14 +3821,10 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal) { switch (signal->theData[0]) { case 1: - infoEvent("creadyDistCom = %d, cpresident = %d, cpresidentBusy = %d\n", - creadyDistCom, cpresident, cpresidentBusy); - infoEvent("cacceptRegreq = %d, ccm_infoconfCounter = %d\n", - cacceptRegreq, ccm_infoconfCounter); - infoEvent("cstartNo = %d, cstartNode = %d, cwaitC..phase1 = %d\n", - cstartNo, cstartNode, cwaitContinuebPhase1); - infoEvent("cwaitC..phase2 = %d, cpresidentAlive = %d, cpresidentCand = %d\n" - ,cwaitContinuebPhase2, cpresidentAlive, cpresidentCandidate); + infoEvent("creadyDistCom = %d, cpresident = %d\n", + creadyDistCom, cpresident); + infoEvent("cpresidentAlive = %d, cpresidentCand = %d\n", + cpresidentAlive, cpresidentCandidate); infoEvent("ctoStatus = %d\n", ctoStatus); for(Uint32 i = 1; i<MAX_NDB_NODES; i++){ if(getNodeInfo(i).getType() == NodeInfo::DB){ @@ -4469,18 +3836,15 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal) case ZINIT: sprintf(buf, "Node %d: ZINIT(%d)", i, nodePtr.p->phase); break; - case ZBLOCKED: - sprintf(buf, "Node %d: ZBLOCKED(%d)", i, nodePtr.p->phase); - break; - case ZWAITING: - sprintf(buf, "Node %d: ZWAITING(%d)", i, nodePtr.p->phase); - break; - case ZWAIT_PRESIDENT: - sprintf(buf, "Node %d: ZWAIT_PRESIDENT(%d)", i, nodePtr.p->phase); + case ZSTARTING: + sprintf(buf, "Node %d: ZSTARTING(%d)", i, nodePtr.p->phase); break; case ZRUNNING: sprintf(buf, "Node %d: ZRUNNING(%d)", i, nodePtr.p->phase); break; + case ZPREPARE_FAIL: + sprintf(buf, "Node %d: ZPREPARE_FAIL(%d)", i, nodePtr.p->phase); + break; case ZFAIL_CLOSING: sprintf(buf, "Node %d: ZFAIL_CLOSING(%d)", i, nodePtr.p->phase); break; @@ -4490,9 +3854,6 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal) case ZAPI_ACTIVE: sprintf(buf, "Node %d: ZAPI_ACTIVE(%d)", i, nodePtr.p->phase); break; - case ZPREPARE_FAIL: - sprintf(buf, "Node %d: ZPREPARE_FAIL(%d)", i, nodePtr.p->phase); - break; default: sprintf(buf, "Node %d: <UNKNOWN>(%d)", i, nodePtr.p->phase); break; @@ -4507,6 +3868,7 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal) void Qmgr::execSET_VAR_REQ(Signal* signal) { +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); UintR val = setVarReq->value(); @@ -4530,4 +3892,5 @@ void Qmgr::execSET_VAR_REQ(Signal* signal) default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); }// switch +#endif }//execSET_VAR_REQ() diff --git a/ndb/src/kernel/ndb-main/Main.cpp b/ndb/src/kernel/ndb-main/Main.cpp index 2ac32ada4ec..e8014b63d08 100644 --- a/ndb/src/kernel/ndb-main/Main.cpp +++ b/ndb/src/kernel/ndb-main/Main.cpp @@ -52,10 +52,7 @@ void systemInfo(const Configuration & conf, const char programName[] = "NDB Kernel"; -extern int global_ndb_check; NDB_MAIN(ndb_kernel){ - - global_ndb_check = 1; // Print to stdout/console g_eventLogger.createConsoleHandler(); @@ -130,9 +127,7 @@ NDB_MAIN(ndb_kernel){ } g_eventLogger.info("Angel pid: %d ndb pid: %d", getppid(), getpid()); - - systemInfo(* theConfig, - theConfig->clusterConfigurationData().SizeAltData.logLevel); + systemInfo(* theConfig, * theConfig->m_logLevel); // Load blocks globalEmulatorData.theSimBlockList->load(* theConfig); @@ -147,6 +142,7 @@ NDB_MAIN(ndb_kernel){ char buf[255]; strcpy(buf, homePath); FILE * signalLog = fopen(strncat(buf,"Signal.log", 255), "a"); + globalSignalLoggers.setOwnNodeId(globalData.ownId); globalSignalLoggers.setOutputStream(signalLog); #endif diff --git a/ndb/src/kernel/ndb-main/Makefile_old b/ndb/src/kernel/ndb-main/Makefile_old index 29b7ea7e708..08fc125cb00 100644 --- a/ndb/src/kernel/ndb-main/Makefile_old +++ b/ndb/src/kernel/ndb-main/Makefile_old @@ -11,7 +11,7 @@ BIN_TARGET_ARCHIVES := mgmapi \ error \ trace \ signaldataprint \ - mgmsrvcommon \ + mgmsrvcommon mgmapi \ portlib \ logger \ general diff --git a/ndb/src/kernel/ndb-main/SimBlockList.cpp b/ndb/src/kernel/ndb-main/SimBlockList.cpp index 9e1d28a7fce..bc6262e0723 100644 --- a/ndb/src/kernel/ndb-main/SimBlockList.cpp +++ b/ndb/src/kernel/ndb-main/SimBlockList.cpp @@ -32,6 +32,7 @@ #include <Suma.hpp> #include <Grep.hpp> #include <Dbtux.hpp> +#include <NdbEnv.h> enum SIMBLOCKLIST_DUMMY { A_VALUE = 0 }; @@ -68,10 +69,20 @@ SimBlockList::load(const Configuration & conf){ theList[i] = 0; Dbdict* dbdict = 0; Dbdih* dbdih = 0; - + + SimulatedBlock * fs = 0; + { + char buf[100]; + if(NdbEnv_GetEnv("NDB_NOFS", buf, 100) == 0){ + fs = new (A_VALUE) Ndbfs(conf); + } else { + fs = new (A_VALUE) VoidFs(conf); + } + } + theList[0] = new (A_VALUE) Dbacc(conf); theList[1] = new (A_VALUE) Cmvmi(conf); - theList[2] = new (A_VALUE) Ndbfs(conf); + theList[2] = fs; theList[3] = dbdict = new (A_VALUE) Dbdict(conf); theList[4] = dbdih = new (A_VALUE) Dbdih(conf); theList[5] = new (A_VALUE) Dblqh(conf); diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index 706d75509f2..c97ad951cf3 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -27,6 +27,15 @@ #include <getarg.h> +#include <mgmapi_configuration.hpp> +#include <mgmapi_config_parameters_debug.h> +#include <kernel_config_parameters.h> + +#include <kernel_types.h> +#include <ndb_limits.h> +#include "pc.hpp" +#include <LogLevel.hpp> + extern "C" { void ndbSetOwnVersion(); } @@ -122,10 +131,8 @@ Configuration::init(int argc, const char** argv){ return true; } -Configuration::Configuration(): - the_clusterConfigurationData() +Configuration::Configuration() { - m_ownProperties = 0; _programName = 0; _connectString = 0; _fsPath = 0; @@ -134,8 +141,6 @@ Configuration::Configuration(): } Configuration::~Configuration(){ - delete m_ownProperties; - if(_programName != NULL) free(_programName); @@ -143,12 +148,6 @@ Configuration::~Configuration(){ free(_fsPath); } -const -ClusterConfiguration& -Configuration::clusterConfiguration() const { - return the_clusterConfigurationData; -} - void Configuration::setupConfiguration(){ /** @@ -157,7 +156,7 @@ Configuration::setupConfiguration(){ ConfigRetriever cr; cr.setConnectString(_connectString); stopOnError(true); - Properties * p = cr.getConfig("DB", NDB_VERSION); + ndb_mgm_configuration * p = cr.getConfig(NDB_VERSION, NODE_TYPE_DB); if(p == 0){ const char * s = cr.getErrorString(); if(s == 0) @@ -171,56 +170,46 @@ Configuration::setupConfiguration(){ "/invalid configuration", s); } + Uint32 nodeId = globalData.ownId = cr.getOwnNodeId(); + /** * Configure transporters */ { - IPCConfig * theIPC = new IPCConfig(p); - - if(theIPC->init() != 0){ - ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", ""); - } - - if(theIPC->configureTransporters(&globalTransporterRegistry) <= 0){ + int res = IPCConfig::configureTransporters(nodeId, + * p, + globalTransporterRegistry); + if(res <= 0){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "No transporters configured"); } - - globalData.ownId = theIPC->ownId(); - delete theIPC; } /** * Setup cluster configuration data */ - const Properties * db = 0; - if (!p->get("Node", globalData.ownId, &db)) { + ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE); + if (iter.find(CFG_NODE_ID, globalData.ownId)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "DB missing"); } - const char * type; - if(!(db->get("Type", &type) && strcmp(type, "DB") == 0)){ + + unsigned type; + if(!(iter.get(CFG_TYPE_OF_SECTION, &type) == 0 && type == NODE_TYPE_DB)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "I'm wrong type of node"); } - /** - * Save properties object to use in getOwnProperties() - */ - m_ownProperties = new Properties(* db); - - the_clusterConfigurationData.init(* p, * db); - - if(!db->get("MaxNoOfSavedMessages", &_maxErrorLogs)){ + if(iter.get(CFG_DB_NO_SAVE_MSGS, &_maxErrorLogs)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "MaxNoOfSavedMessages missing"); } - if(!db->get("LockPagesInMainMemory", &_lockPagesInMainMemory)){ + if(iter.get(CFG_DB_MEMLOCK, &_lockPagesInMainMemory)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "LockPagesInMainMemory missing"); } - if(!db->get("TimeBetweenWatchDogCheck", &_timeBetweenWatchDogCheck)){ + if(iter.get(CFG_DB_WATCHDOG_INTERVAL, &_timeBetweenWatchDogCheck)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "TimeBetweenWatchDogCheck missing"); } @@ -230,16 +219,16 @@ Configuration::setupConfiguration(){ */ { const char* pFileSystemPath = NULL; - if(!db->get("FileSystemPath", &pFileSystemPath)){ + if(iter.get(CFG_DB_FILESYSTEM_PATH, &pFileSystemPath)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "FileSystemPath missing"); } - + if(pFileSystemPath == 0 || strlen(pFileSystemPath) == 0){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "Configuration does not contain valid filesystem path"); } - + if(pFileSystemPath[strlen(pFileSystemPath) - 1] == '/') _fsPath = strdup(pFileSystemPath); else { @@ -248,19 +237,17 @@ Configuration::setupConfiguration(){ strcat(_fsPath, "/"); } } - - if(!db->get("StopOnError", &_stopOnError)){ + + if(iter.get(CFG_DB_STOP_ON_ERROR, &_stopOnError)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "StopOnError missing"); } - - if(!db->get("RestartOnErrorInsert", &m_restartOnErrorInsert)){ + + if(iter.get(CFG_DB_STOP_ON_ERROR_INSERT, &m_restartOnErrorInsert)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "RestartOnErrorInsert missing"); } - delete p; - /** * Create the watch dog thread */ @@ -269,7 +256,14 @@ Configuration::setupConfiguration(){ t = globalEmulatorData.theWatchDog ->setCheckInterval(t); _timeBetweenWatchDogCheck = t; } + + ConfigValues* cf = ConfigValuesFactory::extractCurrentSection(iter.m_config); + + m_clusterConfig = p; + m_clusterConfigIter = ndb_mgm_create_configuration_iterator + (p, CFG_SECTION_NODE); + calcSizeAlt(cf); } bool @@ -282,12 +276,6 @@ Configuration::timeBetweenWatchDogCheck() const { return _timeBetweenWatchDogCheck; } -const -ClusterConfiguration::ClusterData& -Configuration::clusterConfigurationData() const { - return the_clusterConfigurationData.clusterData(); -} - void Configuration::timeBetweenWatchDogCheck(int value) { _timeBetweenWatchDogCheck = value; @@ -313,11 +301,6 @@ Configuration::stopOnError(bool val){ _stopOnError = val; } -const Properties * -Configuration::getOwnProperties() const { - return m_ownProperties; -} - int Configuration::getRestartOnErrorInsert() const { return m_restartOnErrorInsert; @@ -335,6 +318,350 @@ Configuration::getConnectStringCopy() const { return 0; } +const ndb_mgm_configuration_iterator * +Configuration::getOwnConfigIterator() const { + return m_ownConfigIterator; +} + +ndb_mgm_configuration_iterator * +Configuration::getClusterConfigIterator() const { + return m_clusterConfigIter; +} + +void +Configuration::calcSizeAlt(ConfigValues * ownConfig){ + const char * msg = "Invalid configuration fetched"; + char buf[255]; + + unsigned int noOfTables = 0; + unsigned int noOfIndexes = 0; + unsigned int noOfReplicas = 0; + unsigned int noOfDBNodes = 0; + unsigned int noOfAPINodes = 0; + unsigned int noOfMGMNodes = 0; + unsigned int noOfNodes = 0; + unsigned int noOfAttributes = 0; + unsigned int noOfOperations = 0; + unsigned int noOfTransactions = 0; + unsigned int noOfIndexPages = 0; + unsigned int noOfDataPages = 0; + unsigned int noOfScanRecords = 0; + m_logLevel = new LogLevel(); + + /** + * {"NoOfConcurrentCheckpointsDuringRestart", &cd.ispValues[1][5] }, + * {"NoOfConcurrentCheckpointsAfterRestart", &cd.ispValues[2][4] }, + * {"NoOfConcurrentProcessesHandleTakeover", &cd.ispValues[1][7] }, + * {"TimeToWaitAlive", &cd.ispValues[0][0] }, + */ + struct AttribStorage { int paramId; Uint32 * storage; }; + AttribStorage tmp[] = { + { CFG_DB_NO_SCANS, &noOfScanRecords }, + { CFG_DB_NO_TABLES, &noOfTables }, + { CFG_DB_NO_INDEXES, &noOfIndexes }, + { CFG_DB_NO_REPLICAS, &noOfReplicas }, + { CFG_DB_NO_ATTRIBUTES, &noOfAttributes }, + { CFG_DB_NO_OPS, &noOfOperations }, + { CFG_DB_NO_TRANSACTIONS, &noOfTransactions } +#if 0 + { "NoOfDiskPagesToDiskDuringRestartTUP", &cd.ispValues[3][8] }, + { "NoOfDiskPagesToDiskAfterRestartTUP", &cd.ispValues[3][9] }, + { "NoOfDiskPagesToDiskDuringRestartACC", &cd.ispValues[3][10] }, + { "NoOfDiskPagesToDiskAfterRestartACC", &cd.ispValues[3][11] }, +#endif + }; + + ndb_mgm_configuration_iterator db(*(ndb_mgm_configuration*)ownConfig, 0); + + const int sz = sizeof(tmp)/sizeof(AttribStorage); + for(int i = 0; i<sz; i++){ + if(ndb_mgm_get_int_parameter(&db, tmp[i].paramId, tmp[i].storage)){ + snprintf(buf, sizeof(buf), "ConfigParam: %d not found", tmp[i].paramId); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + } + + Uint64 indexMem = 0, dataMem = 0; + ndb_mgm_get_int64_parameter(&db, CFG_DB_DATA_MEM, &dataMem); + ndb_mgm_get_int64_parameter(&db, CFG_DB_INDEX_MEM, &indexMem); + if(dataMem == 0){ + snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_DATA_MEM); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + + if(indexMem == 0){ + snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_INDEX_MEM); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + + noOfDataPages = (dataMem / 8192); + noOfIndexPages = (indexMem / 8192); + + for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){ + Uint32 tmp; + if(!ndb_mgm_get_int_parameter(&db, LogLevel::MIN_LOGLEVEL_ID+j, &tmp)){ + m_logLevel->setLogLevel((LogLevel::EventCategory)j, tmp); + } + } + + // tmp + ndb_mgm_configuration_iterator * p = m_clusterConfigIter; + + Uint32 nodeNo = noOfNodes = 0; + NodeBitmask nodes; + for(ndb_mgm_first(p); ndb_mgm_valid(p); ndb_mgm_next(p), nodeNo++){ + + Uint32 nodeId; + Uint32 nodeType; + + if(ndb_mgm_get_int_parameter(p, CFG_NODE_ID, &nodeId)){ + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, "Node data (Id) missing"); + } + + if(ndb_mgm_get_int_parameter(p, CFG_TYPE_OF_SECTION, &nodeType)){ + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, "Node data (Type) missing"); + } + + if(nodeId > MAX_NODES || nodeId == 0){ + snprintf(buf, sizeof(buf), + "Invalid node id: %d", nodeId); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + + if(nodes.get(nodeId)){ + snprintf(buf, sizeof(buf), "Two node can not have the same node id: %d", + nodeId); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + nodes.set(nodeId); + + switch(nodeType){ + case NODE_TYPE_DB: + noOfDBNodes++; // No of NDB processes + + if(nodeId > MAX_NDB_NODES){ + snprintf(buf, sizeof(buf), "Maximum node id for a ndb node is: %d", + MAX_NDB_NODES); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + break; + case NODE_TYPE_API: + noOfAPINodes++; // No of API processes + break; + case NODE_TYPE_REP: + break; + case NODE_TYPE_MGM: + noOfMGMNodes++; // No of MGM processes + break; + case NODE_TYPE_EXT_REP: + break; + default: + snprintf(buf, sizeof(buf), "Unknown node type: %d", nodeType); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + } + noOfNodes = nodeNo; + + /** + * Do size calculations + */ + ConfigValuesFactory cfg(ownConfig); + + noOfTables++; // Remove impact of system table + noOfTables += noOfIndexes; // Indexes are tables too + noOfAttributes += 2; // ---"---- + noOfTables *= 2; // Remove impact of Dict need 2 ids for each table + + if (noOfDBNodes > 15) { + noOfDBNodes = 15; + }//if + Uint32 noOfLocalScanRecords = (noOfDBNodes * noOfScanRecords) + 1; + Uint32 noOfTCScanRecords = noOfScanRecords; + + { + /** + * Acc Size Alt values + */ + // Can keep 65536 pages (= 0.5 GByte) + cfg.put(CFG_ACC_DIR_RANGE, + 4 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_ACC_DIR_ARRAY, + (noOfIndexPages >> 8) + + 4 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_ACC_FRAGMENT, + 2 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + /*-----------------------------------------------------------------------*/ + // The extra operation records added are used by the scan and node + // recovery process. + // Node recovery process will have its operations dedicated to ensure + // that they never have a problem with allocation of the operation record. + // The remainder are allowed for use by the scan processes. + /*-----------------------------------------------------------------------*/ + cfg.put(CFG_ACC_OP_RECS, + noOfReplicas*((16 * noOfOperations) / 10 + 50) + + (noOfLocalScanRecords * MAX_PARALLEL_SCANS_PER_FRAG) + + NODE_RECOVERY_SCAN_OP_RECORDS); + + cfg.put(CFG_ACC_OVERFLOW_RECS, + noOfIndexPages + + 2 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_ACC_PAGE8, + noOfIndexPages + 32); + + cfg.put(CFG_ACC_ROOT_FRAG, + NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_ACC_TABLE, noOfTables); + + cfg.put(CFG_ACC_SCAN, noOfLocalScanRecords); + } + + { + /** + * Dict Size Alt values + */ + cfg.put(CFG_DICT_ATTRIBUTE, + noOfAttributes); + + cfg.put(CFG_DICT_CONNECT, + noOfOperations + 32); + + cfg.put(CFG_DICT_FRAG_CONNECT, + NO_OF_FRAG_PER_NODE * noOfDBNodes * noOfReplicas); + + cfg.put(CFG_DICT_TABLE, + noOfTables); + + cfg.put(CFG_DICT_TC_CONNECT, + 2* noOfOperations); + } + + { + /** + * Dih Size Alt values + */ + cfg.put(CFG_DIH_API_CONNECT, + 2 * noOfTransactions); + + cfg.put(CFG_DIH_CONNECT, + noOfOperations + 46); + + cfg.put(CFG_DIH_FRAG_CONNECT, + NO_OF_FRAG_PER_NODE * noOfTables * noOfDBNodes); + + int temp; + temp = noOfReplicas - 2; + if (temp < 0) + temp = 1; + else + temp++; + cfg.put(CFG_DIH_MORE_NODES, + temp * NO_OF_FRAG_PER_NODE * + noOfTables * noOfDBNodes); + + cfg.put(CFG_DIH_REPLICAS, + NO_OF_FRAG_PER_NODE * noOfTables * + noOfDBNodes * noOfReplicas); + + cfg.put(CFG_DIH_TABLE, + noOfTables); + } + + { + /** + * Lqh Size Alt values + */ + cfg.put(CFG_LQH_FRAG, + NO_OF_FRAG_PER_NODE * noOfTables * noOfReplicas); + + cfg.put(CFG_LQH_CONNECT, + noOfReplicas*((11 * noOfOperations) / 10 + 50)); + + cfg.put(CFG_LQH_TABLE, + noOfTables); + + cfg.put(CFG_LQH_TC_CONNECT, + noOfReplicas*((16 * noOfOperations) / 10 + 50)); + + cfg.put(CFG_LQH_REPLICAS, + noOfReplicas); + + cfg.put(CFG_LQH_SCAN, + noOfLocalScanRecords); + } + + { + /** + * Tc Size Alt values + */ + cfg.put(CFG_TC_API_CONNECT, + 3 * noOfTransactions); + + cfg.put(CFG_TC_TC_CONNECT, + noOfOperations + 16 + noOfTransactions); + + cfg.put(CFG_TC_TABLE, + noOfTables); + + cfg.put(CFG_TC_LOCAL_SCAN, + noOfLocalScanRecords); + + cfg.put(CFG_TC_SCAN, + noOfTCScanRecords); + } + + { + /** + * Tup Size Alt values + */ + cfg.put(CFG_TUP_FRAG, + 2 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_TUP_OP_RECS, + noOfReplicas*((16 * noOfOperations) / 10 + 50)); + + cfg.put(CFG_TUP_PAGE, + noOfDataPages); + + cfg.put(CFG_TUP_PAGE_RANGE, + 4 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_TUP_TABLE, + noOfTables); + + cfg.put(CFG_TUP_TABLE_DESC, + 4 * NO_OF_FRAG_PER_NODE * noOfAttributes* noOfReplicas + + 12 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas ); + + cfg.put(CFG_TUP_STORED_PROC, + noOfLocalScanRecords); + } + + { + /** + * Tux Size Alt values + */ + cfg.put(CFG_TUX_INDEX, + noOfTables); + + cfg.put(CFG_TUX_FRAGMENT, + 2 * NO_OF_FRAG_PER_NODE * noOfTables * noOfReplicas); + + cfg.put(CFG_TUX_ATTRIBUTE, + noOfIndexes * 4); + + cfg.put(CFG_TUX_SCAN_OP, noOfLocalScanRecords); + } + + m_ownConfig = (ndb_mgm_configuration*)cfg.getConfigValues(); + m_ownConfigIterator = ndb_mgm_create_configuration_iterator + (m_ownConfig, 0); +} + void Configuration::setInitialStart(bool val){ _initialStart = val; diff --git a/ndb/src/kernel/vm/Configuration.hpp b/ndb/src/kernel/vm/Configuration.hpp index 3f96bb454c5..1706ad05867 100644 --- a/ndb/src/kernel/vm/Configuration.hpp +++ b/ndb/src/kernel/vm/Configuration.hpp @@ -17,7 +17,8 @@ #ifndef Configuration_H #define Configuration_H -#include "ClusterConfiguration.hpp" +#include <mgmapi.h> +#include <ndb_types.h> class Configuration { public: @@ -46,35 +47,36 @@ public: void setRestartOnErrorInsert(int); // Cluster configuration - const ClusterConfiguration::ClusterData& clusterConfigurationData() const; - const ClusterConfiguration& clusterConfiguration() const; - const char * programName() const; const char * fileSystemPath() const; char * getConnectStringCopy() const; /** - * Return Properties for own node - */ - const Properties * getOwnProperties() const; - - /** * */ bool getInitialStart() const; void setInitialStart(bool val); bool getDaemonMode() const; - + + const ndb_mgm_configuration_iterator * getOwnConfigIterator() const; + + class LogLevel * m_logLevel; private: + friend class Cmvmi; + friend class Qmgr; + ndb_mgm_configuration_iterator * getClusterConfigIterator() const; + Uint32 _stopOnError; Uint32 m_restartOnErrorInsert; Uint32 _maxErrorLogs; Uint32 _lockPagesInMainMemory; Uint32 _timeBetweenWatchDogCheck; + ndb_mgm_configuration * m_ownConfig; + ndb_mgm_configuration * m_clusterConfig; - ClusterConfiguration the_clusterConfigurationData; - const Properties * m_ownProperties; + ndb_mgm_configuration_iterator * m_clusterConfigIter; + ndb_mgm_configuration_iterator * m_ownConfigIterator; /** * arguments to NDB process @@ -84,6 +86,8 @@ private: bool _initialStart; char * _connectString; bool _daemonMode; + + void calcSizeAlt(class ConfigValues * ); }; inline diff --git a/ndb/src/kernel/vm/FastScheduler.cpp b/ndb/src/kernel/vm/FastScheduler.cpp index e9ca4834562..eca456d26dd 100644 --- a/ndb/src/kernel/vm/FastScheduler.cpp +++ b/ndb/src/kernel/vm/FastScheduler.cpp @@ -316,14 +316,14 @@ APZJobBuffer::signal2buffer(Signal* signal, void APZJobBuffer::insert(const SignalHeader * const sh, const Uint32 * const theData, const Uint32 secPtrI[3]){ - Uint32 tOccupancy = theOccupancy; + Uint32 tOccupancy = theOccupancy + 1; Uint32 myWPtr = wPtr; register BufferEntry& buf = buffer[myWPtr]; if (tOccupancy < bufSize) { Uint32 cond = (++myWPtr == bufSize) - 1; wPtr = myWPtr & cond; - theOccupancy = tOccupancy + 1; + theOccupancy = tOccupancy; buf.header = * sh; const Uint32 len = buf.header.theLength; @@ -342,8 +342,9 @@ APZJobBuffer::insert(const SignalHeader * const sh, }//if } APZJobBuffer::APZJobBuffer() - : rPtr(0), wPtr(0), theOccupancy(0), bufSize(0), buffer(NULL), memRef(NULL) + : bufSize(0), buffer(NULL), memRef(NULL) { + clear(); } APZJobBuffer::~APZJobBuffer() @@ -354,9 +355,11 @@ APZJobBuffer::~APZJobBuffer() void APZJobBuffer::newBuffer(int size) { - buffer = new BufferEntry[size]; + buffer = new BufferEntry[size + 1]; // +1 to support "overrrun" if(buffer){ +#ifndef NDB_PURIFY ::memset(buffer, 0, (size * sizeof(BufferEntry))); +#endif bufSize = size; } else bufSize = 0; @@ -474,10 +477,11 @@ FastScheduler::reportDoJobStatistics(Uint32 tMeanLoopCount) { signal.theData[0] = EventReport::JobStatistic; signal.theData[1] = tMeanLoopCount; + memset(&signal.header, 0, sizeof(SignalHeader)); signal.header.theLength = 2; signal.header.theSendersSignalId = 0; signal.header.theSendersBlockRef = numberToRef(0, 0); - + execute(&signal, JBA, CMVMI, GSN_EVENT_REP); } diff --git a/ndb/src/kernel/vm/FastScheduler.hpp b/ndb/src/kernel/vm/FastScheduler.hpp index 586a7ea27ad..9749dab5d85 100644 --- a/ndb/src/kernel/vm/FastScheduler.hpp +++ b/ndb/src/kernel/vm/FastScheduler.hpp @@ -43,7 +43,7 @@ class BufferEntry { public: SignalHeader header; - Uint32 theDataRegister[28]; + Uint32 theDataRegister[25]; }; class APZJobBuffer @@ -68,7 +68,6 @@ public: void retrieveDump(Signal *signal, Uint32 myRptr); void clear(); - bool isEmpty() const; Uint32 getOccupancy() const; Uint32 getReadPtr() const; @@ -313,13 +312,13 @@ void APZJobBuffer::insert(Signal* signal, BlockNumber bnr, GlobalSignalNumber gsn) { - Uint32 tOccupancy = theOccupancy; + Uint32 tOccupancy = theOccupancy + 1; Uint32 myWPtr = wPtr; if (tOccupancy < bufSize) { register BufferEntry& buf = buffer[myWPtr]; Uint32 cond = (++myWPtr == bufSize) - 1; wPtr = myWPtr & cond; - theOccupancy = tOccupancy + 1; + theOccupancy = tOccupancy; signal2buffer(signal, bnr, gsn, buf); //--------------------------------------------------------- // Prefetch of buffer[wPtr] is done here. We prefetch for @@ -343,11 +342,4 @@ APZJobBuffer::insert(Signal* signal, BlockNumber bnr, signal2buffer(signal, bnr, gsn, buf); } -inline -bool -APZJobBuffer::isEmpty() const -{ - return (theOccupancy == 0); -} - #endif diff --git a/ndb/src/kernel/vm/Makefile_old b/ndb/src/kernel/vm/Makefile_old index 3f448b77b17..a162f3672ce 100644 --- a/ndb/src/kernel/vm/Makefile_old +++ b/ndb/src/kernel/vm/Makefile_old @@ -13,17 +13,18 @@ SOURCES = \ TransporterCallback.cpp \ Emulator.cpp \ Configuration.cpp \ - ClusterConfiguration.cpp \ WatchDog.cpp \ SimplePropertiesSection.cpp \ SectionReader.cpp \ MetaData.cpp \ Mutex.cpp SafeCounter.cpp +CFLAGS_Configuration.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) + DIRS := testCopy testDataBuffer testSimplePropertiesSection + ifneq ($(USE_EDITLINE), N) DIRS += testLongSig endif - include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/vm/SignalCounter.hpp b/ndb/src/kernel/vm/SignalCounter.hpp index d572551ea92..ea770324aa6 100644 --- a/ndb/src/kernel/vm/SignalCounter.hpp +++ b/ndb/src/kernel/vm/SignalCounter.hpp @@ -21,6 +21,8 @@ #include <ErrorReporter.hpp> class SignalCounter { + friend struct NodeReceiverGroup; + private: Uint32 m_count; NdbNodeBitmask m_nodes; diff --git a/ndb/src/kernel/vm/SimulatedBlock.cpp b/ndb/src/kernel/vm/SimulatedBlock.cpp index e3f087d7d74..a6a8a6242cd 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.cpp +++ b/ndb/src/kernel/vm/SimulatedBlock.cpp @@ -60,7 +60,8 @@ SimulatedBlock::SimulatedBlock(BlockNumber blockNumber, c_fragmentIdCounter = 1; c_fragSenderRunning = false; - const Properties * p = conf.getOwnProperties(); + Properties tmp; + const Properties * p = &tmp; ndbrequire(p != 0); Uint32 count = 10; @@ -98,7 +99,9 @@ SimulatedBlock::SimulatedBlock(BlockNumber blockNumber, for(GlobalSignalNumber i = 0; i<=MAX_GSN; i++) theExecArray[i] = 0; + installSimulatedBlockFunctions(); + UpgradeStartup::installEXEC(this); CLEAR_ERROR_INSERT_VALUE; } @@ -127,6 +130,7 @@ SimulatedBlock::installSimulatedBlockFunctions(){ a[GSN_UTIL_LOCK_CONF] = &SimulatedBlock::execUTIL_LOCK_CONF; a[GSN_UTIL_UNLOCK_REF] = &SimulatedBlock::execUTIL_UNLOCK_REF; a[GSN_UTIL_UNLOCK_CONF] = &SimulatedBlock::execUTIL_UNLOCK_CONF; + a[GSN_READ_CONFIG_REQ] = &SimulatedBlock::execREAD_CONFIG_REQ; } void @@ -182,7 +186,7 @@ SimulatedBlock::sendSignal(BlockReference ref, Uint32 tSignalId = signal->header.theSignalId; - if ((length == 0) || (length > 25) || (recBlock == 0)) { + if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) { signal_error(gsn, length, recBlock, __FILE__, __LINE__); return; }//if @@ -263,7 +267,7 @@ SimulatedBlock::sendSignal(NodeReceiverGroup rg, signal->header.theSendersSignalId = tSignalId; signal->header.theSendersBlockRef = reference(); - if ((length == 0) || (length > 25) || (recBlock == 0)) { + if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) { signal_error(gsn, length, recBlock, __FILE__, __LINE__); return; }//if @@ -371,7 +375,7 @@ SimulatedBlock::sendSignal(BlockReference ref, Uint32 tSignalId = signal->header.theSignalId; Uint32 tFragInfo = signal->header.m_fragmentInfo; - if ((length == 0) || (length > 25) || (recBlock == 0)) { + if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) { signal_error(gsn, length, recBlock, __FILE__, __LINE__); return; }//if @@ -464,7 +468,7 @@ SimulatedBlock::sendSignal(NodeReceiverGroup rg, signal->header.theSendersBlockRef = reference(); signal->header.m_noOfSections = noOfSections; - if ((length == 0) || (length > 25) || (recBlock == 0)) { + if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) { signal_error(gsn, length, recBlock, __FILE__, __LINE__); return; }//if @@ -1338,7 +1342,7 @@ SimulatedBlock::sendFirstFragment(FragmentSendInfo & info, */ return true; } - + /** * Setup info object */ @@ -1724,9 +1728,52 @@ void SimulatedBlock::execUTIL_UNLOCK_CONF(Signal* signal){ c_mutexMgr.execUTIL_UNLOCK_CONF(signal); } +void +SimulatedBlock::execREAD_CONFIG_REQ(Signal* signal){ + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = senderData; + sendSignal(ref, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); +} + void SimulatedBlock::ignoreMutexUnlockCallback(Signal* signal, Uint32 ptrI, Uint32 retVal){ c_mutexMgr.release(ptrI); } +void +UpgradeStartup::installEXEC(SimulatedBlock* block){ + SimulatedBlock::ExecFunction * a = block->theExecArray; + switch(block->number()){ + case QMGR: + a[UpgradeStartup::GSN_CM_APPCHG] = &SimulatedBlock::execUPGRADE; + break; + case CNTR: + a[UpgradeStartup::GSN_CNTR_MASTERREF] = &SimulatedBlock::execUPGRADE; + a[UpgradeStartup::GSN_CNTR_MASTERCONF] = &SimulatedBlock::execUPGRADE; + break; + } +} + +void +SimulatedBlock::execUPGRADE(Signal* signal){ + Uint32 gsn = signal->header.theVerId_signalNumber; + switch(gsn){ + case UpgradeStartup::GSN_CM_APPCHG: + UpgradeStartup::execCM_APPCHG(* this, signal); + break; + case UpgradeStartup::GSN_CNTR_MASTERREF: + UpgradeStartup::execCNTR_MASTER_REPLY(* this, signal); + break; + case UpgradeStartup::GSN_CNTR_MASTERCONF: + UpgradeStartup::execCNTR_MASTER_REPLY(* this, signal); + break; + } +} diff --git a/ndb/src/kernel/vm/SimulatedBlock.hpp b/ndb/src/kernel/vm/SimulatedBlock.hpp index 42b8a3034f5..491d432625e 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -45,6 +45,16 @@ #include "SafeCounter.hpp" #include "MetaData.hpp" +#include <mgmapi.h> +#include <mgmapi_config_parameters.h> +#include <mgmapi_config_parameters_debug.h> +#include <kernel_config_parameters.h> +#include <Configuration.hpp> + +#include <signaldata/ReadConfig.hpp> +#include <signaldata/UpgradeStartup.hpp> + + /** * Something for filesystem access */ @@ -70,6 +80,7 @@ class SimulatedBlock { friend class MutexManager; friend class SafeCounter; friend class SafeCounterManager; + friend struct UpgradeStartup; public: friend class BlockComponent; virtual ~SimulatedBlock(); @@ -378,7 +389,7 @@ private: void execSIGNAL_DROPPED_REP(Signal* signal); void execCONTINUE_FRAGMENTED(Signal* signal); - + Uint32 c_fragmentIdCounter; ArrayPool<FragmentInfo> c_fragmentInfoPool; DLHashTable<FragmentInfo> c_fragmentInfoHash; @@ -404,7 +415,9 @@ private: void execUTIL_UNLOCK_REF(Signal* signal); void execUTIL_UNLOCK_CONF(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); protected: + void execUPGRADE(Signal* signal); // Variable for storing inserted errors, see pc.H ERROR_INSERT_VARIABLE; diff --git a/ndb/src/kernel/vm/TransporterCallback.cpp b/ndb/src/kernel/vm/TransporterCallback.cpp index 3798e4040c8..eb7d138895c 100644 --- a/ndb/src/kernel/vm/TransporterCallback.cpp +++ b/ndb/src/kernel/vm/TransporterCallback.cpp @@ -206,6 +206,7 @@ execute(void * callbackObj, LinearSectionPtr ptr[3]){ const Uint32 secCount = header->m_noOfSections; + const Uint32 length = header->theLength; #ifdef TRACE_DISTRIBUTED ndbout_c("recv: %s(%d) from (%s, %d)", @@ -225,6 +226,11 @@ execute(void * callbackObj, case 1: ok &= import(secPtr[0], ptr[0].p, ptr[0].sz); } + + /** + * Check that we haven't received a too long signal + */ + ok &= (length + secCount <= 25); Uint32 secPtrI[3]; if(ok){ @@ -234,6 +240,7 @@ execute(void * callbackObj, secPtrI[0] = secPtr[0].i; secPtrI[1] = secPtr[1].i; secPtrI[2] = secPtr[2].i; + globalScheduler.execute(header, prio, theData, secPtrI); return; } diff --git a/ndb/src/kernel/vm/VMSignal.hpp b/ndb/src/kernel/vm/VMSignal.hpp index 45e731f2079..9111ee7949c 100644 --- a/ndb/src/kernel/vm/VMSignal.hpp +++ b/ndb/src/kernel/vm/VMSignal.hpp @@ -34,6 +34,7 @@ struct NodeReceiverGroup { NodeReceiverGroup(); NodeReceiverGroup(Uint32 blockRef); NodeReceiverGroup(Uint32 blockNo, const NodeBitmask &); + NodeReceiverGroup(Uint32 blockNo, const class SignalCounter &); NodeReceiverGroup& operator=(BlockReference ref); @@ -171,6 +172,14 @@ NodeReceiverGroup::NodeReceiverGroup(Uint32 blockNo, const NodeBitmask & nodes){ m_nodes = nodes; } +#include "SignalCounter.hpp" + +inline +NodeReceiverGroup::NodeReceiverGroup(Uint32 blockNo, const SignalCounter & nodes){ + m_block = blockNo; + m_nodes = nodes.m_nodes; +} + inline NodeReceiverGroup& NodeReceiverGroup::operator=(BlockReference blockRef){ diff --git a/ndb/src/kernel/vm/pc.hpp b/ndb/src/kernel/vm/pc.hpp index 873a986bc35..849799a47f3 100644 --- a/ndb/src/kernel/vm/pc.hpp +++ b/ndb/src/kernel/vm/pc.hpp @@ -116,12 +116,6 @@ #define arrGuard(ind, size) #endif -// ------- EVENT STATES OF A NODE ----------------------------- -#define ZADD 0 /* New application added */ -#define ZREMOVE 1 /* An application has been removed */ -#define ZSTART 2 /* An application is ready to start */ -#define ZRUN 3 /* An application has started to run */ - // -------- ERROR INSERT MACROS ------- #ifdef ERROR_INSERT #define ERROR_INSERT_VARIABLE UintR cerrorInsert diff --git a/ndb/src/kernel/vm/testLongSig/testLongSig.cpp b/ndb/src/kernel/vm/testLongSig/testLongSig.cpp index af4e2ca6e24..1d1fb8ebc82 100644 --- a/ndb/src/kernel/vm/testLongSig/testLongSig.cpp +++ b/ndb/src/kernel/vm/testLongSig/testLongSig.cpp @@ -39,6 +39,7 @@ print_help(){ ndbout << "11 - Sending of CONTINUEB fragmented signals w/ linear sections" << endl; ndbout << "12 - As but using receiver group" << endl; + ndbout << "13 - Send 100 * 1000 25 len signals wo/ sections" << endl; ndbout << "r - Recive signal from anyone" << endl; ndbout << "a - Run tests 1 - 12 with variable sizes - 10 loops" << endl; ndbout << "b - Run tests 1 - 12 with variable sizes - 100 loops" << endl; @@ -103,7 +104,7 @@ main(void){ data[5] = 70; data[6] = 123; data[7] = 10; - const Uint32 theDataLen = 8; + const Uint32 theDataLen = 18; for(Uint32 i = 0; i<70; i++) sec0[i] = i; @@ -198,6 +199,38 @@ main(void){ delete ret1; count--; } + } else if (data[1] == 13) { + const Uint32 count = 3500; + const Uint32 loop = 1000; + + signal1.set(ss, 0, CMVMI, GSN_TESTSIG, 25); + signal1.header.m_fragmentInfo = 0; + signal1.header.m_noOfSections = 0; + signal1.theData[1] = 14; + signal1.theData[3] = 0; // Print + signal1.theData[8] = count; + signal1.theData[9] = loop; + Uint32 nodeId = ss.getAliveNode(); + ndbout_c("Sending 25 len signal to node %d", nodeId); + ss.sendSignal(nodeId, &signal1); + + Uint32 total; + { + SimpleSignal * ret1 = ss.waitFor((Uint16)nodeId); + ndbout_c("received from node %d", + refToNode(ret1->header.theSendersBlockRef)); + total = ret1->theData[10] - 1; + delete ret1; + } + + do { + ndbout << "Waiting for " << total << " signals... " << flush; + SimpleSignal * ret1 = ss.waitFor((Uint16)nodeId); + ndbout_c("received from node %d", + refToNode(ret1->header.theSendersBlockRef)); + delete ret1; + total --; + } while(total > 0); } else { print_help(); } @@ -218,7 +251,6 @@ runTest(SignalSender & ss, Uint32 count, bool verbose){ sec2[i] = i * i; } - sig.set(ss, 0, CMVMI, GSN_TESTSIG, 8); sig.theData[0] = ss.getOwnRef(); sig.theData[1] = 1; // TestType sig.theData[2] = 128; // FragSize @@ -236,6 +268,8 @@ runTest(SignalSender & ss, Uint32 count, bool verbose){ sig.ptr[1].sz = randRange(1, 256); sig.ptr[2].sz = randRange(1, 256); sig.header.m_noOfSections = secs; + const Uint32 len = 5 + (secs > 0 ? 1 : 0) * (25 - 5 - 7); + sig.set(ss, 0, CMVMI, GSN_TESTSIG, len); ndbout << "Loop " << loop << " #secs = " << secs << " sizes = [ "; unsigned min = 256; unsigned max = 0; @@ -248,7 +282,7 @@ runTest(SignalSender & ss, Uint32 count, bool verbose){ sum += sz; sig.theData[5+i] = sz; } - ndbout_c("]"); + ndbout_c("] len = %d", len); for(int test = 1; test <= 12; test++){ sig.theData[1] = test; Uint32 nodeId = ss.getAliveNode(); diff --git a/ndb/src/mgmapi/Makefile_old b/ndb/src/mgmapi/Makefile_old index 9e7ba4f5ac7..fa734f998e6 100644 --- a/ndb/src/mgmapi/Makefile_old +++ b/ndb/src/mgmapi/Makefile_old @@ -15,7 +15,7 @@ LIB_TARGET := MGM_API LIB_TARGET_ARCHIVES := $(ARCHIVE_TARGET) general portlib # Source files of non-templated classes (.C files) -SOURCES = mgmapi.cpp +SOURCES = mgmapi.cpp mgmapi_configuration.cpp CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index fcdfe943fb1..72ba282ad13 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -19,6 +19,7 @@ #include <NdbTCP.h> #include "mgmapi.h" #include "mgmapi_debug.h" +#include "mgmapi_configuration.hpp" #include <socket_io.h> #include <NdbOut.hpp> @@ -26,6 +27,7 @@ #include <Parser.hpp> #include <OutputStream.hpp> #include <InputStream.hpp> +#include <Base64.hpp> #define MGM_CMD(name, fun, desc) \ @@ -93,15 +95,20 @@ struct ndb_mgm_handle { #endif }; -#define SET_ERROR(h, e, s) \ - { \ - char tmp[NDB_MGM_MAX_ERR_DESC_SIZE]; \ - snprintf(tmp, NDB_MGM_MAX_ERR_DESC_SIZE, " (mgmapi.cpp:%d)", __LINE__); \ - strncpy(h->last_error_desc, s, NDB_MGM_MAX_ERR_DESC_SIZE); \ - strncat(h->last_error_desc, tmp, NDB_MGM_MAX_ERR_DESC_SIZE); \ - h->last_error = e; \ - h->last_error_line = __LINE__; \ - } +#define SET_ERROR(h, e, s) setError(h, e, __LINE__, s) + +static +void +setError(NdbMgmHandle h, int error, int error_line, const char * msg, ...){ + + h->last_error = error; \ + h->last_error_line = error_line; + + va_list ap; + va_start(ap, msg); + vsnprintf(h->last_error_desc, sizeof(h->last_error_desc), msg, ap); + va_end(ap); +} #define CHECK_HANDLE(handle, ret) \ if(handle == 0) { \ @@ -185,9 +192,12 @@ ndb_mgm_get_latest_error(const NdbMgmHandle h) return h->last_error; } -/** - * Get latest error line associated with a handle - */ +extern "C" +const char * +ndb_mgm_get_latest_error_desc(const NdbMgmHandle h){ + return h->last_error_desc; +} + extern "C" int ndb_mgm_get_latest_error_line(const NdbMgmHandle h) @@ -207,13 +217,6 @@ ndb_mgm_get_latest_error_msg(const NdbMgmHandle h) return "Error"; // Unknown Error message } -extern "C" -const char * -ndb_mgm_get_latest_error_desc(const NdbMgmHandle h) -{ - return h->last_error_desc; -} - static int parse_connect_string(const char * connect_string, @@ -372,7 +375,8 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv) // Convert ip address presentation format to numeric format const int res1 = Ndb_getInAddr(&servaddr.sin_addr, handle->hostname); if (res1 != 0) { - SET_ERROR(handle, NDB_MGM_ILLEGAL_IP_ADDRESS, ""); + DEBUG("Ndb_getInAddr(...) == -1"); + setError(handle, EINVAL, __LINE__, "Invalid hostname/address"); return -1; } @@ -380,7 +384,8 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv) sizeof(servaddr)); if (res2 == -1) { NDB_CLOSE_SOCKET(sockfd); - SET_ERROR(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, ""); + setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, "Unable to connect to %s", + mgmsrv); return -1; } @@ -389,7 +394,7 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv) return 0; } - + /** * Disconnect from a mgm server */ @@ -514,6 +519,8 @@ status_ackumulate(struct ndb_mgm_node_state * state, state->node_group = atoi(value); } else if(strcmp("version", field) == 0){ state->version = atoi(value); + } else if(strcmp("connect_count", field) == 0){ + state->connect_count = atoi(value); } else { ndbout_c("Unknown field: %s", field); } @@ -1422,10 +1429,103 @@ ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId, return 0; } +extern "C" +struct ndb_mgm_configuration * +ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) { + + CHECK_HANDLE(handle, 0); + CHECK_CONNECTED(handle, 0); + + Properties args; + args.put("version", version); + + const ParserRow<ParserDummy> reply[] = { + MGM_CMD("get config reply", NULL, ""), + MGM_ARG("result", String, Mandatory, "Error message"), + MGM_ARG("Content-Length", Int, Optional, "Content length in bytes"), + MGM_ARG("Content-Type", String, Optional, "Type (octet-stream)"), + MGM_ARG("Content-Transfer-Encoding", String, Optional, "Encoding(base64)"), + MGM_END() + }; + + const Properties *prop; + prop = ndb_mgm_call(handle, reply, "get config", &args); + + if(prop == NULL) { + SET_ERROR(handle, EIO, "Unable to fetch config"); + return 0; + } + + do { + const char * buf; + if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ + ndbout_c("ERROR Message: %s\n", buf); + break; + } + + buf = "<Unspecified>"; + if(!prop->get("Content-Type", &buf) || + strcmp(buf, "ndbconfig/octet-stream") != 0){ + ndbout_c("Unhandled response type: %s", buf); + break; + } + + buf = "<Unspecified>"; + if(!prop->get("Content-Transfer-Encoding", &buf) + || strcmp(buf, "base64") != 0){ + ndbout_c("Unhandled encoding: %s", buf); + break; + } + + buf = "<Content-Length Unspecified>"; + Uint32 len = 0; + if(!prop->get("Content-Length", &len)){ + ndbout_c("Invalid response: %s\n", buf); + break; + } + + len += 1; // Trailing \n + + char* buf64 = new char[len]; + int read = 0; + size_t start = 0; + do { + if((read = read_socket(handle->socket, handle->read_timeout, + &buf64[start], len-start)) == -1){ + delete[] buf64; + buf64 = 0; + break; + } + start += read; + } while(start < len); + if(buf64 == 0) + break; + + UtilBuffer tmp; + const int res = base64_decode(buf64, len-1, tmp); + delete[] buf64; + if(res != 0){ + ndbout_c("Failed to decode buffer"); + break; + } + + ConfigValuesFactory cvf; + const int res2 = cvf.unpack(tmp); + if(!res2){ + ndbout_c("Failed to unpack buffer"); + break; + } + + return (ndb_mgm_configuration*)cvf.m_cfg; + } while(0); + + delete prop; + return 0; +} + /***************************************************************************** * Global Replication - *****************************************************************************/ - + ******************************************************************************/ extern "C" int ndb_mgm_rep_command(NdbMgmHandle handle, unsigned int request, diff --git a/ndb/src/mgmapi/mgmapi_configuration.cpp b/ndb/src/mgmapi/mgmapi_configuration.cpp new file mode 100644 index 00000000000..ae7fe2c294c --- /dev/null +++ b/ndb/src/mgmapi/mgmapi_configuration.cpp @@ -0,0 +1,157 @@ +#include <mgmapi.h> +#include "mgmapi_configuration.hpp" +#include <new> + +ndb_mgm_configuration_iterator::ndb_mgm_configuration_iterator +(const ndb_mgm_configuration & conf, unsigned type_of_section) + : m_config(conf.m_config) +{ + m_sectionNo = ~0; + m_typeOfSection = type_of_section; + first(); +} + +ndb_mgm_configuration_iterator::~ndb_mgm_configuration_iterator(){ + reset(); +} + +void +ndb_mgm_configuration_iterator::reset(){ + if(m_sectionNo != (Uint32)~0){ + m_config.closeSection(); + } +} + + +int +ndb_mgm_configuration_iterator::enter(){ + bool ok = m_config.openSection(m_typeOfSection, m_sectionNo); + if(ok){ + return 0; + } + + reset(); + m_sectionNo = ~0; + return -1; +} + +int +ndb_mgm_configuration_iterator::first(){ + reset(); + m_sectionNo = 0; + return enter(); +} + +int +ndb_mgm_configuration_iterator::next(){ + reset(); + m_sectionNo++; + return enter(); +} + +int +ndb_mgm_configuration_iterator::valid() const { + return m_sectionNo != (Uint32)~0; +} + +int +ndb_mgm_configuration_iterator::find(int param, unsigned search){ + unsigned val = search + 1; + + while(get(param, &val) == 0 && val != search){ + if(next() != 0) + break; + } + + if(val == search) + return 0; + + return -1; +} + +int +ndb_mgm_configuration_iterator::get(int param, unsigned * value) const { + return m_config.get(param, value) != true; + +} + +int +ndb_mgm_configuration_iterator::get(int param, + unsigned long long * value) const{ + return m_config.get(param, value) != true; +} + +int +ndb_mgm_configuration_iterator::get(int param, const char ** value) const { + return m_config.get(param, value) != true; +} + +/** + * Published C interface + */ +extern "C" +ndb_mgm_configuration_iterator* +ndb_mgm_create_configuration_iterator(ndb_mgm_configuration * conf, + unsigned type_of_section){ + ndb_mgm_configuration_iterator* iter = (ndb_mgm_configuration_iterator*) + malloc(sizeof(ndb_mgm_configuration_iterator)); + if(iter == 0) + return 0; + + return new(iter) ndb_mgm_configuration_iterator(* conf, type_of_section); +} + + +extern "C" +void ndb_mgm_destroy_iterator(ndb_mgm_configuration_iterator* iter){ + if(iter != 0){ + iter->~ndb_mgm_configuration_iterator(); + free(iter); + } +} + +extern "C" +int +ndb_mgm_first(ndb_mgm_configuration_iterator* iter){ + return iter->first(); +} + +extern "C" +int +ndb_mgm_next(ndb_mgm_configuration_iterator* iter){ + return iter->next(); +} + +extern "C" +int +ndb_mgm_valid(const ndb_mgm_configuration_iterator* iter){ + return iter->valid(); +} + +extern "C" +int +ndb_mgm_get_int_parameter(const ndb_mgm_configuration_iterator* iter, + int param, unsigned * value){ + return iter->get(param, value); +} + +extern "C" +int +ndb_mgm_get_int64_parameter(const ndb_mgm_configuration_iterator* iter, + int param, unsigned long long * value){ + return iter->get(param, value); +} + +extern "C" +int +ndb_mgm_get_string_parameter(const ndb_mgm_configuration_iterator* iter, + int param, const char ** value){ + return iter->get(param, value); +} + +extern "C" +int +ndb_mgm_find(ndb_mgm_configuration_iterator* iter, + int param, unsigned search){ + return iter->find(param, search); +} diff --git a/ndb/src/mgmapi/mgmapi_configuration.hpp b/ndb/src/mgmapi/mgmapi_configuration.hpp new file mode 100644 index 00000000000..c7feffd3a4e --- /dev/null +++ b/ndb/src/mgmapi/mgmapi_configuration.hpp @@ -0,0 +1,32 @@ +#ifndef MGMAPI_CONFIGURATION_HPP +#define MGMAPI_CONFIGURATION_HPP + +#include <ConfigValues.hpp> + +struct ndb_mgm_configuration { + ConfigValues m_config; +}; + +struct ndb_mgm_configuration_iterator { + Uint32 m_sectionNo; + Uint32 m_typeOfSection; + ConfigValues::ConstIterator m_config; + + ndb_mgm_configuration_iterator(const ndb_mgm_configuration &, unsigned type); + ~ndb_mgm_configuration_iterator(); + + int first(); + int next(); + int valid() const; + int find(int param, unsigned value); + + int get(int param, unsigned * value) const ; + int get(int param, unsigned long long * value) const ; + int get(int param, const char ** value) const ; + + // + void reset(); + int enter(); +}; + +#endif diff --git a/ndb/src/mgmapi/test/keso.c b/ndb/src/mgmapi/test/keso.c index d5086b20b6a..d2675b2ca8a 100644 --- a/ndb/src/mgmapi/test/keso.c +++ b/ndb/src/mgmapi/test/keso.c @@ -29,6 +29,7 @@ static int testConnect(NdbMgmHandle h, struct ndb_mgm_reply* reply); static int testDisconnect(NdbMgmHandle h, struct ndb_mgm_reply* reply); static int testStatus(NdbMgmHandle h, struct ndb_mgm_reply* reply); +static int testGetConfig(NdbMgmHandle h, struct ndb_mgm_reply* reply); #ifdef VM_TRACE static int testLogSignals(NdbMgmHandle h, struct ndb_mgm_reply* reply); static int testStartSignalLog(NdbMgmHandle h, struct ndb_mgm_reply* reply); @@ -152,6 +153,19 @@ int testDisconnect(NdbMgmHandle h, struct ndb_mgm_reply* reply) { } static +int testGetConfig(NdbMgmHandle h, struct ndb_mgm_reply* reply) { + int i = 0; + struct ndb_mgm_configuration * config = ndb_mgm_get_configuration(h, 0); + if (config != NULL) { + free(config); + } else { + ndbout_c("Unable to get config"); + return -1; + } + return 0; +} + +static int testStatus(NdbMgmHandle h, struct ndb_mgm_reply* reply) { int i = 0; struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h); diff --git a/ndb/src/mgmclient/Makefile_old b/ndb/src/mgmclient/Makefile_old index 9f9a6344ab9..d1b2d60a52a 100644 --- a/ndb/src/mgmclient/Makefile_old +++ b/ndb/src/mgmclient/Makefile_old @@ -4,7 +4,7 @@ TYPE := ndbapi BIN_TARGET := mgmtclient BIN_TARGET_LIBS := -BIN_TARGET_ARCHIVES := trace logger general mgmapi mgmsrvcommon portlib repapi +BIN_TARGET_ARCHIVES := trace logger mgmapi general mgmsrvcommon portlib repapi BIN_TARGET_ARCHIVES += editline diff --git a/ndb/src/mgmsrv/CommandInterpreter.cpp b/ndb/src/mgmsrv/CommandInterpreter.cpp index 8a7293b8434..cda613a5ef2 100644 --- a/ndb/src/mgmsrv/CommandInterpreter.cpp +++ b/ndb/src/mgmsrv/CommandInterpreter.cpp @@ -453,14 +453,15 @@ void CommandInterpreter::executeShow(char* parameters) { return; } else if (strcmp(parameters, "PROPERTIES") == 0 || strcmp(parameters, "PROP") == 0) { - _mgmtSrvr.getConfig()->print(); + ndbout << "_mgmtSrvr.getConfig()->print();" << endl; /* XXX */ } else if (strcmp(parameters, "CONFIGURATION") == 0 || strcmp(parameters, "CONFIG") == 0){ + ndbout << "_mgmtSrvr.getConfigFile()->print();" << endl; /* XXX */ _mgmtSrvr.getConfig()->printConfigFile(); } else if (strcmp(parameters, "PARAMETERS") == 0 || strcmp(parameters, "PARAMS") == 0 || strcmp(parameters, "PARAM") == 0) { - _mgmtSrvr.getConfig()->getConfigInfo()->print(); + ndbout << "_mgmtSrvr.getConfigInfo()->print();" << endl; /* XXX */ } else { ndbout << "Invalid argument." << endl; } @@ -773,11 +774,11 @@ void CommandInterpreter::executeStatus(int processId, } ndb_mgm_node_status status; - Uint32 startPhase, version, dynamicId, nodeGroup; + Uint32 startPhase, version, dynamicId, nodeGroup, connectCount; bool system; int result = _mgmtSrvr.status(processId, &status, &version, &startPhase, &system, - &dynamicId, &nodeGroup); + &dynamicId, &nodeGroup, &connectCount); if(result != 0){ ndbout << _mgmtSrvr.getErrorText(result) << endl; return; diff --git a/ndb/src/mgmsrv/Makefile_old b/ndb/src/mgmsrv/Makefile_old index b10bdb64d30..c99875ae8b6 100644 --- a/ndb/src/mgmsrv/Makefile_old +++ b/ndb/src/mgmsrv/Makefile_old @@ -1,10 +1,10 @@ include .defs.mk -TYPE := ndbapi +TYPE := ndbapi mgmapiclient BIN_TARGET := mgmtsrvr BIN_TARGET_LIBS := -BIN_TARGET_ARCHIVES := mgmapi NDB_API mgmsrvcommon +BIN_TARGET_ARCHIVES := NDB_API mgmsrvcommon mgmapi general ifneq ($(USE_EDITLINE), N) BIN_TARGET_ARCHIVES += editline @@ -31,6 +31,7 @@ SOURCES += CommandInterpreter.cpp endif CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/src/ndbapi) \ + -I$(call fixpath,$(NDB_TOP)/src/mgmapi) \ -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 34ef9dbb08e..713433cb8e9 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -28,7 +28,6 @@ #include <GlobalSignalNumbers.h> #include <signaldata/TestOrd.hpp> #include <signaldata/TamperOrd.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/StartOrd.hpp> #include <signaldata/ApiVersion.hpp> #include <signaldata/ResumeReq.hpp> @@ -48,6 +47,10 @@ #include "NodeLogLevel.hpp" #include <NdbConfig.h> +#include <mgmapi.h> +#include <mgmapi_configuration.hpp> +#include <mgmapi_config_parameters.h> + //#define MGM_SRV_DEBUG #ifdef MGM_SRV_DEBUG #define DEBUG(x) do ndbout << x << endl; while(0) @@ -224,19 +227,33 @@ void MgmtSrvr::startEventLog() { g_EventLogger.setCategory("MgmSrvr"); - const Properties *mgmProps; - _config->get("Node", _ownNodeId, &mgmProps); + + ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator + ((ndb_mgm_configuration*)_config->m_configValues, CFG_SECTION_NODE); + if(iter == 0) + return ; + + if(ndb_mgm_find(iter, CFG_NODE_ID, _ownNodeId) != 0){ + ndb_mgm_destroy_iterator(iter); + return ; + } + + const char * tmp; BaseString logdest; char clusterLog[MAXPATHLEN]; - NdbConfig_ClusterLogFileName(clusterLog, sizeof(clusterLog)); - - mgmProps->get("LogDestination", logdest); - + + + if(ndb_mgm_get_string_parameter(iter, CFG_LOG_DESTINATION, &tmp) == 0){ + logdest.assign(tmp); + } + ndb_mgm_destroy_iterator(iter); + if(logdest.length()==0) { - logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6", clusterLog); + logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6", + clusterLog); } - + if(!g_EventLogger.addHandler(logdest)) { ndbout << "ERROR: cannot parse \"" << logdest << "\"" << endl; exit(1); @@ -374,8 +391,8 @@ MgmtSrvr::getNodeCount(enum ndb_mgm_node_type type) const } int -MgmtSrvr::getStatPort() const -{ +MgmtSrvr::getStatPort() const { +#if 0 const Properties *mgmProps; if(!getConfig()->get("Node", _ownNodeId, &mgmProps)) return -1; @@ -385,12 +402,16 @@ MgmtSrvr::getStatPort() const return -1; return tmp; +#else + return -1; +#endif } /* Constructor */ MgmtSrvr::MgmtSrvr(NodeId nodeId, const BaseString &configFilename, - const BaseString &ndb_config_filename): + const BaseString &ndb_config_filename, + Config * config): _blockNumber(1), // Hard coded block number since it makes it easy to send // signals to other management servers. _ownReference(0), @@ -415,8 +436,8 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, m_nextConfigGenerationNumber = 0; - _config = readConfig(); - + _config = (config == 0 ? readConfig() : config); + theMgmtWaitForResponseCondPtr = NdbCondition_Create(); m_configMutex = NdbMutex_Create(); @@ -427,31 +448,38 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, for(Uint32 i = 0; i<MAX_NODES; i++) nodeTypes[i] = (enum ndb_mgm_node_type)-1; - Properties::Iterator it(_config); - const char * name; - for(name = it.first(); name != NULL; name = it.next()){ - if(strncmp(name, "Node_", strlen("Node_")) == 0){ - const Properties * tmp; + 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) + continue; - _config->get(name, &tmp); - - Uint32 nodeId; - BaseString type; - MGM_REQUIRE(tmp->get("Id", &nodeId)); - MGM_REQUIRE(tmp->get("Type", type)); - MGM_REQUIRE(nodeId < MAX_NODES); + if(ndb_mgm_get_int_parameter(iter, CFG_NODE_ID, &id) != 0) + continue; + + MGM_REQUIRE(id < MAX_NODES); - if(type == "MGM") - nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_MGM; - if(type == "API") - nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_API; - if(type == "DB") - nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_NDB; - if(type == "REP") - nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_API; + switch(type){ + case NODE_TYPE_DB: + nodeTypes[id] = NDB_MGM_NODE_TYPE_NDB; + break; + case NODE_TYPE_API: + nodeTypes[id] = NDB_MGM_NODE_TYPE_API; + break; + case NODE_TYPE_MGM: + nodeTypes[id] = NDB_MGM_NODE_TYPE_MGM; + break; + case NODE_TYPE_REP: + nodeTypes[id] = NDB_MGM_NODE_TYPE_REP; + break; + case NODE_TYPE_EXT_REP: + default: + break; } } - + ndb_mgm_destroy_iterator(iter); + m_statisticsListner = NULL; _nodeLogLevelList = new NodeLogLevelList(); @@ -471,13 +499,6 @@ MgmtSrvr::check_start() return false; } - _props = new Config(* _config); - if (_props == 0) { - DEBUG("MgmtSrvr.cpp: Object props is NULL."); - return false; - } - MGM_REQUIRE(_props->put("LocalNodeId", _ownNodeId, true)); - return true; } @@ -488,11 +509,10 @@ MgmtSrvr::start() if (!check_start()) return false; } + theFacade = TransporterFacade::start_instance + (_ownNodeId, + (ndb_mgm_configuration*)_config->m_configValues); - theFacade = TransporterFacade::start_instance(_props, NULL); - delete _props; - _props = NULL; - if(theFacade == 0) { DEBUG("MgmtSrvr.cpp: theFacade is NULL."); return false; @@ -505,14 +525,14 @@ MgmtSrvr::start() _blockNumber = theFacade->open(this, signalReceivedNotification, nodeStatusNotification); - + if(_blockNumber == -1){ DEBUG("MgmtSrvr.cpp: _blockNumber is -1."); theFacade->stop_instance(); theFacade = 0; return false; } - + _ownReference = numberToRef(_blockNumber, _ownNodeId); startEventLog(); @@ -557,7 +577,11 @@ MgmtSrvr::~MgmtSrvr() NdbMutex_Destroy(m_configMutex); if(m_newConfig != NULL) - delete m_newConfig; + free(m_newConfig); + + if(_config != NULL) + delete _config; + delete _nodeLogLevelList; delete _clusterLogLevelList; @@ -812,9 +836,10 @@ MgmtSrvr::restart(bool nostart, bool initalStart, bool abort, s = NDB_MGM_NODE_STATUS_NO_CONTACT; while (s == NDB_MGM_NODE_STATUS_NO_CONTACT && waitTime > 0) { Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0; + Uint32 connectCount = 0; bool system; status(nodeId, &s, &version, &startPhase, - &system, &dynamicId, &nodeGroup); + &system, &dynamicId, &nodeGroup, &connectCount); NdbSleep_MilliSleep(100); waitTime = (maxTime - NdbTick_CurrentMillisecond()); } @@ -1297,7 +1322,8 @@ MgmtSrvr::status(int processId, Uint32 * _phase, bool * _system, Uint32 * dynamic, - Uint32 * nodegroup) + Uint32 * nodegroup, + Uint32 * connectCount) { if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API) { if(versionNode(processId, false,0,0) ==0) @@ -1324,7 +1350,8 @@ MgmtSrvr::status(int processId, * dynamic = node.m_state.dynamicId; * nodegroup = node.m_state.nodeGroup; - + * connectCount = node.m_info.m_connectCount; + switch(node.m_state.startLevel){ case NodeState::SL_CMVMI: * _status = NDB_MGM_NODE_STATUS_NOT_STARTED; @@ -1375,11 +1402,11 @@ MgmtSrvr::status(int processId, * _phase = 0; return 0; } - + return -1; } - - + + //**************************************************************************** //**************************************************************************** int @@ -1949,7 +1976,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) BackupEvent event; event.Event = BackupEvent::BackupStarted; event.Started.BackupId = conf->backupId; - event.Started.Nodes = conf->nodes; + event.Nodes = conf->nodes; #ifdef VM_TRACE ndbout_c("Backup master is %d", refToNode(signal->theSendersBlockRef)); #endif @@ -2012,7 +2039,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) event.Completed.stopGCP = rep->stopGCP; event.Completed.startGCP = rep->startGCP; - event.Completed.Nodes = rep->nodes; + event.Nodes = rep->nodes; backupCallback(event); } @@ -2169,8 +2196,9 @@ MgmtSrvr::getNextNodeId(NodeId * nodeId, enum ndb_mgm_node_type type) const while(nodeTypes[tmp] != type && tmp < MAX_NODES) tmp++; - if(tmp == MAX_NODES) + if(tmp == MAX_NODES){ return false; + } * nodeId = tmp; return true; @@ -2529,8 +2557,8 @@ MgmtSrvr::getStuff() } NodeId -MgmtSrvr::getPrimaryNode() const -{ +MgmtSrvr::getPrimaryNode() const { +#if 0 Uint32 tmp; const Properties *prop = NULL; @@ -2541,4 +2569,7 @@ MgmtSrvr::getPrimaryNode() const prop->get("PrimaryMGMNode", &tmp); return tmp; +#else + return 0; +#endif } diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index ce8765d6c73..1d394a14857 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -27,6 +27,7 @@ #include <NodeBitmask.hpp> #include <signaldata/ManagementServer.hpp> #include "SignalQueue.hpp" +#include <ndb_version.h> #include "NodeLogLevelList.hpp" @@ -151,7 +152,8 @@ public: /* Constructor */ MgmtSrvr(NodeId nodeId, /* Local nodeid */ const BaseString &config_filename, /* Where to save config */ - const BaseString &ndb_config_filename); /* Ndb.cfg filename */ + const BaseString &ndb_config_filename, /* Ndb.cfg filename */ + Config * config); /** * Read (initial) config file, create TransporterFacade, @@ -169,7 +171,8 @@ public: Uint32 * phase, bool * systemShutdown, Uint32 * dynamicId, - Uint32 * nodeGroup); + Uint32 * nodeGroup, + Uint32 * connectCount); // All the functions below may return any of this error codes: // NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE, @@ -307,10 +310,10 @@ public: BackupAborted = 4 } Event; + NdbNodeBitmask Nodes; union { struct { Uint32 BackupId; - NdbNodeBitmask Nodes; } Started ; struct { Uint32 ErrorCode; @@ -321,7 +324,6 @@ public: Uint32 NoOfRecords; Uint32 NoOfLogBytes; Uint32 NoOfLogRecords; - NdbNodeBitmask Nodes; Uint32 startGCP; Uint32 stopGCP; } Completed ; @@ -522,7 +524,7 @@ private: int _blockNumber; NodeId _ownNodeId; BlockReference _ownReference; - NdbMutex *m_configMutex; + NdbMutex *m_configMutex; const Config * _config; Config * m_newConfig; BaseString m_configFilename; diff --git a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp index f4e53409b30..10316bd2851 100644 --- a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp +++ b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp @@ -275,31 +275,30 @@ MgmtSrvr::readConfig() { Config *conf = NULL; if(m_configFilename.length() != 0) { /* Use config file */ - InitConfigFileParser parser(m_configFilename.c_str()); - - if(!parser.readConfigFile()) { + InitConfigFileParser parser; + conf = parser.parseConfig(m_configFilename.c_str()); + + if(conf == NULL) { /* Try to get configuration from other MGM server */ - ConfigRetriever cr; - cr.setLocalConfigFileName(m_localNdbConfigFilename.c_str()); - conf = new Config(*cr.getConfig("MGM", NDB_VERSION)); - } else { - conf = new Config(*parser.getConfig()); + return fetchConfig(); } - - if(conf == NULL) - return NULL; } return conf; } Config * MgmtSrvr::fetchConfig() { - Config *conf = NULL; ConfigRetriever cr; cr.setLocalConfigFileName(m_localNdbConfigFilename.c_str()); - conf = new Config(*cr.getConfig("MGM", NDB_VERSION)); + struct ndb_mgm_configuration * tmp = cr.getConfig(NDB_VERSION, + NODE_TYPE_MGM); + if(tmp != 0){ + Config * conf = new Config(); + conf->m_configValues = tmp; + return conf; + } - return conf; + return 0; } bool diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 24f41fe64bf..739eef90c52 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -26,6 +26,9 @@ #include <BaseString.hpp> #include <Base64.hpp> +#include <ConfigValues.hpp> +#include <mgmapi_configuration.hpp> + #include "Services.hpp" static const unsigned int MAX_READ_TIMEOUT = 1000 ; @@ -275,12 +278,60 @@ MgmApiSession::getConfig_old(Parser_t::Context &ctx) { } #endif /* MGM_GET_CONFIG_BACKWARDS_COMPAT */ +inline void require(bool b){ if(!b) abort(); } + void MgmApiSession::getConfig(Parser_t::Context &ctx, const class Properties &args) { getConfig_common(ctx, args); } +static Properties * +backward(const char * base, const Properties* reply){ + Properties * ret = new Properties(); + Properties::Iterator it(reply); + for(const char * name = it.first(); name != 0; name=it.next()){ + PropertiesType type; + reply->getTypeOf(name, &type); + switch(type){ + case PropertiesType_Uint32:{ + Uint32 val; + reply->get(name, &val); + ret->put(name, val); + } + break; + case PropertiesType_char: + { + const char * val; + reply->get(name, &val); + ret->put(name, val); + if(!strcmp(name, "Type") && !strcmp(val, "DB")){ + ret->put("NoOfDiskBufferPages", (unsigned)0); + ret->put("NoOfDiskFiles", (unsigned)0); + ret->put("NoOfDiskClusters", (unsigned)0); + ret->put("NoOfFreeDiskClusters", (unsigned)0); + ret->put("NoOfDiskClustersPerDiskFile", (unsigned)0); + ret->put("NoOfConcurrentCheckpointsDuringRestart", (unsigned)1); + ret->put("NoOfConcurrentCheckpointsAfterRestart", (unsigned)1); + ret->put("NoOfConcurrentProcessesHandleTakeover", (unsigned)1); + } + } + break; + case PropertiesType_Properties: + { + const Properties * recurse; + reply->get(name, &recurse); + Properties * val = backward(name, recurse); + ret->put(name, val); + } + break; + case PropertiesType_Uint64: + break; + } + } + return ret; +} + void MgmApiSession::getConfig_common(Parser_t::Context &, const class Properties &args, @@ -290,92 +341,100 @@ MgmApiSession::getConfig_common(Parser_t::Context &, args.get("version", &version); args.get("node", &node); -#if 0 - if(version != 0) { - m_output->println("get config"); - m_output->println("result: Invalid version number"); - m_output->println(""); - return; - } -#endif - const Config *conf = m_mgmsrv.getConfig(); if(conf == NULL) { - m_output->println("get config"); + m_output->println("get config reply"); m_output->println("result: Could not fetch configuration"); m_output->println(""); return; } - bool compatible; - switch (m_mgmsrv.getNodeType(node)) { - case NDB_MGM_NODE_TYPE_NDB: - compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version); - break; - case NDB_MGM_NODE_TYPE_API: - case NDB_MGM_NODE_TYPE_MGM: - compatible = ndbCompatible_mgmt_api(NDB_VERSION, version); - break; - default: - m_output->println("get config"); - m_output->println("result: unrecognignized node type"); - m_output->println(""); - return; - } - - if (!compatible){ - m_output->println("get config"); - m_output->println("result: incompatible version mgmt 0x%x and node 0x%x", - NDB_VERSION, version); - m_output->println(""); - return; - } - - Properties *reply = new Properties(*conf); - reply->put("Version", NDB_VERSION); // reply->put("Version", version); - reply->put("LocalNodeId", node); + if(version > 0 && version < makeVersion(3, 5, 0) && compat){ + Properties *reply = backward("", conf->m_oldConfig); + reply->put("Version", version); + reply->put("LocalNodeId", node); -#ifdef MGM_GET_CONFIG_BACKWARDS_COMPAT - if(compat) { + backward("", reply); + //reply->print(); + const Uint32 size = reply->getPackedSize(); Uint32 *buffer = new Uint32[size/4+1]; reply->pack(buffer); delete reply; - + const int uurows = (size + 44)/45; char * uubuf = new char[uurows * 62+5]; - + const int uusz = uuencode_mem(uubuf, (char *)buffer, size); delete[] buffer; - + m_output->println("GET CONFIG %d %d %d %d %d", - 0, NDB_VERSION, node, size, uusz);// 0, version, node, size, uusz); - + 0, version, node, size, uusz); + m_output->println("begin 664 Ndb_cfg.bin"); - + /* XXX Need to write directly to the socket, because the uubuf is not * NUL-terminated. This could/should probably be done in a nicer way. */ write_socket(m_socket, MAX_WRITE_TIMEOUT, uubuf, uusz); delete[] uubuf; - + m_output->println("end"); m_output->println(""); - } else { -#endif /* MGM_GET_CONFIG_BACKWARDS_COMPAT */ - - UtilBuffer buffer; - BaseString str; - reply->pack(buffer); - delete reply; - base64_encode(buffer, str); + return; + } - m_output->println("config: %s", str.c_str()); - m_output->println(""); -#ifdef MGM_GET_CONFIG_BACKWARDS_COMPAT + if(compat){ + m_output->println("GET CONFIG %d %d %d %d %d",1, version, 0, 0, 0); + return; } -#endif /* MGM_GET_CONFIG_BACKWARDS_COMPAT */ + + if(node != 0){ + bool compatible; + switch (m_mgmsrv.getNodeType(node)) { + case NDB_MGM_NODE_TYPE_NDB: + compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version); + break; + case NDB_MGM_NODE_TYPE_API: + case NDB_MGM_NODE_TYPE_MGM: + compatible = ndbCompatible_mgmt_api(NDB_VERSION, version); + break; + default: + m_output->println("get config"); + m_output->println("result: unrecognignized node type"); + m_output->println(""); + return; + } + + if (!compatible){ + m_output->println("get config"); + m_output->println("result: incompatible version mgmt 0x%x and node 0x%x", + NDB_VERSION, version); + m_output->println(""); + return; + } + } + + const ConfigValues * cfg = &conf->m_configValues->m_config; + const Uint32 size = cfg->getPackedSize(); + + UtilBuffer src; + cfg->pack(src); + + BaseString str; + int res = base64_encode(src, str); + + m_output->println("get config reply"); + m_output->println("result: Ok"); + m_output->println("Content-Length: %d", str.length()); + m_output->println("Content-Type: ndbconfig/octet-stream"); + m_output->println("Content-Transfer-Encoding: base64"); + m_output->println(""); + m_output->println(str.c_str()); + m_output->println(""); + + return; } void @@ -756,10 +815,14 @@ printNodeStatus(OutputStream *output, NodeId nodeId = 0; while(mgmsrv.getNextNodeId(&nodeId, type)) { enum ndb_mgm_node_status status; - Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0; + Uint32 startPhase = 0, + version = 0, + dynamicId = 0, + nodeGroup = 0, + connectCount = 0; bool system; mgmsrv.status(nodeId, &status, &version, &startPhase, - &system, &dynamicId, &nodeGroup); + &system, &dynamicId, &nodeGroup, &connectCount); output->println("node.%d.type: %s", nodeId, ndb_mgm_get_node_type_string(type)); @@ -770,6 +833,7 @@ printNodeStatus(OutputStream *output, output->println("node.%d.startphase: %d", nodeId, startPhase); output->println("node.%d.dynamic_id: %d", nodeId, dynamicId); output->println("node.%d.node_group: %d", nodeId, nodeGroup); + output->println("node.%d.connect_count: %d", nodeId, connectCount); } } diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index 91b443f61a2..d9eb0001c44 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -34,6 +34,7 @@ #include <NdbHost.h> #include <ndb_version.h> #include <ConfigRetriever.hpp> +#include <mgmapi_config_parameters.h> #include <getarg.h> #if defined NDB_OSE || defined NDB_SOFTOSE @@ -191,7 +192,10 @@ NDB_MAIN(mgmsrv){ glob.mgmObject = new MgmtSrvr(glob.localNodeId, BaseString(glob.config_filename), - BaseString(glob.local_config_filename == 0 ? "" : glob.local_config_filename)); + BaseString(glob.local_config_filename == 0 ? "" : glob.local_config_filename), + glob.cluster_config); + + glob.cluster_config = 0; if(!glob.mgmObject->check_start()){ ndbout_c("Unable to start management server."); @@ -321,18 +325,21 @@ readGlobalConfig() { return false; /* Use config file */ - InitConfigFileParser parser(glob.config_filename); - - if(parser.readConfigFile()) { - glob.cluster_config = new Config(*parser.getConfig()); - } else { - /* Try to get configuration from other MGM server */ + InitConfigFileParser parser; + glob.cluster_config = parser.parseConfig(glob.config_filename); + if(glob.cluster_config == 0){ + /** + * Try to get configuration from other MGM server + * Note: Only new format + */ + glob.cluster_config = new Config(); + ConfigRetriever cr; cr.setLocalConfigFileName(glob.local_config_filename); - Properties* mgmconf = cr.getConfig("MGM", NDB_VERSION); - if (mgmconf == NULL) + glob.cluster_config->m_configValues = cr.getConfig(NDB_VERSION, + NODE_TYPE_MGM); + if (glob.cluster_config->m_configValues == NULL) return false; - glob.cluster_config = new Config(*mgmconf); } return true; } @@ -350,15 +357,23 @@ static bool setPortNo(){ const Properties *mgmProps; - if(!glob.cluster_config->get("Node", glob.localNodeId, &mgmProps)){ + ndb_mgm_configuration_iterator * iter = + ndb_mgm_create_configuration_iterator(glob.cluster_config->m_configValues, + CFG_SECTION_NODE); + if(iter == 0) + return false; + + if(ndb_mgm_find(iter, CFG_NODE_ID, glob.localNodeId) != 0){ ndbout << "Could not retrieve configuration for Node " << glob.localNodeId << " in config file." << endl << "Have you set correct NodeId for this node?" << endl; + ndb_mgm_destroy_iterator(iter); return false; } - BaseString type; - if(!mgmProps->get("Type", type) || strcasecmp(type.c_str(), "MGM") != 0){ + unsigned type; + if(ndb_mgm_get_int_parameter(iter, CFG_TYPE_OF_SECTION, &type) != 0 || + type != NODE_TYPE_MGM){ ndbout << "Local node id " << glob.localNodeId << " is not defined as management server" << endl << "Have you set correct NodeId for this node?" << endl; @@ -369,7 +384,7 @@ setPortNo(){ * Set Port * ************/ Uint32 tmp = 0; - if (!mgmProps->get("PortNumber", &tmp)){ + if(ndb_mgm_get_int_parameter(iter, CFG_MGM_PORT, &tmp) != 0){ ndbout << "Could not find PortNumber in the configuration file." << endl; return false; } @@ -378,15 +393,18 @@ setPortNo(){ /***************** * Set Stat Port * *****************/ +#if 0 if (!mgmProps->get("PortNumberStats", &tmp)){ ndbout << "Could not find PortNumberStats in the configuration file." << endl; return false; } glob.port_stats = tmp; +#endif - BaseString host; - if(!mgmProps->get("ExecuteOnComputer", host)){ +#if 0 + const char * host; + if(ndb_mgm_get_string_parameter(iter, mgmProps->get("ExecuteOnComputer", host)){ ndbout << "Failed to find \"ExecuteOnComputer\" for my node" << endl; ndbout << "Unable to verify own hostname" << endl; return false; @@ -422,8 +440,11 @@ setPortNo(){ return true; } - glob.use_specific_ip = false; glob.interface_name = strdup(hostname); - +#endif + + glob.interface_name = 0; + glob.use_specific_ip = false; + return true; } diff --git a/ndb/src/mgmsrv/mkconfig/Makefile b/ndb/src/mgmsrv/mkconfig/Makefile index d35f68a5648..43574eefbd1 100644 --- a/ndb/src/mgmsrv/mkconfig/Makefile +++ b/ndb/src/mgmsrv/mkconfig/Makefile @@ -3,12 +3,11 @@ include .defs.mk TYPE := ndbapi BIN_TARGET := mkconfig -BIN_TARGET_ARCHIVES := logger general trace mgmsrvcommon portlib +BIN_TARGET_ARCHIVES := logger trace mgmsrvcommon portlib general SOURCES := mkconfig.cpp CCFLAGS_LOC += -I.. -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) - -OBJECTS_LOC := ../convertStrToInt.o +CFLAGS_mkconfig.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/mgmsrv/mkconfig/mkconfig.cpp b/ndb/src/mgmsrv/mkconfig/mkconfig.cpp index 224c82aa8a1..3b2046d7b49 100644 --- a/ndb/src/mgmsrv/mkconfig/mkconfig.cpp +++ b/ndb/src/mgmsrv/mkconfig/mkconfig.cpp @@ -16,6 +16,7 @@ #include <ndb_global.h> #include <ndb_version.h> +#include <mgmapi_configuration.hpp> #include <NdbMain.h> #include <Properties.hpp> @@ -36,25 +37,20 @@ NDB_COMMAND(mkconfig, return 0; } - InitConfigFileParser parser(argv[1]); - Config* cp; + InitConfigFileParser parser; + Config* _cp; - if (!parser.readConfigFile()) + if ((_cp = parser.parseConfig(argv[1])) == 0) return false; - cp = (Config *) parser.getConfig(); - if (cp == NULL) - return false; - - cp->put("VersionId", (Uint32)NDB_VERSION); - + ConfigValues* cp = &_cp->m_configValues->m_config; Uint32 sz = cp->getPackedSize(); - Uint32 * buf = new Uint32[sz]; + UtilBuffer buf; if(!cp->pack(buf)) return -1; - + FILE * f = fopen(argv[2], "w"); - if(fwrite(buf, 1, sz, f) != sz){ + if(fwrite(buf.get_data(), 1, buf.length(), f) != sz){ fclose(f); unlink(argv[2]); return -1; diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp index 57967e5534f..b26d550fe31 100644 --- a/ndb/src/ndbapi/ClusterMgr.cpp +++ b/ndb/src/ndbapi/ClusterMgr.cpp @@ -32,6 +32,10 @@ #include <signaldata/NFCompleteRep.hpp> #include <signaldata/ApiRegSignalData.hpp> +#include <mgmapi.h> +#include <mgmapi_configuration.hpp> +#include <mgmapi_config_parameters.h> + // Just a C wrapper for threadMain extern "C" void* @@ -69,32 +73,49 @@ ClusterMgr::~ClusterMgr(){ } void -ClusterMgr::init(const IPCConfig & config){ - NodeId tmp = 0; - while(config.getNextRemoteNodeId(tmp)) { +ClusterMgr::init(ndb_mgm_configuration_iterator & iter){ + for(iter.first(); iter.valid(); iter.next()){ + Uint32 tmp = 0; + if(iter.get(CFG_NODE_ID, &tmp)) + continue; + theNodes[tmp].defined = true; #if 0 ndbout << "--------------------------------------" << endl; - config.print(); ndbout << "--------------------------------------" << endl; ndbout_c("ClusterMgr: Node %d defined as %s", tmp, config.getNodeType(tmp)); #endif - if(strcmp(config.getNodeType(tmp), "DB") == 0) { + + unsigned type; + if(iter.get(CFG_TYPE_OF_SECTION, &type)) + continue; + + switch(type){ + case NODE_TYPE_DB: theNodes[tmp].m_info.m_type = NodeInfo::DB; - } else if(strcmp(config.getNodeType(tmp), "API") == 0) { + break; + case NODE_TYPE_API: theNodes[tmp].m_info.m_type = NodeInfo::API; - } else if(strcmp(config.getNodeType(tmp), "MGM") == 0) { + break; + case NODE_TYPE_MGM: theNodes[tmp].m_info.m_type = NodeInfo::MGM; - } else if(strcmp(config.getNodeType(tmp), "REP") == 0) { + break; + case NODE_TYPE_REP: theNodes[tmp].m_info.m_type = NodeInfo::REP; - } else if(strcmp(config.getNodeType(tmp), "EXTERNAL REP") == 0) { + break; + case NODE_TYPE_EXT_REP: theNodes[tmp].m_info.m_type = NodeInfo::REP; - theNodes[tmp].hbFrequency = config.getREPHBFrequency(tmp); - assert(100 <= theNodes[tmp].hbFrequency && - theNodes[tmp].hbFrequency < 60 * 60 * 1000); - } else { + { + Uint32 hbFreq = 10000; + //ndb_mgm_get_int_parameter(iter, CFG_, &hbFreq); + theNodes[tmp].hbFrequency = hbFreq; + assert(100 <= hbFreq && hbFreq < 60 * 60 * 1000); + } + break; + default: + type = type; #if 0 - ndbout_c("ClusterMgr: Unknown node type: %s", config.getNodeType(tmp)); + ndbout_c("ClusterMgr: Unknown node type: %d", type); #endif } } @@ -162,45 +183,43 @@ ClusterMgr::threadMain( ){ const NodeId nodeId = i; Node & theNode = theNodes[nodeId]; - if (theNode.defined == true) { -#if 0 - ndbout_c("ClusterMgr: compatible %d", (int)nodeId); -#endif + if (!theNode.defined) + continue; - if (theNode.connected == false){ - theFacade.doConnect(nodeId); - continue; + if (theNode.connected == false){ + theFacade.doConnect(nodeId); + continue; + } + + if (!theNode.compatible){ + continue; + } + + theNode.hbCounter += timeSlept; + if (theNode.hbCounter >= theNode.hbFrequency){ + /** + * It is now time to send a new Heartbeat + */ + theNode.hbSent++; + theNode.hbCounter = 0; + /** + * If the node is of type REP, + * then the receiver of the signal should be API_CLUSTERMGR + */ + if (theNode.m_info.m_type == NodeInfo::REP) { + signal.theReceiversBlockNumber = API_CLUSTERMGR; } - -#if 0 - ndbout_c("ClusterMgr: connected %d", (int)nodeId); +#if 0 + ndbout_c("ClusterMgr: Sending API_REGREQ to node %d", (int)nodeId); #endif - - theNode.hbCounter += timeSlept; - if (theNode.hbCounter >= theNode.hbFrequency){ - /** - * It is now time to send a new Heartbeat - */ - theNode.hbSent++; - theNode.hbCounter = 0; - /** - * If the node is of type REP, - * then the receiver of the signal should be API_CLUSTERMGR - */ - if (theNode.m_info.m_type == NodeInfo::REP) { - signal.theReceiversBlockNumber = API_CLUSTERMGR; - } -#if 0 - ndbout_c("ClusterMgr: Sending API_REGREQ to node %d", (int)nodeId); -#endif - theFacade.sendSignalUnCond(&signal, nodeId); - }//if - - if (theNode.hbSent == 4 && theNode.hbFrequency > 0){ - reportNodeFailed(i); - }//if - }//if(defined) - }//for + theFacade.sendSignalUnCond(&signal, nodeId); + }//if + + if (theNode.hbSent == 4 && theNode.hbFrequency > 0){ + reportNodeFailed(i); + }//if + } + /** * End of secure area. Let other threads in */ @@ -281,6 +300,10 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){ const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0]; const NodeId nodeId = refToNode(apiRegConf->qmgrRef); +#if 0 + ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId); +#endif + assert(nodeId > 0 && nodeId < MAX_NODES); Node & node = theNodes[nodeId]; diff --git a/ndb/src/ndbapi/ClusterMgr.hpp b/ndb/src/ndbapi/ClusterMgr.hpp index 7b7b947742b..cc3cf66c8aa 100644 --- a/ndb/src/ndbapi/ClusterMgr.hpp +++ b/ndb/src/ndbapi/ClusterMgr.hpp @@ -40,7 +40,7 @@ class ClusterMgr { public: ClusterMgr(class TransporterFacade &); ~ClusterMgr(); - void init(const IPCConfig & config); + void init(struct ndb_mgm_configuration_iterator & config); void reportConnected(NodeId nodeId); void reportDisconnected(NodeId nodeId); @@ -114,7 +114,7 @@ ClusterMgr::getNoOfConnectedNodes() const { return noOfConnectedNodes; } -/******************************************************************************/ +/*****************************************************************************/ /** * @class ArbitMgr diff --git a/ndb/src/ndbapi/Makefile_old b/ndb/src/ndbapi/Makefile_old index f4c82e5d6ba..648c8cbb016 100644 --- a/ndb/src/ndbapi/Makefile_old +++ b/ndb/src/ndbapi/Makefile_old @@ -15,13 +15,16 @@ LIB_TARGET_ARCHIVES := $(ARCHIVE_TARGET) \ transporter \ general \ signaldataprint \ - mgmsrvcommon \ + mgmapi mgmsrvcommon \ portlib \ logger \ trace DIRS := signal-sender +CFLAGS_TransporterFacade.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) +CFLAGS_ClusterMgr.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) + # Source files of non-templated classes (.cpp files) SOURCES = \ TransporterFacade.cpp \ @@ -31,31 +34,25 @@ SOURCES = \ Ndblist.cpp \ Ndbif.cpp \ Ndbinit.cpp \ - Ndberr.cpp \ - ndberror.c \ - NdbErrorOut.cpp \ - NdbConnection.cpp \ + ndberror.c Ndberr.cpp NdbErrorOut.cpp \ + NdbConnection.cpp \ NdbConnectionScan.cpp \ NdbOperation.cpp \ NdbOperationSearch.cpp \ - NdbOperationScan.cpp \ NdbOperationInt.cpp \ NdbOperationDefine.cpp \ NdbOperationExec.cpp \ - NdbScanReceiver.cpp \ NdbResultSet.cpp \ - NdbCursorOperation.cpp \ NdbScanOperation.cpp NdbScanFilter.cpp \ NdbIndexOperation.cpp \ NdbEventOperation.cpp \ NdbEventOperationImpl.cpp \ NdbApiSignal.cpp \ NdbRecAttr.cpp \ - NdbSchemaCon.cpp \ - NdbSchemaOp.cpp \ NdbUtil.cpp \ NdbReceiver.cpp \ - NdbDictionary.cpp NdbDictionaryImpl.cpp DictCache.cpp + NdbDictionary.cpp NdbDictionaryImpl.cpp DictCache.cpp \ + NdbSchemaCon.cpp NdbSchemaOp.cpp include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index fe21b4e02a4..e7edf19c0a3 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -156,26 +156,22 @@ Ndb::NDB_connect(Uint32 tNode) tNdbCon->Status(NdbConnection::Connecting); // Set status to connecting Uint32 nodeSequence; { // send and receive signal - tp->lock_mutex(); + Guard guard(tp->theMutexPtr); nodeSequence = tp->getNodeSequence(tNode); bool node_is_alive = tp->get_node_alive(tNode); if (node_is_alive) { tReturnCode = tp->sendSignal(tSignal, tNode); releaseSignal(tSignal); - if (tReturnCode == -1) { - tp->unlock_mutex(); - } else { + if (tReturnCode != -1) { theWaiter.m_node = tNode; theWaiter.m_state = WAIT_TC_SEIZE; tReturnCode = receiveResponse(); }//if } else { releaseSignal(tSignal); - tp->unlock_mutex(); tReturnCode = -1; }//if } - if ((tReturnCode == 0) && (tNdbCon->Status() == NdbConnection::Connected)) { //************************************************ // Send and receive was successful @@ -465,41 +461,43 @@ Ndb::closeTransaction(NdbConnection* aConnection) CHECK_STATUS_MACRO_VOID; tCon = theTransactionList; - + if (aConnection == tCon) { // Remove the active connection object - theTransactionList = tCon->next(); // from the transaction list. + theTransactionList = tCon->next(); // from the transaction list. } else { while (aConnection != tCon) { if (tCon == NULL) { //----------------------------------------------------- // closeTransaction called on non-existing transaction //----------------------------------------------------- + + if(aConnection->theError.code == 4008){ + /** + * When a SCAN timed-out, returning the NdbConnection leads + * to reuse. And TC crashes when the API tries to reuse it to + * something else... + */ #ifdef VM_TRACE - printf("Non-existing transaction into closeTransaction\n"); + printf("Scan timeout:ed NdbConnection-> " + "not returning it-> memory leak\n"); +#endif + return; + } + +#ifdef VM_TRACE + printf("Non-existing transaction into closeTransaction\n"); abort(); #endif - return; + return; }//if tPreviousCon = tCon; tCon = tCon->next(); }//while tPreviousCon->next(tCon->next()); }//if - + aConnection->release(); - - if(aConnection->theError.code == 4008){ - /** - * When a SCAN timed-out, returning the NdbConnection leads - * to reuse. And TC crashes when the API tries to reuse it to - * something else... - */ -#ifdef VM_TRACE - printf("Scan timeout:ed NdbConnection-> not returning it-> memory leak\n"); -#endif - return; - } - + if(aConnection->theError.code == 4008){ /** * Something timed-out, returning the NdbConnection leads @@ -511,7 +509,7 @@ Ndb::closeTransaction(NdbConnection* aConnection) #endif return; } - + if (aConnection->theReleaseOnClose == false) { /** * Put it back in idle list for that node diff --git a/ndb/src/ndbapi/NdbApiSignal.cpp b/ndb/src/ndbapi/NdbApiSignal.cpp index a44937cd398..d173a462020 100644 --- a/ndb/src/ndbapi/NdbApiSignal.cpp +++ b/ndb/src/ndbapi/NdbApiSignal.cpp @@ -46,6 +46,7 @@ Adjust: 971114 UABMNST First version. #include <signaldata/IndxKeyInfo.hpp> #include <signaldata/IndxAttrInfo.hpp> #include <signaldata/TcHbRep.hpp> +#include <signaldata/ScanTab.hpp> #include <NdbOut.hpp> @@ -188,7 +189,7 @@ NdbApiSignal::setSignal(int aNdbSignalType) theTrace = TestOrd::TraceAPI; theReceiversBlockNumber = DBTC; theVerId_signalNumber = GSN_SCAN_TABREQ; - theLength = 25; + theLength = 9; // ScanTabReq::SignalLength; } break; diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index fbfd0e99238..8ccd0aa8523 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -27,11 +27,12 @@ Description: Interface between TIS and NDB Documentation: Adjust: 971022 UABMNST First version. *****************************************************************************/ -#include "NdbOut.hpp" -#include "NdbConnection.hpp" -#include "NdbOperation.hpp" -#include "NdbScanOperation.hpp" -#include "NdbIndexOperation.hpp" +#include <NdbOut.hpp> +#include <NdbConnection.hpp> +#include <NdbOperation.hpp> +#include <NdbScanOperation.hpp> +#include <NdbIndexScanOperation.hpp> +#include <NdbIndexOperation.hpp> #include "NdbApiSignal.hpp" #include "TransporterFacade.hpp" #include "API.hpp" @@ -79,15 +80,12 @@ NdbConnection::NdbConnection( Ndb* aNdb ) : theTransactionIsStarted(false), theDBnode(0), theReleaseOnClose(false), - // Cursor operations + // Scan operations m_waitForReply(true), - m_theFirstCursorOperation(NULL), - m_theLastCursorOperation(NULL), - m_firstExecutedCursorOp(NULL), + m_theFirstScanOperation(NULL), + m_theLastScanOperation(NULL), + m_firstExecutedScanOp(NULL), // Scan operations - theScanFinished(0), - theCurrentScanRec(NULL), - thePreviousScanRec(NULL), theScanningOp(NULL), theBuddyConPtr(0xFFFFFFFF) { @@ -117,7 +115,6 @@ NdbConnection::init() theListState = NotInList; theInUseState = true; theTransactionIsStarted = false; - theScanFinished = 0; theNext = NULL; theFirstOpInList = NULL; @@ -128,9 +125,6 @@ NdbConnection::init() theFirstExecOpInList = NULL; theLastExecOpInList = NULL; - theCurrentScanRec = NULL; - thePreviousScanRec = NULL; - theCompletedFirstOp = NULL; theGlobalCheckpointId = 0; @@ -146,11 +140,11 @@ NdbConnection::init() theSimpleState = true; theSendStatus = InitState; theMagicNumber = 0x37412619; - // Cursor operations + // Scan operations m_waitForReply = true; - m_theFirstCursorOperation = NULL; - m_theLastCursorOperation = NULL; - m_firstExecutedCursorOp = 0; + m_theFirstScanOperation = NULL; + m_theLastScanOperation = NULL; + m_firstExecutedScanOp = 0; theBuddyConPtr = 0xFFFFFFFF; }//NdbConnection::init() @@ -331,7 +325,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, */ theError.code = 0; - NdbCursorOperation* tcOp = m_theFirstCursorOperation; + NdbScanOperation* tcOp = m_theFirstScanOperation; if (tcOp != 0){ // Execute any cursor operations while (tcOp != NULL) { @@ -340,14 +334,14 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, if (tReturnCode == -1) { return; }//if - tcOp = (NdbCursorOperation*)tcOp->next(); + tcOp = (NdbScanOperation*)tcOp->next(); } // while - m_theLastCursorOperation->next(m_firstExecutedCursorOp); - m_firstExecutedCursorOp = m_theFirstCursorOperation; + m_theLastScanOperation->next(m_firstExecutedScanOp); + m_firstExecutedScanOp = m_theFirstScanOperation; // Discard cursor operations, since these are also // in the complete operations list we do not need // to release them. - m_theFirstCursorOperation = m_theLastCursorOperation = NULL; + m_theFirstScanOperation = m_theLastScanOperation = NULL; } bool tTransactionIsStarted = theTransactionIsStarted; @@ -714,17 +708,14 @@ Remark: Release all operations. ******************************************************************************/ void NdbConnection::release(){ - if (theTransactionIsStarted == true && theScanningOp != NULL ) - stopScan(); - releaseOperations(); if ( (theTransactionIsStarted == true) && - ((theCommitStatus != Committed) && - (theCommitStatus != Aborted))) { -/**************************************************************************** - * The user did not perform any rollback but simply closed the - * transaction. We must rollback Ndb since Ndb have been contacted. -******************************************************************************/ + ((theCommitStatus != Committed) && + (theCommitStatus != Aborted))) { + /************************************************************************ + * The user did not perform any rollback but simply closed the + * transaction. We must rollback Ndb since Ndb have been contacted. + ************************************************************************/ execute(Rollback); }//if theMagicNumber = 0xFE11DC; @@ -756,8 +747,8 @@ void NdbConnection::releaseOperations() { // Release any open scans - releaseCursorOperations(m_theFirstCursorOperation); - releaseCursorOperations(m_firstExecutedCursorOp); + releaseScanOperations(m_theFirstScanOperation); + releaseScanOperations(m_firstExecutedScanOp); releaseOps(theCompletedFirstOp); releaseOps(theFirstOpInList); @@ -769,9 +760,9 @@ NdbConnection::releaseOperations() theLastOpInList = NULL; theLastExecOpInList = NULL; theScanningOp = NULL; - m_theFirstCursorOperation = NULL; - m_theLastCursorOperation = NULL; - m_firstExecutedCursorOp = NULL; + m_theFirstScanOperation = NULL; + m_theLastScanOperation = NULL; + m_firstExecutedScanOp = NULL; }//NdbConnection::releaseOperations() void @@ -782,24 +773,21 @@ NdbConnection::releaseCompletedOperations() }//NdbConnection::releaseOperations() /****************************************************************************** -void releaseCursorOperations(); +void releaseScanOperations(); Remark: Release all cursor operations. (NdbScanOperation and NdbIndexOperation) ******************************************************************************/ void -NdbConnection::releaseCursorOperations(NdbCursorOperation* cursorOp) +NdbConnection::releaseScanOperations(NdbIndexScanOperation* cursorOp) { while(cursorOp != 0){ - NdbCursorOperation* next = (NdbCursorOperation*)cursorOp->next(); + NdbIndexScanOperation* next = (NdbIndexScanOperation*)cursorOp->next(); cursorOp->release(); - if (cursorOp->cursorType() == NdbCursorOperation::ScanCursor) - theNdb->releaseScanOperation((NdbScanOperation*)cursorOp); - else - theNdb->releaseOperation(cursorOp); + theNdb->releaseScanOperation(cursorOp); cursorOp = next; } -}//NdbConnection::releaseCursorOperations() +}//NdbConnection::releaseScanOperations() /***************************************************************************** NdbOperation* getNdbOperation(const char* aTableName); @@ -833,45 +821,6 @@ NdbConnection::getNdbOperation(const char* aTableName) }//NdbConnection::getNdbOperation() /***************************************************************************** -NdbOperation* getNdbOperation(const char* anIndexName, const char* aTableName); - -Return Value Return a pointer to a NdbOperation object if getNdbOperation - was succesful. - Return NULL : In all other case. -Parameters: anIndexName : Name of the index to use. - aTableName : Name of the database table. -Remark: Get an operation from NdbOperation idlelist and get the - NdbConnection object - who was fetch by startTransaction pointing to this operation - getOperation will set the theTableId in the NdbOperation object. - synchronous -******************************************************************************/ -NdbOperation* -NdbConnection::getNdbOperation(const char* anIndexName, const char* aTableName) -{ - if ((theError.code == 0) && - (theCommitStatus == Started)){ - NdbIndexImpl* index = - theNdb->theDictionary->getIndex(anIndexName, aTableName); - NdbTableImpl* table = theNdb->theDictionary->getTable(aTableName); - NdbTableImpl* indexTable = - theNdb->theDictionary->getIndexTable(index, table); - if (indexTable != 0){ - return getNdbOperation(indexTable); - } else { - setErrorCode(theNdb->theDictionary->getNdbError().code); - return NULL; - }//if - } else { - if (theError.code == 0) { - setOperationErrorCodeAbort(4114); - }//if - - return NULL; - }//if -}//NdbConnection::getNdbOperation() - -/***************************************************************************** NdbOperation* getNdbOperation(int aTableId); Return Value Return a pointer to a NdbOperation object if getNdbOperation @@ -956,8 +905,9 @@ Remark: Get an operation from NdbScanOperation idlelist and get the NdbC who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbOperation object.synchronous ******************************************************************************/ -NdbScanOperation* -NdbConnection::getNdbScanOperation(const char* anIndexName, const char* aTableName) +NdbIndexScanOperation* +NdbConnection::getNdbIndexScanOperation(const char* anIndexName, + const char* aTableName) { if (theCommitStatus == Started){ NdbIndexImpl* index = @@ -966,7 +916,9 @@ NdbConnection::getNdbScanOperation(const char* anIndexName, const char* aTableNa NdbTableImpl* indexTable = theNdb->theDictionary->getIndexTable(index, table); if (indexTable != 0){ - return getNdbScanOperation(indexTable); + NdbIndexScanOperation* tOp = getNdbScanOperation(indexTable); + if(tOp) tOp->m_cursor_type = NdbScanOperation::IndexCursor; + return tOp; } else { setOperationErrorCodeAbort(theNdb->theError.code); return NULL; @@ -987,21 +939,21 @@ Remark: Get an operation from NdbScanOperation object idlelist and get t object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbOperation object, synchronous. *****************************************************************************/ -NdbScanOperation* +NdbIndexScanOperation* NdbConnection::getNdbScanOperation(NdbTableImpl * tab) { - NdbScanOperation* tOp; + NdbIndexScanOperation* tOp; tOp = theNdb->getScanOperation(); if (tOp == NULL) goto getNdbOp_error1; // Link scan operation into list of cursor operations - if (m_theLastCursorOperation == NULL) - m_theFirstCursorOperation = m_theLastCursorOperation = tOp; + if (m_theLastScanOperation == NULL) + m_theFirstScanOperation = m_theLastScanOperation = tOp; else { - m_theLastCursorOperation->next(tOp); - m_theLastCursorOperation = tOp; + m_theLastScanOperation->next(tOp); + m_theLastScanOperation = tOp; } tOp->next(NULL); if (tOp->init(tab, this) != -1) { @@ -1211,12 +1163,12 @@ Remark: int NdbConnection::receiveTC_COMMITCONF(const TcCommitConf * commitConf) { - if(theStatus != Connected){ - return -1; + if(checkState_TransId(&commitConf->transId1)){ + theCommitStatus = Committed; + theCompletionStatus = CompletedSuccess; + return 0; } - theCommitStatus = Committed; - theCompletionStatus = CompletedSuccess; - return 0; + return -1; }//NdbConnection::receiveTC_COMMITCONF() /****************************************************************************** @@ -1230,33 +1182,33 @@ Remark: int NdbConnection::receiveTC_COMMITREF(NdbApiSignal* aSignal) { - if(theStatus != Connected){ - return -1; + const TcCommitRef * ref = CAST_CONSTPTR(TcCommitRef, aSignal->getDataPtr()); + if(checkState_TransId(&ref->transId1)){ + setOperationErrorCodeAbort(ref->errorCode); + theCommitStatus = Aborted; + theCompletionStatus = CompletedFailure; + return 0; } - const TcCommitRef * const ref = CAST_CONSTPTR(TcCommitRef, aSignal->getDataPtr()); - setOperationErrorCodeAbort(ref->errorCode); - theCommitStatus = Aborted; - theCompletionStatus = CompletedFailure; - return 0; + return -1; }//NdbConnection::receiveTC_COMMITREF() -/******************************************************************************* +/****************************************************************************** int receiveTCROLLBACKCONF(NdbApiSignal* aSignal); Return Value: Return 0 : receiveTCROLLBACKCONF was successful. Return -1: In all other case. Parameters: aSignal: The signal object pointer. Remark: -*******************************************************************************/ +******************************************************************************/ int NdbConnection::receiveTCROLLBACKCONF(NdbApiSignal* aSignal) { - if(theStatus != Connected){ - return -1; + if(checkState_TransId(aSignal->getDataPtr() + 1)){ + theCommitStatus = Aborted; + theCompletionStatus = CompletedSuccess; + return 0; } - theCommitStatus = Aborted; - theCompletionStatus = CompletedSuccess; - return 0; + return -1; }//NdbConnection::receiveTCROLLBACKCONF() /******************************************************************************* @@ -1270,13 +1222,13 @@ Remark: int NdbConnection::receiveTCROLLBACKREF(NdbApiSignal* aSignal) { - if(theStatus != Connected){ - return -1; + if(checkState_TransId(aSignal->getDataPtr() + 1)){ + setOperationErrorCodeAbort(aSignal->readData(4)); + theCommitStatus = Aborted; + theCompletionStatus = CompletedFailure; + return 0; } - setOperationErrorCodeAbort(aSignal->readData(2)); - theCommitStatus = Aborted; - theCompletionStatus = CompletedFailure; - return 0; + return -1; }//NdbConnection::receiveTCROLLBACKREF() /***************************************************************************** @@ -1291,36 +1243,26 @@ Remark: Handles the reception of the ROLLBACKREP signal. int NdbConnection::receiveTCROLLBACKREP( NdbApiSignal* aSignal) { - Uint64 tRecTransId, tCurrTransId; - Uint32 tTmp1, tTmp2; - - if (theStatus != Connected) { - return -1; - }//if -/***************************************************************************** + /**************************************************************************** Check that we are expecting signals from this transaction and that it doesn't belong to a transaction already completed. Simply ignore messages from other transactions. -******************************************************************************/ - tTmp1 = aSignal->readData(2); - tTmp2 = aSignal->readData(3); - tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32); - tCurrTransId = this->getTransactionId(); - if (tCurrTransId != tRecTransId) { - return -1; - }//if - theError.code = aSignal->readData(4); // Override any previous errors - -/**********************************************************************/ -/* A serious error has occured. This could be due to deadlock or */ -/* lack of resources or simply a programming error in NDB. This */ -/* transaction will be aborted. Actually it has already been */ -/* and we only need to report completion and return with the */ -/* error code to the application. */ -/**********************************************************************/ - theCompletionStatus = CompletedFailure; - theCommitStatus = Aborted; - return 0; + ****************************************************************************/ + if(checkState_TransId(aSignal->getDataPtr() + 1)){ + theError.code = aSignal->readData(4);// Override any previous errors + + /**********************************************************************/ + /* A serious error has occured. This could be due to deadlock or */ + /* lack of resources or simply a programming error in NDB. This */ + /* transaction will be aborted. Actually it has already been */ + /* and we only need to report completion and return with the */ + /* error code to the application. */ + /**********************************************************************/ + theCompletionStatus = CompletedFailure; + theCommitStatus = Aborted; + return 0; + } + return -1; }//NdbConnection::receiveTCROLLBACKREP() /******************************************************************************* @@ -1334,47 +1276,38 @@ Remark: int NdbConnection::receiveTCKEYCONF(const TcKeyConf * keyConf, Uint32 aDataLength) { - Uint64 tRecTransId; - NdbOperation* tOp; - Uint32 tConditionFlag; - + NdbReceiver* tOp; const Uint32 tTemp = keyConf->confInfo; - const Uint32 tTmp1 = keyConf->transId1; - const Uint32 tTmp2 = keyConf->transId2; -/****************************************************************************** + /*************************************************************************** Check that we are expecting signals from this transaction and that it doesn't belong to a transaction already completed. Simply ignore messages from other transactions. -******************************************************************************/ - tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32); + ***************************************************************************/ + if(checkState_TransId(&keyConf->transId1)){ - const Uint32 tNoOfOperations = TcKeyConf::getNoOfOperations(tTemp); - const Uint32 tCommitFlag = TcKeyConf::getCommitFlag(tTemp); - tConditionFlag = (Uint32)(((aDataLength - 5) >> 1) - tNoOfOperations); - tConditionFlag |= (Uint32)(tNoOfOperations > 10); - tConditionFlag |= (Uint32)(tNoOfOperations <= 0); - tConditionFlag |= (Uint32)(theTransactionId - tRecTransId); - tConditionFlag |= (Uint32)(theStatus - Connected); + const Uint32 tNoOfOperations = TcKeyConf::getNoOfOperations(tTemp); + const Uint32 tCommitFlag = TcKeyConf::getCommitFlag(tTemp); - if (tConditionFlag == 0) { const Uint32* tPtr = (Uint32 *)&keyConf->operations[0]; + Uint32 tNoComp = theNoOfOpCompleted; for (Uint32 i = 0; i < tNoOfOperations ; i++) { - tOp = theNdb->void2rec_op(theNdb->int2void(*tPtr)); + tOp = theNdb->void2rec(theNdb->int2void(*tPtr)); tPtr++; const Uint32 tAttrInfoLen = *tPtr; tPtr++; - if (tOp && tOp->checkMagicNumber() != -1) { - tOp->TCOPCONF(tAttrInfoLen); + if (tOp && tOp->checkMagicNumber()) { + tNoComp += tOp->execTCOPCONF(tAttrInfoLen); } else { return -1; }//if }//for - Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoSent = theNoOfOpSent; + theNoOfOpCompleted = tNoComp; Uint32 tGCI = keyConf->gci; if (tCommitFlag == 1) { theCommitStatus = Committed; theGlobalCheckpointId = tGCI; + theTransactionId++; } else if ((tNoComp >= tNoSent) && (theLastExecOpInList->theCommitIndicator == 1)){ /**********************************************************************/ @@ -1406,50 +1339,46 @@ Remark: Handles the reception of the TCKEY_FAILCONF signal. int NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) { - Uint64 tRecTransId, tCurrTransId; - Uint32 tTmp1, tTmp2; NdbOperation* tOp; - if (theStatus != Connected) { - return -1; - }//if /* - Check that we are expecting signals from this transaction and that it - doesn't belong to a transaction already completed. Simply ignore - messages from other transactions. + Check that we are expecting signals from this transaction and that it + doesn't belong to a transaction already completed. Simply ignore + messages from other transactions. */ - tTmp1 = failConf->transId1; - tTmp2 = failConf->transId2; - tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32); - tCurrTransId = this->getTransactionId(); - if (tCurrTransId != tRecTransId) { - return -1; - }//if - /* - A node failure of the TC node occured. The transaction has - been committed. - */ - theCommitStatus = Committed; - tOp = theFirstExecOpInList; - while (tOp != NULL) { + if(checkState_TransId(&failConf->transId1)){ /* - Check if the transaction expected read values... - If it did some of them might have gotten lost even if we succeeded - in committing the transaction. + A node failure of the TC node occured. The transaction has + been committed. */ - if (tOp->theAI_ElementLen != 0) { - theCompletionStatus = CompletedFailure; - setOperationErrorCodeAbort(4115); - break; - }//if - if (tOp->theCurrentRecAttr != NULL) { - theCompletionStatus = CompletedFailure; - setOperationErrorCodeAbort(4115); - break; - }//if - tOp = tOp->next(); - }//while - theReleaseOnClose = true; - return 0; + theCommitStatus = Committed; + tOp = theFirstExecOpInList; + while (tOp != NULL) { + /* + * Check if the transaction expected read values... + * If it did some of them might have gotten lost even if we succeeded + * in committing the transaction. + */ + switch(tOp->theOperationType){ + case UpdateRequest: + case InsertRequest: + case DeleteRequest: + case WriteRequest: + tOp = tOp->next(); + break; + case ReadRequest: + case ReadExclusive: + case OpenScanRequest: + case OpenRangeScanRequest: + theCompletionStatus = CompletedFailure; + setOperationErrorCodeAbort(4115); + tOp = NULL; + break; + }//if + }//while + theReleaseOnClose = true; + return 0; + } + return -1; }//NdbConnection::receiveTCKEY_FAILCONF() /************************************************************************* @@ -1464,101 +1393,75 @@ Remark: Handles the reception of the TCKEY_FAILREF signal. int NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) { - Uint64 tRecTransId, tCurrTransId; - Uint32 tTmp1, tTmp2; - - if (theStatus != Connected) { - return -1; - }//if /* - Check that we are expecting signals from this transaction and - that it doesn't belong to a transaction already - completed. Simply ignore messages from other transactions. + Check that we are expecting signals from this transaction and + that it doesn't belong to a transaction already + completed. Simply ignore messages from other transactions. */ - tTmp1 = aSignal->readData(2); - tTmp2 = aSignal->readData(3); - tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32); - tCurrTransId = this->getTransactionId(); - if (tCurrTransId != tRecTransId) { - return -1; - }//if - /* - We received an indication of that this transaction was aborted due to a - node failure. - */ - if (theSendStatus == sendTC_ROLLBACK) { + if(checkState_TransId(aSignal->getDataPtr()+1)){ /* - We were in the process of sending a rollback anyways. We will - report it as a success. + We received an indication of that this transaction was aborted due to a + node failure. */ - theCompletionStatus = CompletedSuccess; - } else { - theCompletionStatus = CompletedFailure; - theError.code = 4031; - }//if - theReleaseOnClose = true; - theCommitStatus = Aborted; - return 0; + if (theSendStatus == sendTC_ROLLBACK) { + /* + We were in the process of sending a rollback anyways. We will + report it as a success. + */ + theCompletionStatus = CompletedSuccess; + } else { + theCompletionStatus = CompletedFailure; + theError.code = 4031; + }//if + theReleaseOnClose = true; + theCommitStatus = Aborted; + return 0; + } + return -1; }//NdbConnection::receiveTCKEY_FAILREF() -/******************************************************************************* +/****************************************************************************** int receiveTCINDXCONF(NdbApiSignal* aSignal, Uint32 long_short_ind); Return Value: Return 0 : receiveTCINDXCONF was successful. Return -1: In all other case. Parameters: aSignal: The signal object pointer. Remark: -*******************************************************************************/ +******************************************************************************/ int -NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, Uint32 aDataLength) +NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, + Uint32 aDataLength) { - Uint64 tRecTransId; - Uint32 tConditionFlag; - - const Uint32 tTemp = indxConf->confInfo; - const Uint32 tTmp1 = indxConf->transId1; - const Uint32 tTmp2 = indxConf->transId2; -/****************************************************************************** -Check that we are expecting signals from this transaction and that it -doesn't belong to a transaction already completed. Simply ignore messages -from other transactions. -******************************************************************************/ - tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32); - - const Uint32 tNoOfOperations = TcIndxConf::getNoOfOperations(tTemp); - const Uint32 tCommitFlag = TcKeyConf::getCommitFlag(tTemp); - - tConditionFlag = (Uint32)(((aDataLength - 5) >> 1) - tNoOfOperations); - tConditionFlag |= (Uint32)(tNoOfOperations > 10); - tConditionFlag |= (Uint32)(tNoOfOperations <= 0); - tConditionFlag |= (Uint32)(theTransactionId - tRecTransId); - tConditionFlag |= (Uint32)(theStatus - Connected); - - if (tConditionFlag == 0) { + if(checkState_TransId(&indxConf->transId1)){ + const Uint32 tTemp = indxConf->confInfo; + const Uint32 tNoOfOperations = TcIndxConf::getNoOfOperations(tTemp); + const Uint32 tCommitFlag = TcKeyConf::getCommitFlag(tTemp); + const Uint32* tPtr = (Uint32 *)&indxConf->operations[0]; + Uint32 tNoComp = theNoOfOpCompleted; for (Uint32 i = 0; i < tNoOfOperations ; i++) { - NdbIndexOperation* tOp = theNdb->void2rec_iop(theNdb->int2void(*tPtr)); + NdbReceiver* tOp = theNdb->void2rec(theNdb->int2void(*tPtr)); tPtr++; const Uint32 tAttrInfoLen = *tPtr; tPtr++; - if (tOp && tOp->checkMagicNumber() != -1) { - tOp->TCOPCONF(tAttrInfoLen); + if (tOp && tOp->checkMagicNumber()) { + tNoComp += tOp->execTCOPCONF(tAttrInfoLen); } else { return -1; }//if }//for - Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoSent = theNoOfOpSent; Uint32 tGCI = indxConf->gci; + theNoOfOpCompleted = tNoComp; if (tCommitFlag == 1) { theCommitStatus = Committed; theGlobalCheckpointId = tGCI; } else if ((tNoComp >= tNoSent) && (theLastExecOpInList->theCommitIndicator == 1)){ -/**********************************************************************/ -// We sent the transaction with Commit flag set and received a CONF with -// no Commit flag set. This is clearly an anomaly. -/**********************************************************************/ + /**********************************************************************/ + // We sent the transaction with Commit flag set and received a CONF with + // no Commit flag set. This is clearly an anomaly. + /**********************************************************************/ theError.code = 4011; theCompletionStatus = CompletedFailure; theCommitStatus = Aborted; @@ -1584,36 +1487,21 @@ Remark: Handles the reception of the TCINDXREF signal. int NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal) { - Uint64 tRecTransId, tCurrTransId; - Uint32 tTmp1, tTmp2; - - if (theStatus != Connected) { - return -1; - }//if -/***************************************************************************** -Check that we are expecting signals from this transaction and that it doesn't -belong to a transaction already completed. Simply ignore messages from other -transactions. -******************************************************************************/ - tTmp1 = aSignal->readData(2); - tTmp2 = aSignal->readData(3); - tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32); - tCurrTransId = this->getTransactionId(); - if (tCurrTransId != tRecTransId) { - return -1; - }//if - theError.code = aSignal->readData(4); // Override any previous errors - -/**********************************************************************/ -/* A serious error has occured. This could be due to deadlock or */ -/* lack of resources or simply a programming error in NDB. This */ -/* transaction will be aborted. Actually it has already been */ -/* and we only need to report completion and return with the */ -/* error code to the application. */ -/**********************************************************************/ - theCompletionStatus = CompletedFailure; - theCommitStatus = Aborted; - return 0; + if(checkState_TransId(aSignal->getDataPtr()+1)){ + theError.code = aSignal->readData(4); // Override any previous errors + + /**********************************************************************/ + /* A serious error has occured. This could be due to deadlock or */ + /* lack of resources or simply a programming error in NDB. This */ + /* transaction will be aborted. Actually it has already been */ + /* and we only need to report completion and return with the */ + /* error code to the application. */ + /**********************************************************************/ + theCompletionStatus = CompletedFailure; + theCommitStatus = Aborted; + return 0; + } + return -1; }//NdbConnection::receiveTCINDXREF() /******************************************************************************* diff --git a/ndb/src/ndbapi/NdbConnectionScan.cpp b/ndb/src/ndbapi/NdbConnectionScan.cpp index 962acc0bdac..ea45f2b5a00 100644 --- a/ndb/src/ndbapi/NdbConnectionScan.cpp +++ b/ndb/src/ndbapi/NdbConnectionScan.cpp @@ -33,7 +33,6 @@ #include <NdbConnection.hpp> #include <NdbOperation.hpp> #include <NdbScanOperation.hpp> -#include "NdbScanReceiver.hpp" #include "NdbApiSignal.hpp" #include "TransporterFacade.hpp" #include "NdbUtil.hpp" @@ -49,299 +48,6 @@ #define WAITFOR_SCAN_TIMEOUT 120000 -/***************************************************************************** - * int executeScan(); - * - * 1. Check that the transaction is started and other important preconditions - * 2. Tell the kernel to start scanning by sending one SCAN_TABREQ, if - * parallelism is greater than 16 also send one SCAN_TABINFO for each - * additional 16 - * Define which attributes to scan in ATTRINFO, this signal also holds the - * interpreted program - * 3. Wait for the answer of the SCAN_TABREQ. This is either a SCAN_TABCONF if - * the scan was correctly defined and a SCAN_TABREF if the scan couldn't - * be started. - * 4. Check the result, if scan was not started return -1 - * - ****************************************************************************/ -int -NdbConnection::executeScan(){ - if (theTransactionIsStarted == true){ // Transaction already started. - setErrorCode(4600); - return -1; - } - if (theStatus != Connected) { // Lost connection - setErrorCode(4601); - return -1; - } - if (theScanningOp == NULL){ - setErrorCode(4602); // getNdbOperation must be called before executeScan - return -1; - } - TransporterFacade* tp = TransporterFacade::instance(); - theNoOfOpCompleted = 0; - theNoOfSCANTABCONFRecv = 0; - tp->lock_mutex(); - if (tp->get_node_alive(theDBnode) && - (tp->getNodeSequence(theDBnode) == theNodeSequence)) { - if (tp->check_send_size(theDBnode, get_send_size())) { - theTransactionIsStarted = true; - if (sendScanStart() == -1){ - tp->unlock_mutex(); - return -1; - }//if - theNdb->theWaiter.m_node = theDBnode; - theNdb->theWaiter.m_state = WAIT_SCAN; - int res = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); - if (res == 0) { - return 0; - } else { - if (res == -1) { - setErrorCode(4008); - } else if (res == -2) { - theTransactionIsStarted = false; - theReleaseOnClose = true; - setErrorCode(4028); - } else { - ndbout << "Impossible return from receiveResponse in executeScan"; - ndbout << endl; - abort(); - }//if - theCommitStatus = Aborted; - return -1; - }//if - } else { - TRACE_DEBUG("Start a scan with send buffer full attempted"); - setErrorCode(4022); - theCommitStatus = Aborted; - }//if - } else { - if (!(tp->get_node_stopping(theDBnode) && - (tp->getNodeSequence(theDBnode) == theNodeSequence))) { - TRACE_DEBUG("The node is hard dead when attempting to start a scan"); - setErrorCode(4029); - theReleaseOnClose = true; - } else { - TRACE_DEBUG("The node is stopping when attempting to start a scan"); - setErrorCode(4030); - }//if - theCommitStatus = Aborted; - }//if - tp->unlock_mutex(); - return -1; -} - -/****************************************************************************** - * int nextScanResult(); - * Remark: - * This method is used to distribute data received to the application. - * Iterate through the list and search for operations that haven't - * been distributed yet (status != Finished). - * If there are no more operations/records still waiting to be exececuted - * we have to send SCAN_NEXTREQ to fetch next set of records. - * - * TODO - This function should be able to return a value indicating if - * there are any more records already fetched from memory or if it has to - * ask the db for more. This would mean we could get better performance when - * takeOver is used wince we can take over all ops already fetched, put them - * in another trans and send them of to the db when there are no more records - * already fetched. Maybe use a new argument to the function for this -******************************************************************************/ -int -NdbConnection::nextScanResult(bool fetchAllowed){ - - if (theTransactionIsStarted != true){ // Transaction not started. - setErrorCode(4601); - return -1; - } - // Scan has finished ok but no operations recived = empty recordset. - if(theScanFinished == true){ - return 1; // No more records - } - if (theStatus != Connected){// Lost connection - setErrorCode(4601); - return -1; - } - // Something went wrong, probably we got a SCAN_TABREF earlier. - if (theCompletionStatus == CompletedFailure) { - return -1; - } - if (theNoOfOpCompleted == theNoOfOpFetched) { - // There are no more records cached in NdbApi - if (fetchAllowed == true){ - // Get some more records from db - - if (fetchNextScanResult() == -1){ - return -1; - } - if (theScanFinished == true) { // The scan has finished. - return 1; // 1 = No more records - } - if (theCompletionStatus == CompletedFailure) { - return -1; // Something went wrong, probably we got a SCAN_TABREF. - } - } else { - // There where no more cached records in NdbApi - // and we where not allowed to go to db and ask for - // more - return 2; - } - } - - // It's not allowed to come here without any cached records - if (theCurrentScanRec == NULL){ -#ifdef VM_TRACE - ndbout << "nextScanResult("<<fetchAllowed<<")"<<endl - << " theTransactionIsStarted = " << theTransactionIsStarted << endl - << " theScanFinished = " << theScanFinished << endl - << " theCommitStatus = " << theCommitStatus << endl - << " theStatus = " << theStatus << endl - << " theCompletionStatus = " << theCompletionStatus << endl - << " theNoOfOpCompleted = " << theNoOfOpCompleted << endl - << " theNoOfOpFetched = " << theNoOfOpFetched << endl - << " theScanningOp = " << theScanningOp << endl - << " theNoOfSCANTABCONFRecv = "<< theNoOfSCANTABCONFRecv << endl - << " theNdb->theWaiter.m_node = " <<theNdb->theWaiter.m_node<<endl - << " theNdb->theWaiter.m_state = " << theNdb->theWaiter.m_state << endl; - abort(); -#endif - return -1; - } - - // Execute the saved signals for this operation. - NdbScanReceiver* tScanRec = theCurrentScanRec; - theScanningOp->theCurrRecAI_Len = 0; - theScanningOp->theCurrentRecAttr = theScanningOp->theFirstRecAttr; - if(tScanRec->executeSavedSignals() != 0) - return -1; - theNoOfOpCompleted++; - // Remember for next iteration and takeOverScanOp - thePreviousScanRec = tScanRec; - theCurrentScanRec = tScanRec->next(); - return 0; // 0 = There are more rows to be fetched. -} - -/****************************************************************************** - * int stopScan() - * Remark: By sending SCAN_NEXTREQ with data word 2 set to TRUE we - * abort the scan process. - *****************************************************************************/ -int -NdbConnection::stopScan() -{ - if(theScanFinished == true){ - return 0; - } - if (theCompletionStatus == CompletedFailure){ - return 0; - } - - if (theScanningOp == 0){ - return 0; - } - - theNoOfOpCompleted = 0; - theNoOfSCANTABCONFRecv = 0; - theScanningOp->prepareNextScanResult(); - return sendScanNext(1); -} - - -/******************************************************************** - * int sendScanStart() - * - * Send the signals reuired to define and start the scan - * 1. Send SCAN_TABREQ - * 2. Send SCAN_TABINFO(if any, parallelism must be > 16) - * 3. Send ATTRINFO signals - * - * Returns -1 if an error occurs otherwise 0. - * - ********************************************************************/ -int -NdbConnection::sendScanStart(){ - - /***** 0. Prepare signals ******************/ - // This might modify variables and signals - if(theScanningOp->prepareSendScan(theTCConPtr, - theTransactionId) == -1) - return -1; - - /***** 1. Send SCAN_TABREQ **************/ - /***** 2. Send SCAN_TABINFO *************/ - /***** 3. Send ATTRINFO signals *********/ - if (theScanningOp->doSendScan(theDBnode) == -1) - return -1; - return 0; -} - - -int -NdbConnection::fetchNextScanResult(){ - theNoOfOpCompleted = 0; - theNoOfSCANTABCONFRecv = 0; - theScanningOp->prepareNextScanResult(); - return sendScanNext(0); -} - - - -/*********************************************************** - * int sendScanNext(int stopScanFlag) - * - * ************************************************************/ -int NdbConnection::sendScanNext(bool stopScanFlag){ - NdbApiSignal tSignal(theNdb->theMyRef); - Uint32 tTransId1, tTransId2; - tSignal.setSignal(GSN_SCAN_NEXTREQ); - tSignal.setData(theTCConPtr, 1); - // Set the stop flag in word 2(1 = stop) - Uint32 tStopValue; - tStopValue = stopScanFlag == true ? 1 : 0; - tSignal.setData(tStopValue, 2); - tTransId1 = (Uint32) theTransactionId; - tTransId2 = (Uint32) (theTransactionId >> 32); - tSignal.setData(tTransId1, 3); - tSignal.setData(tTransId2, 4); - tSignal.setLength(4); - Uint32 conn_seq = theNodeSequence; - int return_code = theNdb->sendRecSignal(theDBnode, - WAIT_SCAN, - &tSignal, - conn_seq); - if (return_code == 0) { - return 0; - } else if (return_code == -1) { // Time-out - TRACE_DEBUG("Time-out when sending sendScanNext"); - setErrorCode(4024); - theTransactionIsStarted = false; - theReleaseOnClose = true; - theCommitStatus = Aborted; - } else if (return_code == -2) { // Node failed - TRACE_DEBUG("Node failed when sendScanNext"); - setErrorCode(4027); - theTransactionIsStarted = false; - theReleaseOnClose = true; - theCommitStatus = Aborted; - } else if (return_code == -3) { - TRACE_DEBUG("Send failed when sendScanNext"); - setErrorCode(4033); - theTransactionIsStarted = false; - theReleaseOnClose = true; - theCommitStatus = Aborted; - } else if (return_code == -4) { - TRACE_DEBUG("Send buffer full when sendScanNext"); - setErrorCode(4032); - } else if (return_code == -5) { - TRACE_DEBUG("Node stopping when sendScanNext"); - setErrorCode(4034); - } else { - ndbout << "Impossible return from sendRecSignal" << endl; - abort(); - }//if - return -1; -} - /*************************************************************************** * int receiveSCAN_TABREF(NdbApiSignal* aSignal) @@ -352,39 +58,13 @@ int NdbConnection::sendScanNext(bool stopScanFlag){ ****************************************************************************/ int NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){ - const ScanTabRef * const scanTabRef = CAST_CONSTPTR(ScanTabRef, aSignal->getDataPtr()); - if (theStatus != Connected){ -#ifdef VM_TRACE - ndbout << "SCAN_TABREF dropped, theStatus = " << theStatus << endl; -#endif - return -1; - } - if (aSignal->getLength() != ScanTabRef::SignalLength){ -#ifdef VM_TRACE - ndbout << "SCAN_TABREF dropped, signal length " << aSignal->getLength() << endl; -#endif - return -1; - } - const Uint64 tCurrTransId = this->getTransactionId(); - const Uint64 tRecTransId = (Uint64)scanTabRef->transId1 + - ((Uint64)scanTabRef->transId2 << 32); - if ((tRecTransId - tCurrTransId) != (Uint64)0){ -#ifdef VM_TRACE - ndbout << "SCAN_TABREF dropped, wrong transid" << endl; -#endif - return -1; + const ScanTabRef * ref = CAST_CONSTPTR(ScanTabRef, aSignal->getDataPtr()); + + if(checkState_TransId(&ref->transId1)){ + theScanningOp->execCLOSE_SCAN_REP(ref->errorCode); + return 0; } -#if 0 - ndbout << "SCAN_TABREF, " - <<"transid=("<<hex<<scanTabRef->transId1<<", "<<hex<<scanTabRef->transId2<<")" - <<", err="<<dec<<scanTabRef->errorCode << endl; -#endif - setErrorCode(scanTabRef->errorCode); - theCompletionStatus = CompletedFailure; - theCommitStatus = Aborted; // Indicate that this "transaction" was aborted - theTransactionIsStarted = false; - theScanningOp->releaseSignals(); - return 0; + return -1; } /***************************************************************************** @@ -401,173 +81,43 @@ NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){ * *****************************************************************************/ int -NdbConnection::receiveSCAN_TABCONF(NdbApiSignal* aSignal) -{ - const ScanTabConf * const conf = CAST_CONSTPTR(ScanTabConf, aSignal->getDataPtr()); - if (theStatus != Connected){ -#ifdef VM_TRACE - ndbout << "Dropping SCAN_TABCONF, theStatus = "<< theStatus << endl; -#endif - return -1; - } - if(aSignal->getLength() != ScanTabConf::SignalLength){ -#ifdef VM_TRACE - ndbout << "Dropping SCAN_TABCONF, getLength = "<< aSignal->getLength() << endl; -#endif - return -1; - } - const Uint64 tCurrTransId = this->getTransactionId(); - const Uint64 tRecTransId = - (Uint64)conf->transId1 + ((Uint64)conf->transId2 << 32); - if ((tRecTransId - tCurrTransId) != (Uint64)0){ -#ifdef VM_TRACE - ndbout << "Dropping SCAN_TABCONF, wrong transid" << endl; -#endif - return -1; - } - - const Uint8 scanStatus = - ScanTabConf::getScanStatus(conf->requestInfo); - - if (scanStatus != 0) { - theCompletionStatus = CompletedSuccess; - theCommitStatus = Committed; - theScanFinished = true; - return 0; - } - - // There can only be one SCANTABCONF - assert(theNoOfSCANTABCONFRecv == 0); - theNoOfSCANTABCONFRecv++; - - // Save a copy of the signal - NdbApiSignal * tCopy = new NdbApiSignal(0);//getSignal(); - if (tCopy == NULL){ - setErrorCode(4000); - return 2; // theWaiter.m_state = NO_WAIT - } - tCopy->copyFrom(aSignal); - tCopy->next(NULL); - theScanningOp->theSCAN_TABCONF_Recv = tCopy; - - return checkNextScanResultComplete(); - -} - -/***************************************************************************** - * int receiveSCAN_TABINFO(NdbApiSignal* aSignal) - * - * Receive SCAN_TABINFO - * - *****************************************************************************/ -int -NdbConnection::receiveSCAN_TABINFO(NdbApiSignal* aSignal) +NdbConnection::receiveSCAN_TABCONF(NdbApiSignal* aSignal, + const Uint32 * ops, Uint32 len) { - if (theStatus != Connected){ - //ndbout << "SCAN_TABINFO dropped, theStatus = " << theStatus << endl; - return -1; - } - if (aSignal->getLength() != ScanTabInfo::SignalLength){ - //ndbout << "SCAN_TABINFO dropped, length = " << aSignal->getLength() << endl; - return -1; - } - - NdbApiSignal * tCopy = new NdbApiSignal(0);//getSignal(); - if (tCopy == NULL){ - setErrorCode(4000); - return 2; // theWaiter.m_state = NO_WAIT - } - tCopy->copyFrom(aSignal); - tCopy->next(NULL); - - // Put the signal last in list - if (theScanningOp->theFirstSCAN_TABINFO_Recv == NULL) - theScanningOp->theFirstSCAN_TABINFO_Recv = tCopy; - else - theScanningOp->theLastSCAN_TABINFO_Recv->next(tCopy); - theScanningOp->theLastSCAN_TABINFO_Recv = tCopy; - - return checkNextScanResultComplete(); -} - -/****************************************************************************** - * int checkNextScanResultComplete(NdbApiSignal* aSignal) - * - * Remark Traverses all the lists that are associated with - * this resultset and checks if all signals are there. - * If all required signal are received return 0 - * - * - *****************************************************************************/ -int -NdbConnection::checkNextScanResultComplete(){ - - if (theNoOfSCANTABCONFRecv != 1) { - return -1; - } - - Uint32 tNoOfOpFetched = 0; - theCurrentScanRec = NULL; - thePreviousScanRec = NULL; - - const ScanTabConf * const conf = - CAST_CONSTPTR(ScanTabConf, theScanningOp->theSCAN_TABCONF_Recv->getDataPtr()); - const Uint32 numOperations = ScanTabConf::getOperations(conf->requestInfo); - Uint32 sigIndex = 0; - NdbApiSignal* tSignal = theScanningOp->theFirstSCAN_TABINFO_Recv; - while(tSignal != NULL){ - const ScanTabInfo * const info = CAST_CONSTPTR(ScanTabInfo, tSignal->getDataPtr()); - // Loop through the operations for this SCAN_TABINFO - // tOpAndLength is allowed to be zero, this means no - // TRANSID_AI signals where sent for this record - // I.e getValue was called 0 times when defining scan - - // The max number of operations in each signal is 16 - Uint32 numOpsInSig = numOperations - sigIndex*16; - if (numOpsInSig > 16) - numOpsInSig = 16; - for(Uint32 i = 0; i < numOpsInSig; i++){ - const Uint32 tOpAndLength = info->operLenAndIdx[i]; - const Uint32 tOpIndex = ScanTabInfo::getIdx(tOpAndLength); - const Uint32 tOpLen = ScanTabInfo::getLen(tOpAndLength); - - assert(tOpIndex < 256); - NdbScanReceiver* tScanRec = - theScanningOp->theScanReceiversArray[tOpIndex]; - assert(tScanRec != NULL); - if(tScanRec->isCompleted(tOpLen)) - tScanRec->setCompleted(); - else{ - return -1; // At least one receiver was not ready - } - - // Build list of scan receivers - if (theCurrentScanRec == NULL) { - theCurrentScanRec = tScanRec; - thePreviousScanRec = tScanRec; - } else { - thePreviousScanRec->next(tScanRec); - thePreviousScanRec = tScanRec; + const ScanTabConf * conf = CAST_CONSTPTR(ScanTabConf, aSignal->getDataPtr()); + if(checkState_TransId(&conf->transId1)){ + + if (conf->requestInfo == ScanTabConf::EndOfData) { + theScanningOp->execCLOSE_SCAN_REP(0); + return 0; + } + + int noComp = -1; + for(Uint32 i = 0; i<len; i += 3){ + Uint32 ptrI = * ops++; + Uint32 tcPtrI = * ops++; + Uint32 info = * ops++; + Uint32 opCount = ScanTabConf::getRows(info); + Uint32 totalLen = ScanTabConf::getLength(info); + + void * tPtr = theNdb->int2void(ptrI); + assert(tPtr); // For now + NdbReceiver* tOp = theNdb->void2rec(tPtr); + if (tOp && tOp->checkMagicNumber()){ + if(tOp->execSCANOPCONF(tcPtrI, totalLen, opCount)){ + /** + * + */ + noComp++; + theScanningOp->receiver_delivered(tOp); + } else if(info == ScanTabConf::EndOfData){ + noComp++; + theScanningOp->receiver_completed(tOp); + } } - tNoOfOpFetched++; } - tSignal = tSignal->next(); - sigIndex++; - } - - // Check number of operations fetched against value in SCANTAB_CONF - if (tNoOfOpFetched != numOperations) { - setErrorCode(4113); - return 2; // theWaiter.m_state = NO_WAIT + return noComp; } - // All signals for this resultset recieved - // release SCAN_TAB signals - theNoOfSCANTABCONFRecv = 0; - theScanningOp->releaseSignals(); - - // We have received all operations with correct lengths. - thePreviousScanRec = NULL; - theNoOfOpFetched = tNoOfOpFetched; - return 0; + return -1; } diff --git a/ndb/src/ndbapi/NdbCursorOperation.cpp b/ndb/src/ndbapi/NdbCursorOperation.cpp index e4dd600c57f..a9f84c4c110 100644 --- a/ndb/src/ndbapi/NdbCursorOperation.cpp +++ b/ndb/src/ndbapi/NdbCursorOperation.cpp @@ -30,8 +30,6 @@ #include <NdbResultSet.hpp> NdbCursorOperation::NdbCursorOperation(Ndb* aNdb) : - NdbOperation(aNdb), - m_resultSet(0) { } @@ -48,10 +46,6 @@ void NdbCursorOperation::cursInit() NdbResultSet* NdbCursorOperation::getResultSet() { - if (!m_resultSet) - m_resultSet = new NdbResultSet(this); - - return m_resultSet; } diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 3b31fa70e35..899359b12a4 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -257,6 +257,7 @@ NdbTableImpl::init(){ m_indexType = NdbDictionary::Index::Undefined; m_noOfKeys = 0; + m_fragmentCount = 0; } bool @@ -275,11 +276,9 @@ NdbTableImpl::equal(const NdbTableImpl& obj) const if(strcmp(m_internalName.c_str(), obj.m_internalName.c_str()) != 0){ return false; } - if(m_fragmentType != obj.m_fragmentType){ return false; } - if(m_columns.size() != obj.m_columns.size()){ return false; } @@ -318,6 +317,7 @@ NdbTableImpl::assign(const NdbTableImpl& org) m_newExternalName.assign(org.m_newExternalName); m_frm.assign(org.m_frm.get_data(), org.m_frm.length()); m_fragmentType = org.m_fragmentType; + m_fragmentCount = org.m_fragmentCount; for(unsigned i = 0; i<org.m_columns.size(); i++){ NdbColumnImpl * col = new NdbColumnImpl(); @@ -826,6 +826,7 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal, m_waiter.m_state = wst; m_waiter.wait(theWait); + m_transporter->unlock_mutex(); // End of Protected area if(m_waiter.m_state == NO_WAIT && m_error.code == 0){ @@ -1115,6 +1116,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, impl->m_kvalue = tableDesc.TableKValue; impl->m_minLoadFactor = tableDesc.MinLoadFactor; impl->m_maxLoadFactor = tableDesc.MaxLoadFactor; + impl->m_fragmentCount = tableDesc.FragmentCount; impl->m_indexType = (NdbDictionary::Index::Type) getApiConstant(tableDesc.TableType, @@ -1198,6 +1200,8 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, it.next(); } impl->m_noOfKeys = keyCount; + impl->m_keyLenInWords = keyInfoPos; + * ret = impl; return 0; } @@ -2707,6 +2711,7 @@ NdbDictInterface::listObjects(NdbApiSignal* signal) m_waiter.m_node = aNodeId; m_waiter.m_state = WAIT_LIST_TABLES_CONF; m_waiter.wait(WAITFOR_RESPONSE_TIMEOUT); + m_transporter->unlock_mutex(); // end protected if (m_waiter.m_state == NO_WAIT && m_error.code == 0) return 0; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp index 3263a636a79..311d101f8f4 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -123,7 +123,9 @@ public: int m_kvalue; int m_minLoadFactor; int m_maxLoadFactor; - + int m_keyLenInWords; + int m_fragmentCount; + NdbDictionaryImpl * m_dictionary; NdbIndexImpl * m_index; NdbColumnImpl * getColumn(unsigned attrId); diff --git a/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/ndb/src/ndbapi/NdbEventOperationImpl.cpp index 7b4afc72ef7..6ece69cce91 100644 --- a/ndb/src/ndbapi/NdbEventOperationImpl.cpp +++ b/ndb/src/ndbapi/NdbEventOperationImpl.cpp @@ -166,7 +166,7 @@ NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, in } //theErrorLine++; - tRecAttr->setUNDEFINED(); + tRecAttr->setNULL(); // We want to keep the list sorted to make data insertion easier later if (theFirstRecAttr == NULL) { @@ -387,7 +387,7 @@ NdbEventOperationImpl::next(int *pOverrun) while (tAttrId > tRecAttrId) { //printf("[%u] %u %u [%u]\n", tAttrId, tDataSz, *aDataPtr, tRecAttrId); - tWorkingRecAttr->setUNDEFINED(); + tWorkingRecAttr->setNULL(); tWorkingRecAttr = tWorkingRecAttr->next(); if (tWorkingRecAttr == NULL) break; @@ -399,19 +399,16 @@ NdbEventOperationImpl::next(int *pOverrun) //printf("[%u] %u %u [%u]\n", tAttrId, tDataSz, *aDataPtr, tRecAttrId); if (tAttrId == tRecAttrId) { - tWorkingRecAttr->setNotNULL(); if (!m_eventImpl->m_tableImpl->getColumn(tRecAttrId)->getPrimaryKey()) hasSomeData++; //printf("set!\n"); - Uint32 *theRef = (Uint32*)tWorkingRecAttr->aRef(); - Uint32 *theEndRef = theRef + tDataSz; - while (theRef < theEndRef) - *theRef++ = *aDataPtr++; + tWorkingRecAttr->receive_data(aDataPtr, tDataSz); // move forward, data has already moved forward aAttrPtr++; + aDataPtr += tDataSz; tWorkingRecAttr = tWorkingRecAttr->next(); } else { // move only attr forward @@ -423,7 +420,7 @@ NdbEventOperationImpl::next(int *pOverrun) while (tWorkingRecAttr != NULL) { tRecAttrId = tWorkingRecAttr->attrId(); //printf("set undefined [%u] %u %u [%u]\n", tAttrId, tDataSz, *aDataPtr, tRecAttrId); - tWorkingRecAttr->setUNDEFINED(); + tWorkingRecAttr->setNULL(); tWorkingRecAttr = tWorkingRecAttr->next(); } @@ -436,7 +433,7 @@ NdbEventOperationImpl::next(int *pOverrun) tDataSz = AttributeHeader(*aDataPtr).getDataSize(); aDataPtr++; while (tAttrId > tRecAttrId) { - tWorkingRecAttr->setUNDEFINED(); + tWorkingRecAttr->setNULL(); tWorkingRecAttr = tWorkingRecAttr->next(); if (tWorkingRecAttr == NULL) break; @@ -445,16 +442,11 @@ NdbEventOperationImpl::next(int *pOverrun) if (tWorkingRecAttr == NULL) break; if (tAttrId == tRecAttrId) { - tWorkingRecAttr->setNotNULL(); - if (!m_eventImpl->m_tableImpl->getColumn(tRecAttrId)->getPrimaryKey()) hasSomeData++; - Uint32 *theRef = (Uint32*)tWorkingRecAttr->aRef(); - Uint32 *theEndRef = theRef + tDataSz; - while (theRef < theEndRef) - *theRef++ = *aDataPtr++; - + tWorkingRecAttr->receive_data(aDataPtr, tDataSz); + aDataPtr += tDataSz; // move forward, data+attr has already moved forward tWorkingRecAttr = tWorkingRecAttr->next(); } else { @@ -463,7 +455,7 @@ NdbEventOperationImpl::next(int *pOverrun) } } while (tWorkingRecAttr != NULL) { - tWorkingRecAttr->setUNDEFINED(); + tWorkingRecAttr->setNULL(); tWorkingRecAttr = tWorkingRecAttr->next(); } diff --git a/ndb/src/ndbapi/NdbImpl.hpp b/ndb/src/ndbapi/NdbImpl.hpp index cd05335b337..1fb1969b589 100644 --- a/ndb/src/ndbapi/NdbImpl.hpp +++ b/ndb/src/ndbapi/NdbImpl.hpp @@ -35,6 +35,7 @@ public: #include <NdbError.hpp> #include <NdbCondition.h> #include <NdbReceiver.hpp> +#include <NdbOperation.hpp> #include <NdbTick.h> @@ -83,12 +84,13 @@ Ndb::void2rec_iop(void* val){ return (NdbIndexOperation*)(void2rec(val)->getOwner()); } -inline -NdbScanReceiver* -Ndb::void2rec_srec(void* val){ - return (NdbScanReceiver*)(void2rec(val)->getOwner()); +inline +NdbConnection * +NdbReceiver::getTransaction(){ + return ((NdbOperation*)m_owner)->theNdbCon; } + inline int Ndb::checkInitState() @@ -151,7 +153,6 @@ NdbWaiter::wait(int waitTime) waitTime = maxTime - NdbTick_CurrentMillisecond(); } } - NdbMutex_Unlock((NdbMutex*)m_mutex); } inline diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp index 02d94f39f2d..d976c912c5e 100644 --- a/ndb/src/ndbapi/NdbIndexOperation.cpp +++ b/ndb/src/ndbapi/NdbIndexOperation.cpp @@ -52,7 +52,7 @@ NdbIndexOperation::NdbIndexOperation(Ndb* aNdb) : /** * Change receiver type */ - theReceiver.init(NdbReceiver::NDB_INDEX_OPERATION, this); + theReceiver.init(NdbReceiver::NDB_INDEX_OPERATION, this, false); } NdbIndexOperation::~NdbIndexOperation() @@ -664,10 +664,8 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) tSignal = tnextSignal; } while (tSignal != NULL); }//if - NdbRecAttr* tRecAttrObject = theFirstRecAttr; theStatus = WaitResponse; - theCurrentRecAttr = tRecAttrObject; - + theReceiver.prepareSend(); return 0; } diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp index 8bc9111d060..74d6a462ac8 100644 --- a/ndb/src/ndbapi/NdbOperation.cpp +++ b/ndb/src/ndbapi/NdbOperation.cpp @@ -54,7 +54,6 @@ NdbOperation::NdbOperation(Ndb* aNdb) : //theTable(aTable), theNdbCon(NULL), theNext(NULL), - theNextScanOp(NULL), theTCREQ(NULL), theFirstATTRINFO(NULL), theCurrentATTRINFO(NULL), @@ -62,8 +61,6 @@ NdbOperation::NdbOperation(Ndb* aNdb) : theAI_LenInCurrAI(0), theFirstKEYINFO(NULL), theLastKEYINFO(NULL), - theFirstRecAttr(NULL), - theCurrentRecAttr(NULL), theFirstLabel(NULL), theLastLabel(NULL), @@ -76,10 +73,6 @@ NdbOperation::NdbOperation(Ndb* aNdb) : theNoOfLabels(0), theNoOfSubroutines(0), - theTotalRecAI_Len(0), - theCurrRecAI_Len(0), - theAI_ElementLen(0), - theCurrElemPtr(NULL), m_currentTable(NULL), //theTableId(0xFFFF), m_accessTable(NULL), //theAccessTableId(0xFFFF), //theSchemaVersion(0), @@ -95,17 +88,9 @@ NdbOperation::NdbOperation(Ndb* aNdb) : m_tcReqGSN(GSN_TCKEYREQ), m_keyInfoGSN(GSN_KEYINFO), m_attrInfoGSN(GSN_ATTRINFO), - theParallelism(0), - theScanReceiversArray(NULL), - theSCAN_TABREQ(NULL), - theFirstSCAN_TABINFO_Send(NULL), - theLastSCAN_TABINFO_Send(NULL), - theFirstSCAN_TABINFO_Recv(NULL), - theLastSCAN_TABINFO_Recv(NULL), - theSCAN_TABCONF_Recv(NULL), theBoundATTRINFO(NULL) { - theReceiver.init(NdbReceiver::NDB_OPERATION, this); + theReceiver.init(NdbReceiver::NDB_OPERATION, this, false); theError.code = 0; } /***************************************************************************** @@ -165,7 +150,7 @@ NdbOperation::init(NdbTableImpl* tab, NdbConnection* myConnection){ theNdbCon = myConnection; for (Uint32 i=0; i<NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY; i++) for (int j=0; j<3; j++) - theTupleKeyDefined[i][j] = false; + theTupleKeyDefined[i][j] = 0; theFirstATTRINFO = NULL; theCurrentATTRINFO = NULL; @@ -175,13 +160,11 @@ NdbOperation::init(NdbTableImpl* tab, NdbConnection* myConnection){ theTupKeyLen = 0; theNoOfTupKeyDefined = 0; - theTotalCurrAI_Len = 0; - theAI_LenInCurrAI = 0; - theTotalRecAI_Len = 0; theDistrKeySize = 0; theDistributionGroup = 0; - theCurrRecAI_Len = 0; - theAI_ElementLen = 0; + + theTotalCurrAI_Len = 0; + theAI_LenInCurrAI = 0; theStartIndicator = 0; theCommitIndicator = 0; theSimpleIndicator = 0; @@ -191,9 +174,6 @@ NdbOperation::init(NdbTableImpl* tab, NdbConnection* myConnection){ theDistrGroupType = 0; theDistrKeyIndicator = 0; theScanInfo = 0; - theFirstRecAttr = NULL; - theCurrentRecAttr = NULL; - theCurrElemPtr = NULL; theTotalNrOfKeyWordInSignal = 8; theMagicNumber = 0xABCDEF01; theBoundATTRINFO = NULL; @@ -212,6 +192,7 @@ NdbOperation::init(NdbTableImpl* tab, NdbConnection* myConnection){ tcKeyReq->scanInfo = 0; theKEYINFOptr = &tcKeyReq->keyInfo[0]; theATTRINFOptr = &tcKeyReq->attrInfo[0]; + theReceiver.init(NdbReceiver::NDB_OPERATION, this, false); return 0; } @@ -226,8 +207,6 @@ NdbOperation::release() { NdbApiSignal* tSignal; NdbApiSignal* tSaveSignal; - NdbRecAttr* tRecAttr; - NdbRecAttr* tSaveRecAttr; NdbBranch* tBranch; NdbBranch* tSaveBranch; NdbLabel* tLabel; @@ -260,15 +239,6 @@ NdbOperation::release() } theFirstKEYINFO = NULL; theLastKEYINFO = NULL; - tRecAttr = theFirstRecAttr; - while (tRecAttr != NULL) - { - tSaveRecAttr = tRecAttr; - tRecAttr = tRecAttr->next(); - theNdb->releaseRecAttr(tSaveRecAttr); - } - theFirstRecAttr = NULL; - theCurrentRecAttr = NULL; if (theInterpretIndicator == 1) { tBranch = theFirstBranch; @@ -308,19 +278,18 @@ NdbOperation::release() } theBoundATTRINFO = NULL; } - releaseScan(); } NdbRecAttr* NdbOperation::getValue(const char* anAttrName, char* aValue) { - return getValue(m_currentTable->getColumn(anAttrName), aValue); + return getValue_impl(m_currentTable->getColumn(anAttrName), aValue); } NdbRecAttr* NdbOperation::getValue(Uint32 anAttrId, char* aValue) { - return getValue(m_currentTable->getColumn(anAttrId), aValue); + return getValue_impl(m_currentTable->getColumn(anAttrId), aValue); } int @@ -416,16 +385,4 @@ NdbOperation::write_attr(Uint32 anAttrId, Uint32 RegDest) return write_attr(m_currentTable->getColumn(anAttrId), RegDest); } -int -NdbOperation::setBound(const char* anAttrName, int type, const void* aValue, Uint32 len) -{ - return setBound(m_accessTable->getColumn(anAttrName), type, aValue, len); -} - -int -NdbOperation::setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len) -{ - return setBound(m_accessTable->getColumn(anAttrId), type, aValue, len); -} - diff --git a/ndb/src/ndbapi/NdbOperationDefine.cpp b/ndb/src/ndbapi/NdbOperationDefine.cpp index 20134068075..c174c6a629a 100644 --- a/ndb/src/ndbapi/NdbOperationDefine.cpp +++ b/ndb/src/ndbapi/NdbOperationDefine.cpp @@ -34,6 +34,7 @@ #include "NdbUtil.hpp" #include "NdbOut.hpp" #include "NdbImpl.hpp" +#include <NdbScanOperation.hpp> #include <Interpreter.hpp> @@ -261,30 +262,10 @@ NdbOperation::interpretedUpdateTuple() theStatus = OperationDefined; tNdbCon->theSimpleState = 0; theOperationType = UpdateRequest; - theInterpretIndicator = 1; theAI_LenInCurrAI = 25; theErrorLine = tErrorLine++; - theTotalCurrAI_Len = 5; - theSubroutineSize = 0; - theInitialReadSize = 0; - theInterpretedSize = 0; - theFinalUpdateSize = 0; - theFinalReadSize = 0; - - theFirstLabel = NULL; - theLastLabel = NULL; - theFirstBranch = NULL; - theLastBranch = NULL; - - theFirstCall = NULL; - theLastCall = NULL; - theFirstSubroutine = NULL; - theLastSubroutine = NULL; - - theNoOfLabels = 0; - theNoOfSubroutines = 0; - + initInterpreter(); return 0; } else { setErrorCode(4200); @@ -304,30 +285,11 @@ NdbOperation::interpretedDeleteTuple() theStatus = OperationDefined; tNdbCon->theSimpleState = 0; theOperationType = DeleteRequest; - theInterpretIndicator = 1; theErrorLine = tErrorLine++; theAI_LenInCurrAI = 25; - theTotalCurrAI_Len = 5; - theSubroutineSize = 0; - theInitialReadSize = 0; - theInterpretedSize = 0; - theFinalUpdateSize = 0; - theFinalReadSize = 0; - - theFirstLabel = NULL; - theLastLabel = NULL; - theFirstBranch = NULL; - theLastBranch = NULL; - - theFirstCall = NULL; - theLastCall = NULL; - theFirstSubroutine = NULL; - theLastSubroutine = NULL; - - theNoOfLabels = 0; - theNoOfSubroutines = 0; + initInterpreter(); return 0; } else { setErrorCode(4200); @@ -347,14 +309,14 @@ NdbOperation::interpretedDeleteTuple() * Remark: Define an attribute to retrieve in query. *****************************************************************************/ NdbRecAttr* -NdbOperation::getValue(const NdbColumnImpl* tAttrInfo, char* aValue) +NdbOperation::getValue_impl(const NdbColumnImpl* tAttrInfo, char* aValue) { NdbRecAttr* tRecAttr; if ((tAttrInfo != NULL) && (!tAttrInfo->m_indexOnly) && (theStatus != Init)){ if (theStatus == SetBound) { - saveBoundATTRINFO(); + ((NdbScanOperation*)this)->saveBoundATTRINFO(); theStatus = GetValue; } if (theStatus != GetValue) { @@ -386,33 +348,15 @@ NdbOperation::getValue(const NdbColumnImpl* tAttrInfo, char* aValue) // Insert Attribute Id into ATTRINFO part. /************************************************************************ - * Get a Receive Attribute object and link it into the operation object. - ************************************************************************/ - tRecAttr = theNdb->getRecAttr(); - if (tRecAttr != NULL) { - if (theFirstRecAttr == NULL) - theFirstRecAttr = tRecAttr; - else - theCurrentRecAttr->next(tRecAttr); - theCurrentRecAttr = tRecAttr; - tRecAttr->next(NULL); - - /********************************************************************** - * Now set the attribute identity and the pointer to the data in - * the RecAttr object - * Also set attribute size, array size and attribute type - ********************************************************************/ - if (tRecAttr->setup(tAttrInfo, aValue) == 0) { - theErrorLine++; - return tRecAttr; - } else { - setErrorCodeAbort(4000); - return NULL; - } - } else { + * Get a Receive Attribute object and link it into the operation object. + ***********************************************************************/ + if((tRecAttr = theReceiver.getValue(tAttrInfo, aValue)) != 0){ + theErrorLine++; + return tRecAttr; + } else { setErrorCodeAbort(4000); return NULL; - }//if getRecAttr failure + } } else { return NULL; }//if insertATTRINFO failure @@ -603,47 +547,6 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, return 0; }//NdbOperation::setValue() -/* - * Define bound on index column in range scan. - */ -int -NdbOperation::setBound(const NdbColumnImpl* tAttrInfo, int type, const void* aValue, Uint32 len) -{ - if (theOperationType == OpenRangeScanRequest && - theStatus == SetBound && - (0 <= type && type <= 4) && - aValue != NULL && - len <= 8000) { - // bound type - insertATTRINFO(type); - // attribute header - Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; - if (len != sizeInBytes && (len != 0)) { - setErrorCodeAbort(4209); - return -1; - } - len = sizeInBytes; - Uint32 tIndexAttrId = tAttrInfo->m_attrId; - Uint32 sizeInWords = (len + 3) / 4; - AttributeHeader ah(tIndexAttrId, sizeInWords); - insertATTRINFO(ah.m_value); - // attribute data - if ((UintPtr(aValue) & 0x3) == 0 && (len & 0x3) == 0) - insertATTRINFOloop((const Uint32*)aValue, sizeInWords); - else { - Uint32 temp[2000]; - memcpy(temp, aValue, len); - while ((len & 0x3) != 0) - ((char*)temp)[len++] = 0; - insertATTRINFOloop(temp, sizeInWords); - } - return 0; - } else { - setErrorCodeAbort(4228); // XXX wrong code - return -1; - } -} - /**************************************************************************** * int insertATTRINFO( Uint32 aData ); * diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp index d00c527550d..3d8c2f29615 100644 --- a/ndb/src/ndbapi/NdbOperationExec.cpp +++ b/ndb/src/ndbapi/NdbOperationExec.cpp @@ -46,83 +46,6 @@ Documentation: #include <NdbOut.hpp> -/****************************************************************************** -int doSend() - -Return Value: Return >0 : send was succesful, returns number of signals sent - Return -1: In all other case. -Parameters: aProcessorId: Receiving processor node -Remark: Sends the ATTRINFO signal(s) -******************************************************************************/ -int -NdbOperation::doSendScan(int aProcessorId) -{ - Uint32 tSignalCount = 0; - NdbApiSignal* tSignal; - - if (theInterpretIndicator != 1 || - (theOperationType != OpenScanRequest && - theOperationType != OpenRangeScanRequest)) { - setErrorCodeAbort(4005); - return -1; - } - - assert(theSCAN_TABREQ != NULL); - tSignal = theSCAN_TABREQ; - if (tSignal->setSignal(GSN_SCAN_TABREQ) == -1) { - setErrorCode(4001); - return -1; - } - // Update the "attribute info length in words" in SCAN_TABREQ before - // sending it. This could not be done in openScan because - // we created the ATTRINFO signals after the SCAN_TABREQ signal. - ScanTabReq * const scanTabReq = CAST_PTR(ScanTabReq, tSignal->getDataPtrSend()); - scanTabReq->attrLen = theTotalCurrAI_Len; - if (theOperationType == OpenRangeScanRequest) - scanTabReq->attrLen += theTotalBoundAI_Len; - TransporterFacade *tp = TransporterFacade::instance(); - if (tp->sendSignal(tSignal, aProcessorId) == -1) { - setErrorCode(4002); - return -1; - } - tSignalCount++; - - tSignal = theFirstSCAN_TABINFO_Send; - while (tSignal != NULL){ - if (tp->sendSignal(tSignal, aProcessorId)) { - setErrorCode(4002); - return -1; - } - tSignalCount++; - tSignal = tSignal->next(); - } - - if (theOperationType == OpenRangeScanRequest) { - // must have at least one signal since it contains attrLen for bounds - assert(theBoundATTRINFO != NULL); - tSignal = theBoundATTRINFO; - while (tSignal != NULL) { - if (tp->sendSignal(tSignal,aProcessorId) == -1){ - setErrorCode(4002); - return -1; - } - tSignalCount++; - tSignal = tSignal->next(); - } - } - - tSignal = theFirstATTRINFO; - while (tSignal != NULL) { - if (tp->sendSignal(tSignal,aProcessorId) == -1){ - setErrorCode(4002); - return -1; - } - tSignalCount++; - tSignal = tSignal->next(); - } - theStatus = WaitResponse; - return tSignalCount; -}//NdbOperation::doSendScan() void NdbOperation::setLastFlag(NdbApiSignal* signal, Uint32 lastFlag) @@ -178,62 +101,6 @@ NdbOperation::doSend(int aNodeId, Uint32 lastFlag) }//NdbOperation::doSend() /*************************************************************************** -int prepareSendScan(Uint32 aTC_ConnectPtr, - Uint64 aTransactionId) - -Return Value: Return 0 : preparation of send was succesful. - Return -1: In all other case. -Parameters: aTC_ConnectPtr: the Connect pointer to TC. - aTransactionId: the Transaction identity of the transaction. -Remark: Puts the the final data into ATTRINFO signal(s) after this - we know the how many signal to send and their sizes -***************************************************************************/ -int NdbOperation::prepareSendScan(Uint32 aTC_ConnectPtr, - Uint64 aTransactionId){ - - if (theInterpretIndicator != 1 || - (theOperationType != OpenScanRequest && - theOperationType != OpenRangeScanRequest)) { - setErrorCodeAbort(4005); - return -1; - } - - if (theStatus == SetBound) { - saveBoundATTRINFO(); - theStatus = GetValue; - } - - theErrorLine = 0; - - // In preapareSendInterpreted we set the sizes (word 4-8) in the - // first ATTRINFO signal. - if (prepareSendInterpreted() == -1) - return -1; - - const Uint32 transId1 = (Uint32) (aTransactionId & 0xFFFFFFFF); - const Uint32 transId2 = (Uint32) (aTransactionId >> 32); - - if (theOperationType == OpenRangeScanRequest) { - NdbApiSignal* tSignal = theBoundATTRINFO; - do{ - tSignal->setData(aTC_ConnectPtr, 1); - tSignal->setData(transId1, 2); - tSignal->setData(transId2, 3); - tSignal = tSignal->next(); - } while (tSignal != NULL); - } - theCurrentATTRINFO->setLength(theAI_LenInCurrAI); - NdbApiSignal* tSignal = theFirstATTRINFO; - do{ - tSignal->setData(aTC_ConnectPtr, 1); - tSignal->setData(transId1, 2); - tSignal->setData(transId2, 3); - tSignal = tSignal->next(); - } while (tSignal != NULL); - return 0; -} - -/*************************************************************************** int prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) @@ -457,6 +324,7 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) theTCREQ->setLength(tcKeyReq->getAIInTcKeyReq(tReqInfo) + tAttrInfoIndex + TcKeyReq::StaticLength); + tAIDataPtr[0] = Tdata1; tAIDataPtr[1] = Tdata2; tAIDataPtr[2] = Tdata3; @@ -479,9 +347,8 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) tSignal = tnextSignal; } while (tSignal != NULL); }//if - NdbRecAttr* tRecAttrObject = theFirstRecAttr; theStatus = WaitResponse; - theCurrentRecAttr = tRecAttrObject; + theReceiver.prepareSend(); return 0; }//NdbOperation::prepareSend() @@ -648,71 +515,10 @@ NdbOperation::prepareSendInterpreted() theFirstATTRINFO->setData(tFinalReadSize, 7); theFirstATTRINFO->setData(tSubroutineSize, 8); }//if + theReceiver.prepareSend(); return 0; }//NdbOperation::prepareSendInterpreted() -/*************************************************************************** -int TCOPCONF(int anAttrInfoLen) - -Return Value: Return 0 : send was succesful. - Return -1: In all other case. -Parameters: anAttrInfoLen: The length of the attribute information from TC. -Remark: Handles the reception of the TC[KEY/INDX]CONF signal. -***************************************************************************/ -void -NdbOperation::TCOPCONF(Uint32 anAttrInfoLen) -{ - Uint32 tCurrRecLen = theCurrRecAI_Len; - if (theStatus == WaitResponse) { - theTotalRecAI_Len = anAttrInfoLen; - if (anAttrInfoLen == tCurrRecLen) { - Uint32 tAI_ElemLen = theAI_ElementLen; - NdbRecAttr* tCurrRecAttr = theCurrentRecAttr; - theStatus = Finished; - - if ((tAI_ElemLen == 0) && - (tCurrRecAttr == NULL)) { - NdbRecAttr* tRecAttr = theFirstRecAttr; - while (tRecAttr != NULL) { - if (tRecAttr->copyoutRequired()) // copy to application buffer - tRecAttr->copyout(); - tRecAttr = tRecAttr->next(); - } - theNdbCon->OpCompleteSuccess(); - return; - } else if (tAI_ElemLen != 0) { - setErrorCode(4213); - theNdbCon->OpCompleteFailure(); - return; - } else { - setErrorCode(4214); - theNdbCon->OpCompleteFailure(); - return; - }//if - } else if (anAttrInfoLen > tCurrRecLen) { - return; - } else { - theStatus = Finished; - - if (theAI_ElementLen != 0) { - setErrorCode(4213); - theNdbCon->OpCompleteFailure(); - return; - }//if - if (theCurrentRecAttr != NULL) { - setErrorCode(4214); - theNdbCon->OpCompleteFailure(); - return; - }//if - theNdbCon->OpCompleteFailure(); - return; - }//if - } else { - setErrorCode(4004); - }//if - return; -}//NdbOperation::TCKEYOPCONF() - int NdbOperation::checkState_TransId(NdbApiSignal* aSignal) { @@ -777,188 +583,13 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal) }//NdbOperation::receiveTCKEYREF() -/*************************************************************************** -int receiveREAD_CONF( NdbApiSignal* aSignal) - -Return Value: Return 0 : send was succesful. - Return -1: In all other case. -Parameters: aSignal: the signal object that contains the READCONF signal from TUP. -Remark: Handles the reception of the READCONF signal. -***************************************************************************/ -int -NdbOperation::receiveREAD_CONF(const Uint32* aDataPtr, Uint32 aDataLength) -{ - Uint64 tRecTransId, tCurrTransId; - Uint32 tCondFlag = (Uint32)(theStatus - WaitResponse); - Uint32 tTotLen = aDataPtr[3]; - - tRecTransId = (Uint64)aDataPtr[1] + ((Uint64)aDataPtr[2] << 32); - tCurrTransId = theNdbCon->getTransactionId(); - tCondFlag |= (Uint32)((tRecTransId - tCurrTransId) != (Uint64)0); - tCondFlag |= (Uint32)(aDataLength < 4); - - if (tCondFlag == 0) { - theTotalRecAI_Len = tTotLen; - int tRetValue = receiveREAD_AI((Uint32*)&aDataPtr[4], (aDataLength - 4)); - if (theStatus == Finished) { - return tRetValue; - } else { - theStatus = Finished; - return theNdbCon->OpCompleteFailure(); - }//if - }//if -#ifdef NDB_NO_DROPPED_SIGNAL - abort(); -#endif - return -1; -}//NdbOperation::receiveREAD_CONF() - -/*************************************************************************** -int receiveTRANSID_AI( NdbApiSignal* aSignal) - -Return Value: Return 0 : send was succesful. - Return -1: In all other case. -Parameters: aSignal: the signal object that contains the TRANSID_AI signal. -Remark: Handles the reception of the TRANSID_AI signal. -***************************************************************************/ -int -NdbOperation::receiveTRANSID_AI(const Uint32* aDataPtr, Uint32 aDataLength) -{ - Uint64 tRecTransId, tCurrTransId; - Uint32 tCondFlag = (Uint32)(theStatus - WaitResponse); - - tRecTransId = (Uint64)aDataPtr[1] + ((Uint64)aDataPtr[2] << 32); - tCurrTransId = theNdbCon->getTransactionId(); - tCondFlag |= (Uint32)((tRecTransId - tCurrTransId) != (Uint64)0); - tCondFlag |= (Uint32)(aDataLength < 3); - - if (tCondFlag == 0) { - return receiveREAD_AI((Uint32*)&aDataPtr[3], (aDataLength - 3)); - }//if -#ifdef NDB_NO_DROPPED_SIGNAL - abort(); -#endif - return -1; -}//NdbOperation::receiveTRANSID_AI() - -/*************************************************************************** -int receiveREAD_AI( NdbApiSignal* aSignal, int aLength, int aStartPos) - -Return Value: Return 0 : send was succesoccurredful. - Return -1: In all other case. -Parameters: aSignal: the signal object that contains the LEN_ATTRINFO11 signal. - aLength: - aStartPos: -Remark: Handles the reception of the LEN_ATTRINFO11 signal. -***************************************************************************/ -int -NdbOperation::receiveREAD_AI(Uint32* aDataPtr, Uint32 aLength) -{ - - register Uint32 tAI_ElementLen = theAI_ElementLen; - register Uint32* tCurrElemPtr = theCurrElemPtr; - if (theError.code == 0) { - // If inconsistency error occurred we will still continue - // receiving signals since we need to know whether commit - // has occurred. - - register Uint32 tData; - for (register Uint32 i = 0; i < aLength ; i++, aDataPtr++) - { - // Code to receive Attribute Information - tData = *aDataPtr; - if (tAI_ElementLen != 0) { - tAI_ElementLen--; - *tCurrElemPtr = tData; - tCurrElemPtr++; - continue; - } else { - // Waiting for a new attribute element - NdbRecAttr* tWorkingRecAttr; - - tWorkingRecAttr = theCurrentRecAttr; - AttributeHeader ah(tData); - const Uint32 tAttrId = ah.getAttributeId(); - const Uint32 tAttrSize = ah.getDataSize(); - if ((tWorkingRecAttr != NULL) && - (tWorkingRecAttr->attrId() == tAttrId)) { - ; - } else { - setErrorCode(4211); - break; - }//if - theCurrentRecAttr = tWorkingRecAttr->next(); - NdbColumnImpl * col = m_currentTable->getColumn(tAttrId); - if (ah.isNULL()) { - // Return a Null value from the NDB to the attribute. - if(col != 0 && col->m_nullable) { - tWorkingRecAttr->setNULL(); - tAI_ElementLen = 0; - } else { - setErrorCode(4212); - break; - }//if - } else { - // Return a value from the NDB to the attribute. - tWorkingRecAttr->setNotNULL(); - const Uint32 sizeInBytes = col->m_attrSize * col->m_arraySize; - const Uint32 sizeInWords = (sizeInBytes + 3) / 4; - tAI_ElementLen = tAttrSize; - tCurrElemPtr = (Uint32*)tWorkingRecAttr->aRef(); - if (sizeInWords == tAttrSize){ - continue; - } else { - setErrorCode(4201); - break; - }//if - }//if - }//if - }//for - }//if - Uint32 tCurrRecLen = theCurrRecAI_Len; - Uint32 tTotRecLen = theTotalRecAI_Len; - theAI_ElementLen = tAI_ElementLen; - theCurrElemPtr = tCurrElemPtr; - tCurrRecLen = tCurrRecLen + aLength; - theCurrRecAI_Len = tCurrRecLen; // Update Current Received AI Length - if (tTotRecLen == tCurrRecLen){ // Operation completed - NdbRecAttr* tCurrRecAttr = theCurrentRecAttr; - theStatus = Finished; - - NdbConnection* tNdbCon = theNdbCon; - if ((tAI_ElementLen == 0) && - (tCurrRecAttr == NULL)) { - NdbRecAttr* tRecAttr = theFirstRecAttr; - while (tRecAttr != NULL) { - if (tRecAttr->copyoutRequired()) // copy to application buffer - tRecAttr->copyout(); - tRecAttr = tRecAttr->next(); - } - return tNdbCon->OpCompleteSuccess(); - } else if (tAI_ElementLen != 0) { - setErrorCode(4213); - return tNdbCon->OpCompleteFailure(); - } else { - setErrorCode(4214); - return tNdbCon->OpCompleteFailure(); - }//if - } - else if ((tCurrRecLen > tTotRecLen) && - (tTotRecLen > 0)) { /* == 0 if TCKEYCONF not yet received */ - setErrorCode(4215); - theStatus = Finished; - - return theNdbCon->OpCompleteFailure(); - }//if - return -1; // Continue waiting for more signals of this operation -}//NdbOperation::receiveREAD_AI() void NdbOperation::handleFailedAI_ElemLen() { - NdbRecAttr* tRecAttr = theFirstRecAttr; + NdbRecAttr* tRecAttr = theReceiver.theFirstRecAttr; while (tRecAttr != NULL) { - tRecAttr->setUNDEFINED(); + tRecAttr->setNULL(); tRecAttr = tRecAttr->next(); }//while }//NdbOperation::handleFailedAI_ElemLen() diff --git a/ndb/src/ndbapi/NdbOperationInt.cpp b/ndb/src/ndbapi/NdbOperationInt.cpp index e61fc5b05d7..9abcfd6ef33 100644 --- a/ndb/src/ndbapi/NdbOperationInt.cpp +++ b/ndb/src/ndbapi/NdbOperationInt.cpp @@ -33,6 +33,7 @@ Adjust: 991029 UABRONM First version. #include "NdbRecAttr.hpp" #include "NdbUtil.hpp" #include "Interpreter.hpp" +#include <NdbScanOperation.hpp> #ifdef VM_TRACE #include <NdbEnv.h> @@ -43,6 +44,31 @@ Adjust: 991029 UABRONM First version. #define INT_DEBUG(x) #endif +void +NdbOperation::initInterpreter(){ + theFirstLabel = NULL; + theLastLabel = NULL; + theFirstBranch = NULL; + theLastBranch = NULL; + + theFirstCall = NULL; + theLastCall = NULL; + theFirstSubroutine = NULL; + theLastSubroutine = NULL; + + theNoOfLabels = 0; + theNoOfSubroutines = 0; + + theSubroutineSize = 0; + theInitialReadSize = 0; + theInterpretedSize = 0; + theFinalUpdateSize = 0; + theFinalReadSize = 0; + theInterpretIndicator = 1; + + theTotalCurrAI_Len = 5; +} + int NdbOperation::incCheck(const NdbColumnImpl* tNdbColumnImpl) { @@ -191,7 +217,7 @@ NdbOperation::initial_interpreterCheck() { if ((theInterpretIndicator == 1)) { if (theStatus == SetBound) { - saveBoundATTRINFO(); + ((NdbScanOperation*)this)->saveBoundATTRINFO(); theStatus = GetValue; } if (theStatus == ExecInterpretedValue) { diff --git a/ndb/src/ndbapi/NdbOperationScan.cpp b/ndb/src/ndbapi/NdbOperationScan.cpp index 0c377d3fd98..283eb591bdb 100644 --- a/ndb/src/ndbapi/NdbOperationScan.cpp +++ b/ndb/src/ndbapi/NdbOperationScan.cpp @@ -14,563 +14,3 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "NdbOperation.hpp" -#include "NdbScanReceiver.hpp" - -#include <signaldata/TcKeyReq.hpp> -#include <signaldata/ScanTab.hpp> -#include <signaldata/ScanFrag.hpp> -#include <signaldata/KeyInfo.hpp> - - -/****************************************************************************** - * int openScanRead(); - *****************************************************************************/ -int -NdbOperation::openScanRead(Uint32 aParallelism) -{ - aParallelism = checkParallelism(aParallelism); - - if ((theNdbCon->theCommitStatus != NdbConnection::Started) && - (theStatus != Init) && - (aParallelism == 0)) { - setErrorCode(4200); - return -1; - } - return openScan(aParallelism, false, false, false); -} - -/**************************************************************************** - * int openScanExclusive(); - ****************************************************************************/ -int -NdbOperation::openScanExclusive(Uint32 aParallelism) -{ - aParallelism = checkParallelism(aParallelism); - - if ((theNdbCon->theCommitStatus != NdbConnection::Started) && - (theStatus != Init) && - (aParallelism == 0)) { - setErrorCode(4200); - return -1; - } - return openScan(aParallelism, true, true, false); -} - -/****************************************************************************** - * int openScanReadHoldLock(); - *****************************************************************************/ -int -NdbOperation::openScanReadHoldLock(Uint32 aParallelism) -{ - aParallelism = checkParallelism(aParallelism); - - if ((theNdbCon->theCommitStatus != NdbConnection::Started) && - (theStatus != Init) && - (aParallelism == 0)) { - setErrorCode(4200); - return -1; - } - return openScan(aParallelism, false, true, false); -} - -/****************************************************************************** - * int openScanReadCommitted(); - *****************************************************************************/ -int -NdbOperation::openScanReadCommitted(Uint32 aParallelism) -{ - aParallelism = checkParallelism(aParallelism); - - if ((theNdbCon->theCommitStatus != NdbConnection::Started) && - (theStatus != Init) && - (aParallelism == 0)) { - setErrorCode(4200); - return -1; - } - return openScan(aParallelism, false, false, true); -} - -/**************************************************************************** - * int checkParallelism(); - * Remark If the parallelism is set wrong the number of scan-operations - * will not correspond to the number of TRANSID_AI signals returned - * from NDB and the result will be a crash, therefore - * we adjust it or return an error if the value is totally wrong. - ****************************************************************************/ -int -NdbOperation::checkParallelism(Uint32 aParallelism) -{ - if (aParallelism == 0) { - setErrorCodeAbort(4232); - return 0; - } - if (aParallelism > 16) { - if (aParallelism <= 240) { - - /** - * If tscanConcurrency > 16 it must be a multiple of 16 - */ - if (((aParallelism >> 4) << 4) < aParallelism) { - aParallelism = ((aParallelism >> 4) << 4) + 16; - }//if - - /*---------------------------------------------------------------*/ - /* We cannot have a parallelism > 16 per node */ - /*---------------------------------------------------------------*/ - if ((aParallelism / theNdb->theNoOfDBnodes) > 16) { - aParallelism = theNdb->theNoOfDBnodes * 16; - }//if - - } else { - setErrorCodeAbort(4232); - aParallelism = 0; - }//if - }//if - return aParallelism; -}//NdbOperation::checkParallelism() - -/********************************************************************** - * int openScan(); - *************************************************************************/ -int -NdbOperation::openScan(Uint32 aParallelism, - bool lockMode, bool lockHoldMode, bool readCommitted) -{ - aParallelism = checkParallelism(aParallelism); - if(aParallelism == 0){ - return 0; - } - NdbScanReceiver* tScanRec; - // It is only possible to call openScan if - // 1. this transcation don't already contain another scan operation - // 2. this transaction don't already contain other operations - // 3. theScanOp contains a NdbScanOperation - if (theNdbCon->theScanningOp != NULL){ - setErrorCode(4605); - return -1; - } - - if ((theNdbCon->theFirstOpInList != this) || - (theNdbCon->theLastOpInList != this)) { - setErrorCode(4603); - return -1; - } - theNdbCon->theScanningOp = this; - - initScan(); - theParallelism = aParallelism; - - // If the scan is on ordered index then it is a range scan - if (m_currentTable->m_indexType == NdbDictionary::Index::OrderedIndex || - m_currentTable->m_indexType == NdbDictionary::Index::UniqueOrderedIndex) { - assert(m_currentTable == m_accessTable); - m_currentTable = theNdb->theDictionary->getTable(m_currentTable->m_primaryTable.c_str()); - assert(m_currentTable != NULL); - // Modify operation state - theStatus = SetBound; - theOperationType = OpenRangeScanRequest; - } - - theScanReceiversArray = new NdbScanReceiver* [aParallelism]; - if (theScanReceiversArray == NULL){ - setErrorCodeAbort(4000); - return -1; - } - - for (Uint32 i = 0; i < aParallelism; i ++) { - tScanRec = theNdb->getNdbScanRec(); - if (tScanRec == NULL) { - setErrorCodeAbort(4000); - return -1; - }//if - tScanRec->init(this, lockMode); - theScanReceiversArray[i] = tScanRec; - } - - theSCAN_TABREQ = theNdb->getSignal(); - if (theSCAN_TABREQ == NULL) { - setErrorCodeAbort(4000); - return -1; - }//if - ScanTabReq * const scanTabReq = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend()); - scanTabReq->apiConnectPtr = theNdbCon->theTCConPtr; - scanTabReq->tableId = m_accessTable->m_tableId; - scanTabReq->tableSchemaVersion = m_accessTable->m_version; - scanTabReq->storedProcId = 0xFFFF; - scanTabReq->buddyConPtr = theNdbCon->theBuddyConPtr; - - Uint32 reqInfo = 0; - ScanTabReq::setParallelism(reqInfo, aParallelism); - ScanTabReq::setLockMode(reqInfo, lockMode); - ScanTabReq::setHoldLockFlag(reqInfo, lockHoldMode); - ScanTabReq::setReadCommittedFlag(reqInfo, readCommitted); - if (theOperationType == OpenRangeScanRequest) - ScanTabReq::setRangeScanFlag(reqInfo, true); - scanTabReq->requestInfo = reqInfo; - - Uint64 transId = theNdbCon->getTransactionId(); - scanTabReq->transId1 = (Uint32) transId; - scanTabReq->transId2 = (Uint32) (transId >> 32); - - for (Uint32 i = 0; i < 16 && i < aParallelism ; i++) { - scanTabReq->apiOperationPtr[i] = theScanReceiversArray[i]->ptr2int(); - }//for - - // Create one additional SCAN_TABINFO for each - // 16 of parallelism - NdbApiSignal* tSignal; - Uint32 tParallelism = aParallelism; - while (tParallelism > 16) { - tSignal = theNdb->getSignal(); - if (tSignal == NULL) { - setErrorCodeAbort(4000); - return -1; - }//if - if (tSignal->setSignal(GSN_SCAN_TABINFO) == -1) { - setErrorCode(4001); - return -1; - } - tSignal->next(theFirstSCAN_TABINFO_Send); - theFirstSCAN_TABINFO_Send = tSignal; - tParallelism -= 16; - }//while - - // Format all SCAN_TABINFO signals - tParallelism = 16; - tSignal = theFirstSCAN_TABINFO_Send; - while (tSignal != NULL) { - tSignal->setData(theNdbCon->theTCConPtr, 1); - for (int i = 0; i < 16 ; i++) { - tSignal->setData(theScanReceiversArray[i + tParallelism]->ptr2int(), i + 2); - }//for - tSignal = tSignal->next(); - tParallelism += 16; - }//while - - getFirstATTRINFOScan(); - return 0; -}//NdbScanOperation::openScan() - -/***************************************************************************** - * int getFirstATTRINFOScan( U_int32 aData ) - * - * Return Value: Return 0: Successful - * Return -1: All other cases - * Parameters: None: Only allocate the first signal. - * Remark: When a scan is defined we need to use this method instead - * of insertATTRINFO for the first signal. - * This is because we need not to mess up the code in - * insertATTRINFO with if statements since we are not - * interested in the TCKEYREQ signal. - *****************************************************************************/ -int -NdbOperation::getFirstATTRINFOScan() -{ - NdbApiSignal* tSignal; - - tSignal = theNdb->getSignal(); - if (tSignal == NULL){ - setErrorCodeAbort(4000); - return -1; - } - tSignal->setSignal(m_attrInfoGSN); - theAI_LenInCurrAI = 8; - theATTRINFOptr = &tSignal->getDataPtrSend()[8]; - theFirstATTRINFO = tSignal; - theCurrentATTRINFO = tSignal; - theCurrentATTRINFO->next(NULL); - return 0; -} - -/* - * After setBound() are done, move the accumulated ATTRINFO signals to - * a separate list. Then continue with normal scan. - */ -int -NdbOperation::saveBoundATTRINFO() -{ - theCurrentATTRINFO->setLength(theAI_LenInCurrAI); - theBoundATTRINFO = theFirstATTRINFO; - theTotalBoundAI_Len = theTotalCurrAI_Len; - theTotalCurrAI_Len = 5; - theBoundATTRINFO->setData(theTotalBoundAI_Len, 4); - theBoundATTRINFO->setData(0, 5); - theBoundATTRINFO->setData(0, 6); - theBoundATTRINFO->setData(0, 7); - theBoundATTRINFO->setData(0, 8); - theStatus = GetValue; - return getFirstATTRINFOScan(); -} - -/***************************************************************************** - * void releaseScan() - * - * Return Value No return value. - * Parameters: No parameters. - * Remark: Release objects after scanning. - *****************************************************************************/ -void -NdbOperation::releaseScan() -{ - NdbScanReceiver* tScanRec; - TransporterFacade::instance()->lock_mutex(); - for (Uint32 i = 0; i < theParallelism && theScanReceiversArray != NULL; i++) { - tScanRec = theScanReceiversArray[i]; - if (tScanRec != NULL) { - tScanRec->release(); - tScanRec->next(NULL); - } - } - TransporterFacade::instance()->unlock_mutex(); - releaseSignals(); - - if (theScanReceiversArray != NULL) { - for (Uint32 i = 0; i < theParallelism; i++) { - NdbScanReceiver* tScanRec; - tScanRec = theScanReceiversArray[i]; - if (tScanRec != NULL) { - theNdb->releaseNdbScanRec(tScanRec); - theScanReceiversArray[i] = NULL; - } - } - - delete [] theScanReceiversArray; - }//if - theScanReceiversArray = NULL; - - if (theSCAN_TABREQ != NULL){ - theNdb->releaseSignal(theSCAN_TABREQ); - theSCAN_TABREQ = NULL; - } -} - -void NdbOperation::releaseSignals(){ - theNdb->releaseSignalsInList(&theFirstSCAN_TABINFO_Send); - theFirstSCAN_TABINFO_Send = NULL; - theLastSCAN_TABINFO_Send = NULL; - // theNdb->releaseSignalsInList(&theFirstSCAN_TABINFO_Recv); - - while(theFirstSCAN_TABINFO_Recv != NULL){ - NdbApiSignal* tmp = theFirstSCAN_TABINFO_Recv; - theFirstSCAN_TABINFO_Recv = tmp->next(); - delete tmp; - } - theFirstSCAN_TABINFO_Recv = NULL; - theLastSCAN_TABINFO_Recv = NULL; - if (theSCAN_TABCONF_Recv != NULL){ - // theNdb->releaseSignal(theSCAN_TABCONF_Recv); - delete theSCAN_TABCONF_Recv; - theSCAN_TABCONF_Recv = NULL; - } -} - - -void NdbOperation::prepareNextScanResult(){ - NdbScanReceiver* tScanRec; - for (Uint32 i = 0; i < theParallelism; i++) { - tScanRec = theScanReceiversArray[i]; - assert(tScanRec != NULL); - tScanRec->prepareNextScanResult(); - tScanRec->next(NULL); - } - releaseSignals(); -} - -/****************************************************************************** - * void initScan(); - * - * Return Value: Return 0 : init was successful. - * Return -1: In all other case. - * Remark: Initiates operation record after allocation. - *****************************************************************************/ -void -NdbOperation::initScan() -{ - theTotalRecAI_Len = 0; - theCurrRecAI_Len = 0; - theStatus = GetValue; - theOperationType = OpenScanRequest; - theCurrentRecAttr = theFirstRecAttr; - theScanInfo = 0; - theMagicNumber = 0xABCDEF01; - theTotalCurrAI_Len = 5; - - theFirstLabel = NULL; - theLastLabel = NULL; - theFirstBranch = NULL; - theLastBranch = NULL; - - theFirstCall = NULL; - theLastCall = NULL; - theFirstSubroutine = NULL; - theLastSubroutine = NULL; - - theNoOfLabels = 0; - theNoOfSubroutines = 0; - - theSubroutineSize = 0; - theInitialReadSize = 0; - theInterpretedSize = 0; - theFinalUpdateSize = 0; - theFinalReadSize = 0; - theInterpretIndicator = 1; - - - theFirstSCAN_TABINFO_Send = NULL; - theLastSCAN_TABINFO_Send = NULL; - theFirstSCAN_TABINFO_Recv = NULL; - theLastSCAN_TABINFO_Recv = NULL; - theSCAN_TABCONF_Recv = NULL; - - theScanReceiversArray = NULL; - - theTotalBoundAI_Len = 0; - theBoundATTRINFO = NULL; - return; -} - -NdbOperation* NdbOperation::takeOverForDelete(NdbConnection* updateTrans){ - return takeOverScanOp(DeleteRequest, updateTrans); -} - -NdbOperation* NdbOperation::takeOverForUpdate(NdbConnection* updateTrans){ - return takeOverScanOp(UpdateRequest, updateTrans); -} -/****************************************************************************** - * NdbOperation* takeOverScanOp(NdbConnection* updateTrans); - * - * Parameters: The update transactions NdbConnection pointer. - * Return Value: A reference to the transferred operation object - * or NULL if no success. - * Remark: Take over the scanning transactions NdbOperation - * object for a tuple to an update transaction, - * which is the last operation read in nextScanResult() - * (theNdbCon->thePreviousScanRec) - * - * FUTURE IMPLEMENTATION: (This note was moved from header file.) - * In the future, it will even be possible to transfer - * to a NdbConnection on another Ndb-object. - * In this case the receiving NdbConnection-object must call - * a method receiveOpFromScan to actually receive the information. - * This means that the updating transactions can be placed - * in separate threads and thus increasing the parallelism during - * the scan process. - *****************************************************************************/ -NdbOperation* -NdbOperation::takeOverScanOp(OperationType opType, NdbConnection* updateTrans) -{ - if (opType != UpdateRequest && opType != DeleteRequest) { - setErrorCode(4604); - return NULL; - } - - const NdbScanReceiver* tScanRec = theNdbCon->thePreviousScanRec; - if (tScanRec == NULL){ - // No operation read by nextScanResult - setErrorCode(4609); - return NULL; - } - - if (tScanRec->theFirstKEYINFO20_Recv == NULL){ - // No KEYINFO20 received - setErrorCode(4608); - return NULL; - } - - NdbOperation * newOp = updateTrans->getNdbOperation(m_currentTable); - if (newOp == NULL){ - return NULL; - } - - /** - * Copy and caclulate attributes from the scanned operation to the - * new operation - */ - const KeyInfo20 * const firstKeyInfo20 = - CAST_CONSTPTR(KeyInfo20, tScanRec->theFirstKEYINFO20_Recv->getDataPtr()); - const Uint32 totalKeyLen = firstKeyInfo20->keyLen; - newOp->theTupKeyLen = totalKeyLen; - - newOp->theOperationType = opType; - if (opType == DeleteRequest) { - newOp->theStatus = GetValue; - } else { - newOp->theStatus = SetValue; - } - const Uint32 tScanInfo = firstKeyInfo20->scanInfo_Node & 0xFFFF; - const Uint32 tTakeOverNode = firstKeyInfo20->scanInfo_Node >> 16; - { - UintR scanInfo = 0; - TcKeyReq::setTakeOverScanFlag(scanInfo, 1); - TcKeyReq::setTakeOverScanNode(scanInfo, tTakeOverNode); - TcKeyReq::setTakeOverScanInfo(scanInfo, tScanInfo); - newOp->theScanInfo = scanInfo; - } - - /** - * Copy received KEYINFO20 signals into TCKEYREQ and KEYINFO signals - * put them in list of the new op - */ - TcKeyReq * const tcKeyReq = - CAST_PTR(TcKeyReq, newOp->theTCREQ->getDataPtrSend()); - - // Copy the first 8 words of key info from KEYINF20 into TCKEYREQ - for (Uint32 i = 0; i < TcKeyReq::MaxKeyInfo; i++) { - tcKeyReq->keyInfo[i] = firstKeyInfo20->keyData[i]; - } - if (totalKeyLen > TcKeyReq::MaxKeyInfo) { - - Uint32 keyWordsCopied = TcKeyReq::MaxKeyInfo; - - // Create KEYINFO signals in newOp - for (Uint32 i = keyWordsCopied; i < totalKeyLen; i += KeyInfo::DataLength){ - NdbApiSignal* tSignal = theNdb->getSignal(); - if (tSignal == NULL){ - setErrorCodeAbort(4000); - return NULL; - } - if (tSignal->setSignal(GSN_KEYINFO) == -1){ - setErrorCodeAbort(4001); - return NULL; - } - tSignal->next(newOp->theFirstKEYINFO); - newOp->theFirstKEYINFO = tSignal; - } - - // Init pointers to KEYINFO20 signal - NdbApiSignal* currKeyInfo20 = tScanRec->theFirstKEYINFO20_Recv; - const KeyInfo20 * keyInfo20 = - CAST_CONSTPTR(KeyInfo20, currKeyInfo20->getDataPtr()); - Uint32 posInKeyInfo20 = keyWordsCopied; - - // Init pointers to KEYINFO signal - NdbApiSignal* currKeyInfo = newOp->theFirstKEYINFO; - KeyInfo * keyInfo = CAST_PTR(KeyInfo, currKeyInfo->getDataPtrSend()); - Uint32 posInKeyInfo = 0; - - // Copy from KEYINFO20 to KEYINFO - while(keyWordsCopied < totalKeyLen){ - keyInfo->keyData[posInKeyInfo++] = keyInfo20->keyData[posInKeyInfo20++]; - keyWordsCopied++; - if(keyWordsCopied >= totalKeyLen) - break; - if (posInKeyInfo20 >= - (currKeyInfo20->getLength()-KeyInfo20::HeaderLength)){ - currKeyInfo20 = currKeyInfo20->next(); - keyInfo20 = CAST_CONSTPTR(KeyInfo20, currKeyInfo20->getDataPtr()); - posInKeyInfo20 = 0; - } - if (posInKeyInfo >= KeyInfo::DataLength){ - currKeyInfo = currKeyInfo->next(); - keyInfo = CAST_PTR(KeyInfo, currKeyInfo->getDataPtrSend()); - posInKeyInfo = 0; - } - } - } - - return newOp; -} - - - diff --git a/ndb/src/ndbapi/NdbRecAttr.cpp b/ndb/src/ndbapi/NdbRecAttr.cpp index 0f7baeac4f5..18ce59745d0 100644 --- a/ndb/src/ndbapi/NdbRecAttr.cpp +++ b/ndb/src/ndbapi/NdbRecAttr.cpp @@ -57,6 +57,8 @@ NdbRecAttr::setup(const NdbColumnImpl* anAttrInfo, char* aValue) theAttrSize = tAttrSize; theArraySize = tArraySize; theValue = aValue; + theNULLind = 0; + m_nullable = anAttrInfo->m_nullable; // check alignment to signal data // a future version could check alignment per data type as well @@ -124,3 +126,19 @@ NdbRecAttr::clone() const { memcpy(ret->theRef, theRef, n); return ret; } + +bool +NdbRecAttr::receive_data(const Uint32 * data, Uint32 sz){ + const Uint32 n = (theAttrSize * theArraySize + 3) >> 2; + if(n == sz){ + if(!copyoutRequired()) + memcpy(theRef, data, 4 * sz); + else + memcpy(theValue, data, theAttrSize * theArraySize); + return true; + } else if(sz == 0){ + setNULL(); + return true; + } + return false; +} diff --git a/ndb/src/ndbapi/NdbReceiver.cpp b/ndb/src/ndbapi/NdbReceiver.cpp index 4c461698a4a..7a538de3d7c 100644 --- a/ndb/src/ndbapi/NdbReceiver.cpp +++ b/ndb/src/ndbapi/NdbReceiver.cpp @@ -16,6 +16,10 @@ #include "NdbImpl.hpp" #include <NdbReceiver.hpp> +#include "NdbDictionaryImpl.hpp" +#include <NdbRecAttr.hpp> +#include <AttributeHeader.hpp> +#include <NdbConnection.hpp> NdbReceiver::NdbReceiver(Ndb *aNdb) : theMagicNumber(0), @@ -24,10 +28,11 @@ NdbReceiver::NdbReceiver(Ndb *aNdb) : m_type(NDB_UNINITIALIZED), m_owner(0) { + theCurrentRecAttr = theFirstRecAttr = 0; } void -NdbReceiver::init(ReceiverType type, void* owner) +NdbReceiver::init(ReceiverType type, void* owner, bool keyInfo) { theMagicNumber = 0x11223344; m_type = type; @@ -36,6 +41,24 @@ NdbReceiver::init(ReceiverType type, void* owner) if (m_ndb) m_id = m_ndb->theNdbObjectIdMap->map(this); } + + theFirstRecAttr = NULL; + theCurrentRecAttr = NULL; + m_key_info = (keyInfo ? 1 : 0); + m_defined_rows = 0; +} + +void +NdbReceiver::release(){ + NdbRecAttr* tRecAttr = theFirstRecAttr; + while (tRecAttr != NULL) + { + NdbRecAttr* tSaveRecAttr = tRecAttr; + tRecAttr = tRecAttr->next(); + m_ndb->releaseRecAttr(tSaveRecAttr); + } + theFirstRecAttr = NULL; + theCurrentRecAttr = NULL; } NdbReceiver::~NdbReceiver() @@ -44,3 +67,150 @@ NdbReceiver::~NdbReceiver() m_ndb->theNdbObjectIdMap->unmap(m_id, this); } } + +NdbRecAttr * +NdbReceiver::getValue(const NdbColumnImpl* tAttrInfo, char * user_dst_ptr){ + NdbRecAttr* tRecAttr = m_ndb->getRecAttr(); + if(tRecAttr && !tRecAttr->setup(tAttrInfo, user_dst_ptr)){ + if (theFirstRecAttr == NULL) + theFirstRecAttr = tRecAttr; + else + theCurrentRecAttr->next(tRecAttr); + theCurrentRecAttr = tRecAttr; + tRecAttr->next(NULL); + return tRecAttr; + } + if(tRecAttr){ + m_ndb->releaseRecAttr(tRecAttr); + } + return 0; +} + +#define KEY_ATTR_ID (~0) + +void +NdbReceiver::do_get_value(NdbReceiver * org, Uint32 rows, Uint32 key_size){ + m_defined_rows = rows; + m_rows = new NdbRecAttr*[rows + 1]; m_rows[rows] = 0; + + NdbColumnImpl key; + if(key_size){ + key.m_attrId = KEY_ATTR_ID; + key.m_arraySize = key_size+1; + key.m_attrSize = 4; + key.m_nullable = true; // So that receive works w.r.t KEYINFO20 + } + + for(Uint32 i = 0; i<rows; i++){ + NdbRecAttr * prev = theCurrentRecAttr; + + // Put key-recAttr fir on each row + if(key_size && !getValue(&key, (char*)0)){ + abort(); + return ; // -1 + } + + NdbRecAttr* tRecAttr = org->theFirstRecAttr; + while(tRecAttr != 0){ + if(getValue(&NdbColumnImpl::getImpl(*tRecAttr->m_column), (char*)0)) + tRecAttr = tRecAttr->next(); + else + break; + } + + if(tRecAttr){ + abort(); + return ;// -1; + } + + // Store first recAttr for each row in m_rows[i] + if(prev){ + m_rows[i] = prev->next(); + } else { + m_rows[i] = theFirstRecAttr; + } + } + + prepareSend(); + return ; //0; +} + +void +NdbReceiver::copyout(NdbReceiver & dstRec){ + NdbRecAttr* src = m_rows[m_current_row++]; + NdbRecAttr* dst = dstRec.theFirstRecAttr; + Uint32 tmp = m_key_info; + if(tmp > 0){ + src = src->next(); + } + + while(dst){ + Uint32 len = ((src->theAttrSize * src->theArraySize)+3)/4; + dst->receive_data((Uint32*)src->aRef(), len); + src = src->next(); + dst = dst->next(); + } +} + +int +NdbReceiver::execTRANSID_AI(const Uint32* aDataPtr, Uint32 aLength) +{ + bool ok = true; + NdbRecAttr* currRecAttr = theCurrentRecAttr; + NdbRecAttr* prevRecAttr = currRecAttr; + + for (Uint32 used = 0; used < aLength ; used++){ + AttributeHeader ah(* aDataPtr++); + const Uint32 tAttrId = ah.getAttributeId(); + const Uint32 tAttrSize = ah.getDataSize(); + + /** + * Set all results to NULL if not found... + */ + while(currRecAttr && currRecAttr->attrId() != tAttrId){ + ok &= currRecAttr->setNULL(); + prevRecAttr = currRecAttr; + currRecAttr = currRecAttr->next(); + } + + if(ok && currRecAttr && currRecAttr->receive_data(aDataPtr, tAttrSize)){ + used += tAttrSize; + aDataPtr += tAttrSize; + prevRecAttr = currRecAttr; + currRecAttr = currRecAttr->next(); + } else { + ndbout_c("%p: ok: %d tAttrId: %d currRecAttr: %p", + this,ok, tAttrId, currRecAttr); + abort(); + return -1; + } + } + + theCurrentRecAttr = currRecAttr; + + /** + * Update m_received_result_length + */ + Uint32 tmp = m_received_result_length + aLength; + m_received_result_length = tmp; + + return (tmp == m_expected_result_length ? 1 : 0); +} + +int +NdbReceiver::execKEYINFO20(Uint32 info, const Uint32* aDataPtr, Uint32 aLength) +{ + NdbRecAttr* currRecAttr = m_rows[m_current_row++]; + assert(currRecAttr->attrId() == KEY_ATTR_ID); + currRecAttr->receive_data(aDataPtr, aLength + 1); + + /** + * Save scanInfo in the end of keyinfo + */ + ((Uint32*)currRecAttr->aRef())[aLength] = info; + + Uint32 tmp = m_received_result_length + aLength; + m_received_result_length = tmp; + + return (tmp == m_expected_result_length ? 1 : 0); +} diff --git a/ndb/src/ndbapi/NdbResultSet.cpp b/ndb/src/ndbapi/NdbResultSet.cpp index 65ed43f60d8..d15c58ba972 100644 --- a/ndb/src/ndbapi/NdbResultSet.cpp +++ b/ndb/src/ndbapi/NdbResultSet.cpp @@ -30,7 +30,7 @@ #include <NdbConnection.hpp> #include <NdbResultSet.hpp> -NdbResultSet::NdbResultSet(NdbCursorOperation *owner) +NdbResultSet::NdbResultSet(NdbScanOperation *owner) : m_operation(owner) { } @@ -55,49 +55,22 @@ void NdbResultSet::close() NdbOperation* NdbResultSet::updateTuple(){ - if(m_operation->cursorType() != NdbCursorOperation::ScanCursor){ - m_operation->setErrorCode(4003); - return 0; - } - - NdbScanOperation * op = (NdbScanOperation*)(m_operation); - return op->takeOverScanOp(NdbOperation::UpdateRequest, - op->m_transConnection); + return updateTuple(m_operation->m_transConnection); } NdbOperation* NdbResultSet::updateTuple(NdbConnection* takeOverTrans){ - if(m_operation->cursorType() != NdbCursorOperation::ScanCursor){ - m_operation->setErrorCode(4003); - return 0; - } - return m_operation->takeOverScanOp(NdbOperation::UpdateRequest, takeOverTrans); } int NdbResultSet::deleteTuple(){ - if(m_operation->cursorType() != NdbCursorOperation::ScanCursor){ - m_operation->setErrorCode(4003); - return 0; - } - - NdbScanOperation * op = (NdbScanOperation*)(m_operation); - void * res = op->takeOverScanOp(NdbOperation::DeleteRequest, - op->m_transConnection); - if(res == 0) - return -1; - return 0; + return deleteTuple(m_operation->m_transConnection); } int NdbResultSet::deleteTuple(NdbConnection * takeOverTrans){ - if(m_operation->cursorType() != NdbCursorOperation::ScanCursor){ - m_operation->setErrorCode(4003); - return 0; - } - void * res = m_operation->takeOverScanOp(NdbOperation::DeleteRequest, takeOverTrans); if(res == 0) diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 8064eef838e..8a22d6a3c0f 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -26,36 +26,57 @@ * Adjust: 2002-04-01 UABMASD First version. ****************************************************************************/ -#include <ndb_global.h> #include <Ndb.hpp> #include <NdbScanOperation.hpp> +#include <NdbIndexScanOperation.hpp> #include <NdbConnection.hpp> #include <NdbResultSet.hpp> #include "NdbApiSignal.hpp" #include <NdbOut.hpp> #include "NdbDictionaryImpl.hpp" +#include <NdbRecAttr.hpp> +#include <NdbReceiver.hpp> + +#include <stdlib.h> +#include <NdbSqlUtil.hpp> + +#include <signaldata/ScanTab.hpp> +#include <signaldata/KeyInfo.hpp> +#include <signaldata/TcKeyReq.hpp> + NdbScanOperation::NdbScanOperation(Ndb* aNdb) : - NdbCursorOperation(aNdb), - m_transConnection(NULL), - m_autoExecute(false), - m_updateOp(false), - m_deleteOp(false), - m_setValueList(new SetValueRecList()) + NdbOperation(aNdb), + m_resultSet(0), + m_transConnection(NULL) { + theParallelism = 0; + m_allocated_receivers = 0; + m_prepared_receivers = 0; + m_api_receivers = 0; + m_conf_receivers = 0; + m_sent_receivers = 0; + m_receivers = 0; } NdbScanOperation::~NdbScanOperation() { - if (m_setValueList) delete m_setValueList; + fix_receivers(0, false); + if (m_resultSet) + delete m_resultSet; } -NdbCursorOperation::CursorType -NdbScanOperation::cursorType() +NdbResultSet* +NdbScanOperation::getResultSet() { - return NdbCursorOperation::ScanCursor; + if (!m_resultSet) + m_resultSet = new NdbResultSet(this); + + return m_resultSet; } + + void NdbScanOperation::setErrorCode(int aErrorCode){ NdbConnection* tmp = theNdbCon; @@ -90,267 +111,516 @@ NdbScanOperation::init(NdbTableImpl* tab, NdbConnection* myConnection) setErrorCodeAbort(theNdb->getNdbError().code); return -1; } - aScanConnection->theFirstOpInList = this; - aScanConnection->theLastOpInList = this; - NdbCursorOperation::cursInit(); - // NOTE! The hupped trans becomes the owner of the operation - return NdbOperation::init(tab, aScanConnection); -} - -NdbResultSet* NdbScanOperation::readTuples(Uint32 parallell, - NdbCursorOperation::LockMode lm) -{ - int res = 0; - switch(lm){ - case NdbCursorOperation::LM_Read: - parallell = (parallell == 0 ? 240 : parallell); - res = openScan(parallell, false, true, false); - break; - case NdbCursorOperation::LM_Exclusive: - parallell = (parallell == 0 ? 1 : parallell); - res = openScan(parallell, true, true, false); - break; - case NdbCursorOperation::LM_Dirty: - parallell = (parallell == 0 ? 240 : parallell); - res = openScan(parallell, false, false, true); - break; - default: - res = -1; - setErrorCode(4003); - } - if(res == -1){ - return NULL; - } - theNdbCon->theFirstOpInList = 0; - theNdbCon->theLastOpInList = 0; - return getResultSet(); -} - -int NdbScanOperation::updateTuples(Uint32 parallelism) -{ - if (openScanExclusive(parallelism) == -1) { + // NOTE! The hupped trans becomes the owner of the operation + if(NdbOperation::init(tab, aScanConnection) != 0){ return -1; } - theNdbCon->theFirstOpInList = 0; - theNdbCon->theLastOpInList = 0; - - m_updateOp = true; + + initInterpreter(); + + theStatus = GetValue; + theOperationType = OpenScanRequest; + + theTotalBoundAI_Len = 0; + theBoundATTRINFO = NULL; return 0; } -int NdbScanOperation::deleteTuples(Uint32 parallelism) +NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, + Uint32 batch, + Uint32 parallell) { - if (openScanExclusive(parallelism) == -1) { - return -1; - } - theNdbCon->theFirstOpInList = 0; - theNdbCon->theLastOpInList = 0; + m_ordered = 0; - m_deleteOp = true; + Uint32 fragCount = m_currentTable->m_fragmentCount; - return 0; -} + if(batch + parallell == 0){ // Max speed + batch = 16; + parallell = fragCount; + } -int NdbScanOperation::setValue(const char* anAttrName, const char* aValue, Uint32 len) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrName) == NULL) - return -1; + if(batch == 0 && parallell > 0){ // Backward + batch = (parallell >= 16 ? 16 : parallell & 15); + parallell = (parallell + 15) / 16; + + if(parallell == 0) + parallell = 1; + } - m_setValueList->add(anAttrName, aValue, len); - return 0; -} - -int NdbScanOperation::setValue(const char* anAttrName, Int32 aValue) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrName) == NULL) - return -1; - - m_setValueList->add(anAttrName, aValue); - return 0; -} - -int NdbScanOperation::setValue(const char* anAttrName, Uint32 aValue) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrName) == NULL) - return -1; + if(parallell > fragCount) + parallell = fragCount; + else if(parallell == 0) + parallell = fragCount; + + assert(parallell > 0); + + // It is only possible to call openScan if + // 1. this transcation don't already contain another scan operation + // 2. this transaction don't already contain other operations + // 3. theScanOp contains a NdbScanOperation + if (theNdbCon->theScanningOp != NULL){ + setErrorCode(4605); + return 0; + } - m_setValueList->add(anAttrName, aValue); - return 0; -} + theNdbCon->theScanningOp = this; -int NdbScanOperation::setValue(const char* anAttrName, Uint64 aValue) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrName) == NULL) - return -1; + bool lockExcl, lockHoldMode, readCommitted; + switch(lm){ + case NdbScanOperation::LM_Read: + lockExcl = false; + lockHoldMode = true; + readCommitted = false; + break; + case NdbScanOperation::LM_Exclusive: + lockExcl = true; + lockHoldMode = true; + readCommitted = false; + break; + case NdbScanOperation::LM_Dirty: + lockExcl = false; + lockHoldMode = false; + readCommitted = true; + break; + default: + setErrorCode(4003); + return 0; + } - m_setValueList->add(anAttrName, aValue); - return 0; -} + m_keyInfo = lockExcl; + + bool range = false; + if (m_currentTable->m_indexType == NdbDictionary::Index::OrderedIndex || + m_currentTable->m_indexType == NdbDictionary::Index::UniqueOrderedIndex){ + assert(m_currentTable == m_accessTable); + m_currentTable = theNdb->theDictionary-> + getTable(m_currentTable->m_primaryTable.c_str()); + assert(m_currentTable != NULL); + // Modify operation state + theStatus = SetBound; + theOperationType = OpenRangeScanRequest; + range = true; + } + + theParallelism = parallell; + theBatchSize = batch; -int NdbScanOperation::setValue(const char* anAttrName, Int64 aValue) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrName) == NULL) - return -1; + if(fix_receivers(parallell, lockExcl) == -1){ + setErrorCodeAbort(4000); + return 0; + } + + theSCAN_TABREQ = theNdb->getSignal(); + if (theSCAN_TABREQ == NULL) { + setErrorCodeAbort(4000); + return 0; + }//if + + ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend()); + req->apiConnectPtr = theNdbCon->theTCConPtr; + req->tableId = m_accessTable->m_tableId; + req->tableSchemaVersion = m_accessTable->m_version; + req->storedProcId = 0xFFFF; + req->buddyConPtr = theNdbCon->theBuddyConPtr; + + Uint32 reqInfo = 0; + ScanTabReq::setParallelism(reqInfo, parallell); + ScanTabReq::setScanBatch(reqInfo, batch); + ScanTabReq::setLockMode(reqInfo, lockExcl); + ScanTabReq::setHoldLockFlag(reqInfo, lockHoldMode); + ScanTabReq::setReadCommittedFlag(reqInfo, readCommitted); + ScanTabReq::setRangeScanFlag(reqInfo, range); + req->requestInfo = reqInfo; - m_setValueList->add(anAttrName, aValue); - return 0; -} + Uint64 transId = theNdbCon->getTransactionId(); + req->transId1 = (Uint32) transId; + req->transId2 = (Uint32) (transId >> 32); -int NdbScanOperation::setValue(const char* anAttrName, float aValue) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrName) == NULL) - return -1; + getFirstATTRINFOScan(); - m_setValueList->add(anAttrName, aValue); - return 0; + return getResultSet(); } -int NdbScanOperation::setValue(const char* anAttrName, double aValue) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrName) == NULL) - return -1; +int +NdbScanOperation::fix_receivers(Uint32 parallell, bool keyInfo){ + if(parallell == 0 || parallell > m_allocated_receivers){ + if(m_prepared_receivers) delete[] m_prepared_receivers; + if(m_receivers) delete[] m_receivers; + if(m_api_receivers) delete[] m_api_receivers; + if(m_conf_receivers) delete[] m_conf_receivers; + if(m_sent_receivers) delete[] m_sent_receivers; + + m_allocated_receivers = parallell; + if(parallell == 0){ + return 0; + } + + m_prepared_receivers = new Uint32[parallell]; + m_receivers = new NdbReceiver*[parallell]; + m_api_receivers = new NdbReceiver*[parallell]; + m_conf_receivers = new NdbReceiver*[parallell]; + m_sent_receivers = new NdbReceiver*[parallell]; + + NdbReceiver* tScanRec; + for (Uint32 i = 0; i < parallell; i ++) { + tScanRec = theNdb->getNdbScanRec(); + if (tScanRec == NULL) { + setErrorCodeAbort(4000); + return -1; + }//if + m_receivers[i] = tScanRec; + tScanRec->init(NdbReceiver::NDB_SCANRECEIVER, this, keyInfo); + } + } - m_setValueList->add(anAttrName, aValue); + for(Uint32 i = 0; i<parallell; i++){ + m_receivers[i]->m_list_index = i; + m_prepared_receivers[i] = m_receivers[i]->getId(); + m_sent_receivers[i] = m_receivers[i]; + m_conf_receivers[i] = 0; + m_api_receivers[i] = 0; + } + + m_api_receivers_count = 0; + m_current_api_receiver = 0; + m_sent_receivers_count = parallell; + m_conf_receivers_count = 0; return 0; } - -int NdbScanOperation::setValue(Uint32 anAttrId, const char* aValue, Uint32 len) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrId) == NULL) - return -1; - - m_setValueList->add(anAttrId, aValue, len); - return 0; +/** + * Move receiver from send array to conf:ed array + */ +void +NdbScanOperation::receiver_delivered(NdbReceiver* tRec){ + Uint32 idx = tRec->m_list_index; + Uint32 last = m_sent_receivers_count - 1; + if(idx != last){ + NdbReceiver * move = m_sent_receivers[last]; + m_sent_receivers[idx] = move; + move->m_list_index = idx; + } + m_sent_receivers_count = last; + + last = m_conf_receivers_count; + m_conf_receivers[last] = tRec; + m_conf_receivers_count = last + 1; + tRec->m_list_index = last; + tRec->m_current_row = 0; } -int NdbScanOperation::setValue(Uint32 anAttrId, Int32 aValue) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrId) == NULL) - return -1; - - m_setValueList->add(anAttrId, aValue); - return 0; +/** + * Remove receiver as it's completed + */ +void +NdbScanOperation::receiver_completed(NdbReceiver* tRec){ + Uint32 idx = tRec->m_list_index; + Uint32 last = m_sent_receivers_count - 1; + if(idx != last){ + NdbReceiver * move = m_sent_receivers[last]; + m_sent_receivers[idx] = move; + move->m_list_index = idx; + } + m_sent_receivers_count = last; } -int NdbScanOperation::setValue(Uint32 anAttrId, Uint32 aValue) +/***************************************************************************** + * int getFirstATTRINFOScan( U_int32 aData ) + * + * Return Value: Return 0: Successful + * Return -1: All other cases + * Parameters: None: Only allocate the first signal. + * Remark: When a scan is defined we need to use this method instead + * of insertATTRINFO for the first signal. + * This is because we need not to mess up the code in + * insertATTRINFO with if statements since we are not + * interested in the TCKEYREQ signal. + *****************************************************************************/ +int +NdbScanOperation::getFirstATTRINFOScan() { - // Check if attribute exist - if (m_currentTable->getColumn(anAttrId) == NULL) - return -1; + NdbApiSignal* tSignal; - m_setValueList->add(anAttrId, aValue); - return 0; -} - -int NdbScanOperation::setValue(Uint32 anAttrId, Uint64 aValue) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrId) == NULL) - return -1; + tSignal = theNdb->getSignal(); + if (tSignal == NULL){ + setErrorCodeAbort(4000); + return -1; + } + tSignal->setSignal(m_attrInfoGSN); + theAI_LenInCurrAI = 8; + theATTRINFOptr = &tSignal->getDataPtrSend()[8]; + theFirstATTRINFO = tSignal; + theCurrentATTRINFO = tSignal; + theCurrentATTRINFO->next(NULL); - m_setValueList->add(anAttrId, aValue); return 0; } -int NdbScanOperation::setValue(Uint32 anAttrId, Int64 aValue) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrId) == NULL) - return -1; +/** + * Constats for theTupleKeyDefined[][0] + */ +#define SETBOUND_EQ 1 +#define FAKE_PTR 2 +#define API_PTR 3 - m_setValueList->add(anAttrId, aValue); - return 0; -} -int NdbScanOperation::setValue(Uint32 anAttrId, float aValue) +/* + * After setBound() are done, move the accumulated ATTRINFO signals to + * a separate list. Then continue with normal scan. + */ +int +NdbScanOperation::saveBoundATTRINFO() { - // Check if attribute exist - if (m_currentTable->getColumn(anAttrId) == NULL) - return -1; - - m_setValueList->add(anAttrId, aValue); - return 0; + theCurrentATTRINFO->setLength(theAI_LenInCurrAI); + theBoundATTRINFO = theFirstATTRINFO; + theTotalBoundAI_Len = theTotalCurrAI_Len; + theTotalCurrAI_Len = 5; + theBoundATTRINFO->setData(theTotalBoundAI_Len, 4); + theBoundATTRINFO->setData(0, 5); + theBoundATTRINFO->setData(0, 6); + theBoundATTRINFO->setData(0, 7); + theBoundATTRINFO->setData(0, 8); + theStatus = GetValue; + + int res = getFirstATTRINFOScan(); + + /** + * Define each key with getValue (if ordered) + * unless the one's with EqBound + */ + if(!res && m_ordered){ + Uint32 idx = 0; + Uint32 cnt = m_currentTable->getNoOfPrimaryKeys(); + while(!theTupleKeyDefined[idx][0] && idx < cnt){ + NdbColumnImpl* col = m_currentTable->getColumn(idx); + NdbRecAttr* tmp = NdbScanOperation::getValue_impl(col, (char*)-1); + UintPtr newVal = UintPtr(tmp); + theTupleKeyDefined[idx][0] = FAKE_PTR; + theTupleKeyDefined[idx][1] = (newVal & 0xFFFFFFFF); +#if (SIZEOF_CHARP == 8) + theTupleKeyDefined[idx][2] = (newVal >> 32); +#endif + idx++; + } + } + return res; } -int NdbScanOperation::setValue(Uint32 anAttrId, double aValue) -{ - // Check if attribute exist - if (m_currentTable->getColumn(anAttrId) == NULL) - return -1; +#define WAITFOR_SCAN_TIMEOUT 120000 - m_setValueList->add(anAttrId, aValue); - return 0; +int +NdbScanOperation::executeCursor(int nodeId){ + NdbConnection * tCon = theNdbCon; + TransporterFacade* tp = TransporterFacade::instance(); + Guard guard(tp->theMutexPtr); + Uint32 seq = tCon->theNodeSequence; + if (tp->get_node_alive(nodeId) && + (tp->getNodeSequence(nodeId) == seq)) { + + if(prepareSendScan(tCon->theTCConPtr, tCon->theTransactionId) == -1) + return -1; + + tCon->theMagicNumber = 0x37412619; + + if (doSendScan(nodeId) == -1) + return -1; + + return 0; + } else { + if (!(tp->get_node_stopping(nodeId) && + (tp->getNodeSequence(nodeId) == seq))){ + TRACE_DEBUG("The node is hard dead when attempting to start a scan"); + setErrorCode(4029); + tCon->theReleaseOnClose = true; + abort(); + } else { + TRACE_DEBUG("The node is stopping when attempting to start a scan"); + setErrorCode(4030); + }//if + tCon->theCommitStatus = Aborted; + }//if + return -1; } -// Private methods - -int NdbScanOperation::executeCursor(int ProcessorId) +int NdbScanOperation::nextResult(bool fetchAllowed) { - int result = theNdbCon->executeScan(); - // If the scan started ok and we are updating or deleting - // iterate over all tuples - if ((m_updateOp) || (m_deleteOp)) { - NdbOperation* newOp; - - while ((result != -1) && (nextResult() == 0)) { - if (m_updateOp) { - newOp = takeOverScanOp(UpdateRequest, m_transConnection); - // Pass setValues from scan operation to new operation - m_setValueList->iterate(SetValueRecList::callSetValueFn, *newOp); - // No need to call updateTuple since scan was taken over for update - // it should be the same with delete - MASV - // newOp->updateTuple(); - } - else if (m_deleteOp) { - newOp = takeOverScanOp(DeleteRequest, m_transConnection); - // newOp->deleteTuple(); + if(m_ordered) + return ((NdbIndexScanOperation*)this)->next_result_ordered(fetchAllowed); + + /** + * Check current receiver + */ + int retVal = 2; + Uint32 idx = m_current_api_receiver; + Uint32 last = m_api_receivers_count; + + /** + * Check next buckets + */ + for(; idx < last; idx++){ + NdbReceiver* tRec = m_api_receivers[idx]; + if(tRec->nextResult()){ + tRec->copyout(theReceiver); + retVal = 0; + break; + } + } + + /** + * We have advanced atleast one bucket + */ + if(!fetchAllowed){ + m_current_api_receiver = idx; + return retVal; + } + + Uint32 nodeId = theNdbCon->theDBnode; + TransporterFacade* tp = TransporterFacade::instance(); + Guard guard(tp->theMutexPtr); + Uint32 seq = theNdbCon->theNodeSequence; + if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false) == 0){ + + idx = m_current_api_receiver; + last = m_api_receivers_count; + + do { + Uint32 cnt = m_conf_receivers_count; + Uint32 sent = m_sent_receivers_count; + + if(cnt > 0){ + /** + * Just move completed receivers + */ + memcpy(m_api_receivers+last, m_conf_receivers, cnt * sizeof(char*)); + last += cnt; + m_conf_receivers_count = 0; + } else if(retVal == 2 && sent > 0){ + /** + * No completed... + */ + theNdb->theWaiter.m_node = nodeId; + theNdb->theWaiter.m_state = WAIT_SCAN; + int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + if (return_code == 0 && seq == tp->getNodeSequence(nodeId)) { + continue; + } else { + idx = last; + retVal = -1; //return_code; + } + } else if(retVal == 2){ + /** + * No completed & no sent -> EndOfData + */ + if(send_next_scan(0, true) == 0){ // Close scan + theNdb->theWaiter.m_node = nodeId; + theNdb->theWaiter.m_state = WAIT_SCAN; + int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + if (return_code == 0 && seq == tp->getNodeSequence(nodeId)) { + return 1; + } + retVal = -1; //return_code; + } else { + retVal = -3; + } + idx = last; } -#if 0 - // takeOverScanOp will take over the lock that scan aquired - // the lock is released when nextScanResult is called - // That means that the "takeover" has to be sent to the kernel - // before nextScanresult is called - MASV - if (m_autoExecute){ - m_transConnection->execute(NoCommit); + + if(retVal == 0) + break; + + for(; idx < last; idx++){ + NdbReceiver* tRec = m_api_receivers[idx]; + if(tRec->nextResult()){ + tRec->copyout(theReceiver); + retVal = 0; + break; + } } -#else - m_transConnection->execute(NoCommit); -#endif - } - closeScan(); + } while(retVal == 2); + } else { + retVal = -3; } - - return result; + + m_api_receivers_count = last; + m_current_api_receiver = idx; + + switch(retVal){ + case 0: + case 1: + case 2: + return retVal; + case -1: + setErrorCode(4008); // Timeout + break; + case -2: + setErrorCode(4028); // Node fail + break; + case -3: // send_next_scan -> return fail (set error-code self) + break; + } + + theNdbCon->theTransactionIsStarted = false; + theNdbCon->theReleaseOnClose = true; + return -1; } -int NdbScanOperation::nextResult(bool fetchAllowed) -{ - int result = theNdbCon->nextScanResult(fetchAllowed); - if (result == -1){ - // Move the error code from hupped transaction - // to the real trans - const NdbError err = theNdbCon->getNdbError(); - m_transConnection->setOperationErrorCode(err.code); +int +NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag){ + if(cnt > 0 || stopScanFlag){ + NdbApiSignal tSignal(theNdb->theMyRef); + tSignal.setSignal(GSN_SCAN_NEXTREQ); + + Uint32* theData = tSignal.getDataPtrSend(); + theData[0] = theNdbCon->theTCConPtr; + theData[1] = stopScanFlag == true ? 1 : 0; + Uint64 transId = theNdbCon->theTransactionId; + theData[2] = transId; + theData[3] = (Uint32) (transId >> 32); + + /** + * Prepare ops + */ + Uint32 last = m_sent_receivers_count; + Uint32 * prep_array = (cnt > 21 ? m_prepared_receivers : theData + 4); + for(Uint32 i = 0; i<cnt; i++){ + NdbReceiver * tRec = m_api_receivers[i]; + m_sent_receivers[last+i] = tRec; + tRec->m_list_index = last+i; + prep_array[i] = tRec->m_tcPtrI; + tRec->prepareSend(); + } + memcpy(&m_api_receivers[0], &m_api_receivers[cnt], cnt * sizeof(char*)); + + Uint32 nodeId = theNdbCon->theDBnode; + TransporterFacade * tp = TransporterFacade::instance(); + int ret; + if(cnt > 21){ + tSignal.setLength(4); + LinearSectionPtr ptr[3]; + ptr[0].p = prep_array; + ptr[0].sz = cnt; + ret = tp->sendFragmentedSignal(&tSignal, nodeId, ptr, 1); + } else { + tSignal.setLength(4+cnt); + ret = tp->sendSignal(&tSignal, nodeId); + } + + m_sent_receivers_count = last + cnt + stopScanFlag; + m_api_receivers_count -= cnt; + m_current_api_receiver = 0; + + return ret; } - return result; + return 0; } int NdbScanOperation::prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId) { printf("NdbScanOperation::prepareSend\n"); + abort(); return 0; } @@ -363,300 +633,689 @@ NdbScanOperation::doSend(int ProcessorId) void NdbScanOperation::closeScan() { - if(theNdbCon){ - if (theNdbCon->stopScan() == -1) - theError = theNdbCon->getNdbError(); - theNdb->closeTransaction(theNdbCon); - theNdbCon = 0; - } - m_transConnection = NULL; -} + do { + TransporterFacade* tp = TransporterFacade::instance(); + Guard guard(tp->theMutexPtr); -void NdbScanOperation::release(){ - closeScan(); - NdbCursorOperation::release(); -} + Uint32 seq = theNdbCon->theNodeSequence; + Uint32 nodeId = theNdbCon->theDBnode; -void SetValueRecList::add(const char* anAttrName, const char* aValue, Uint32 len) -{ - SetValueRec* newSetValueRec = new SetValueRec(); + if(seq != tp->getNodeSequence(nodeId)){ + theNdbCon->theReleaseOnClose = true; + break; + } + + /** + * Wait for all running scans... + */ + while(m_sent_receivers_count){ + theNdb->theWaiter.m_node = nodeId; + theNdb->theWaiter.m_state = WAIT_SCAN; + int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + switch(return_code){ + case 0: + break; + case -1: + setErrorCode(4008); + case -2: + m_sent_receivers_count = 0; + m_api_receivers_count = 0; + m_conf_receivers_count = 0; + } + } + + if(seq != tp->getNodeSequence(nodeId)){ + theNdbCon->theReleaseOnClose = true; + break; + } + + if(m_api_receivers_count+m_conf_receivers_count){ + // Send close scan + send_next_scan(0, true); // Close scan + + /** + * wait for close scan conf + */ + do { + theNdb->theWaiter.m_node = nodeId; + theNdb->theWaiter.m_state = WAIT_SCAN; + int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + switch(return_code){ + case 0: + break; + case -1: + setErrorCode(4008); + case -2: + m_api_receivers_count = 0; + m_conf_receivers_count = 0; + } + } while(m_api_receivers_count+m_conf_receivers_count); + } + } while(0); + + theNdbCon->theScanningOp = 0; + theNdb->closeTransaction(theNdbCon); + + theNdbCon = 0; + m_transConnection = NULL; +} - newSetValueRec->stype = SetValueRec::SET_STRING_ATTR1; - newSetValueRec->anAttrName = strdup(anAttrName); - newSetValueRec->stringStruct.aStringValue = (char *) malloc(len); - strlcpy(newSetValueRec->stringStruct.aStringValue, aValue, len); - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; +void +NdbScanOperation::execCLOSE_SCAN_REP(Uint32 errCode){ + /** + * We will receive no further signals from this scan + */ + if(!errCode){ + /** + * Normal termination + */ + theNdbCon->theCommitStatus = Committed; + theNdbCon->theCompletionStatus = CompletedSuccess; + } else { + /** + * Something is fishy + */ + abort(); } + m_api_receivers_count = 0; + m_conf_receivers_count = 0; + m_sent_receivers_count = 0; } -void SetValueRecList::add(const char* anAttrName, Int32 aValue) +void NdbScanOperation::release() { - SetValueRec* newSetValueRec = new SetValueRec(); - - newSetValueRec->stype = SetValueRec::SET_INT32_ATTR1; - newSetValueRec->anAttrName = strdup(anAttrName); - newSetValueRec->anInt32Value = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; + if(theNdbCon != 0 || m_transConnection != 0){ + closeScan(); + } + for(Uint32 i = 0; i<m_allocated_receivers; i++){ + m_receivers[i]->release(); } } -void SetValueRecList::add(const char* anAttrName, Uint32 aValue) -{ - SetValueRec* newSetValueRec = new SetValueRec(); +/*************************************************************************** +int prepareSendScan(Uint32 aTC_ConnectPtr, + Uint64 aTransactionId) + +Return Value: Return 0 : preparation of send was succesful. + Return -1: In all other case. +Parameters: aTC_ConnectPtr: the Connect pointer to TC. + aTransactionId: the Transaction identity of the transaction. +Remark: Puts the the final data into ATTRINFO signal(s) after this + we know the how many signal to send and their sizes +***************************************************************************/ +int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr, + Uint64 aTransactionId){ + + if (theInterpretIndicator != 1 || + (theOperationType != OpenScanRequest && + theOperationType != OpenRangeScanRequest)) { + setErrorCodeAbort(4005); + return -1; + } - newSetValueRec->stype = SetValueRec::SET_UINT32_ATTR1; - newSetValueRec->anAttrName = strdup(anAttrName); - newSetValueRec->anUint32Value = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; + if (theStatus == SetBound) { + saveBoundATTRINFO(); + theStatus = GetValue; } -} -void SetValueRecList::add(const char* anAttrName, Int64 aValue) -{ - SetValueRec* newSetValueRec = new SetValueRec(); + theErrorLine = 0; - newSetValueRec->stype = SetValueRec::SET_INT64_ATTR1; - newSetValueRec->anAttrName = strdup(anAttrName); - newSetValueRec->anInt64Value = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; + // In preapareSendInterpreted we set the sizes (word 4-8) in the + // first ATTRINFO signal. + if (prepareSendInterpreted() == -1) + return -1; + + if(m_ordered){ + ((NdbIndexScanOperation*)this)->fix_get_values(); + } + + const Uint32 transId1 = (Uint32) (aTransactionId & 0xFFFFFFFF); + const Uint32 transId2 = (Uint32) (aTransactionId >> 32); + + if (theOperationType == OpenRangeScanRequest) { + NdbApiSignal* tSignal = theBoundATTRINFO; + do{ + tSignal->setData(aTC_ConnectPtr, 1); + tSignal->setData(transId1, 2); + tSignal->setData(transId2, 3); + tSignal = tSignal->next(); + } while (tSignal != NULL); + } + theCurrentATTRINFO->setLength(theAI_LenInCurrAI); + NdbApiSignal* tSignal = theFirstATTRINFO; + do{ + tSignal->setData(aTC_ConnectPtr, 1); + tSignal->setData(transId1, 2); + tSignal->setData(transId2, 3); + tSignal = tSignal->next(); + } while (tSignal != NULL); + + /** + * Prepare all receivers + */ + theReceiver.prepareSend(); + bool keyInfo = m_keyInfo; + Uint32 key_size = keyInfo ? m_currentTable->m_keyLenInWords : 0; + for(Uint32 i = 0; i<theParallelism; i++){ + m_receivers[i]->do_get_value(&theReceiver, theBatchSize, key_size); } + return 0; } -void SetValueRecList::add(const char* anAttrName, Uint64 aValue) +/****************************************************************************** +int doSend() + +Return Value: Return >0 : send was succesful, returns number of signals sent + Return -1: In all other case. +Parameters: aProcessorId: Receiving processor node +Remark: Sends the ATTRINFO signal(s) +******************************************************************************/ +int +NdbScanOperation::doSendScan(int aProcessorId) { - SetValueRec* newSetValueRec = new SetValueRec(); + Uint32 tSignalCount = 0; + NdbApiSignal* tSignal; + + if (theInterpretIndicator != 1 || + (theOperationType != OpenScanRequest && + theOperationType != OpenRangeScanRequest)) { + setErrorCodeAbort(4005); + return -1; + } + + assert(theSCAN_TABREQ != NULL); + tSignal = theSCAN_TABREQ; + if (tSignal->setSignal(GSN_SCAN_TABREQ) == -1) { + setErrorCode(4001); + return -1; + } + // Update the "attribute info length in words" in SCAN_TABREQ before + // sending it. This could not be done in openScan because + // we created the ATTRINFO signals after the SCAN_TABREQ signal. + ScanTabReq * const req = CAST_PTR(ScanTabReq, tSignal->getDataPtrSend()); + req->attrLen = theTotalCurrAI_Len; + if (theOperationType == OpenRangeScanRequest) + req->attrLen += theTotalBoundAI_Len; + TransporterFacade *tp = TransporterFacade::instance(); + if(theParallelism > 16){ + LinearSectionPtr ptr[3]; + ptr[0].p = m_prepared_receivers; + ptr[0].sz = theParallelism; + if (tp->sendFragmentedSignal(tSignal, aProcessorId, ptr, 1) == -1) { + setErrorCode(4002); + return -1; + } + } else { + tSignal->setLength(9+theParallelism); + memcpy(tSignal->getDataPtrSend()+9, m_prepared_receivers, 4*theParallelism); + if (tp->sendSignal(tSignal, aProcessorId) == -1) { + setErrorCode(4002); + return -1; + } + } - newSetValueRec->stype = SetValueRec::SET_UINT64_ATTR1; - newSetValueRec->anAttrName = strdup(anAttrName); - newSetValueRec->anUint64Value = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; + if (theOperationType == OpenRangeScanRequest) { + // must have at least one signal since it contains attrLen for bounds + assert(theBoundATTRINFO != NULL); + tSignal = theBoundATTRINFO; + while (tSignal != NULL) { + if (tp->sendSignal(tSignal,aProcessorId) == -1){ + setErrorCode(4002); + return -1; + } + tSignalCount++; + tSignal = tSignal->next(); + } } -} + + tSignal = theFirstATTRINFO; + while (tSignal != NULL) { + if (tp->sendSignal(tSignal,aProcessorId) == -1){ + setErrorCode(4002); + return -1; + } + tSignalCount++; + tSignal = tSignal->next(); + } + theStatus = WaitResponse; + return tSignalCount; +}//NdbOperation::doSendScan() + +/****************************************************************************** + * NdbOperation* takeOverScanOp(NdbConnection* updateTrans); + * + * Parameters: The update transactions NdbConnection pointer. + * Return Value: A reference to the transferred operation object + * or NULL if no success. + * Remark: Take over the scanning transactions NdbOperation + * object for a tuple to an update transaction, + * which is the last operation read in nextScanResult() + * (theNdbCon->thePreviousScanRec) + * + * FUTURE IMPLEMENTATION: (This note was moved from header file.) + * In the future, it will even be possible to transfer + * to a NdbConnection on another Ndb-object. + * In this case the receiving NdbConnection-object must call + * a method receiveOpFromScan to actually receive the information. + * This means that the updating transactions can be placed + * in separate threads and thus increasing the parallelism during + * the scan process. + *****************************************************************************/ +NdbOperation* +NdbScanOperation::takeOverScanOp(OperationType opType, NdbConnection* pTrans){ + + Uint32 idx = m_current_api_receiver; + Uint32 last = m_api_receivers_count; + + Uint32 row; + NdbReceiver * tRec; + NdbRecAttr * tRecAttr; + if(idx < last && (tRec = m_api_receivers[idx]) + && ((row = tRec->m_current_row) <= tRec->m_defined_rows) + && (tRecAttr = tRec->m_rows[row-1])){ + + NdbOperation * newOp = pTrans->getNdbOperation(m_currentTable); + if (newOp == NULL){ + return NULL; + } + + const Uint32 len = (tRecAttr->attrSize() * tRecAttr->arraySize() + 3)/4-1; + + newOp->theTupKeyLen = len; + newOp->theOperationType = opType; + if (opType == DeleteRequest) { + newOp->theStatus = GetValue; + } else { + newOp->theStatus = SetValue; + } + + const Uint32 * src = (Uint32*)tRecAttr->aRef(); + const Uint32 tScanInfo = src[len] & 0xFFFF; + const Uint32 tTakeOverNode = src[len] >> 16; + { + UintR scanInfo = 0; + TcKeyReq::setTakeOverScanFlag(scanInfo, 1); + TcKeyReq::setTakeOverScanNode(scanInfo, tTakeOverNode); + TcKeyReq::setTakeOverScanInfo(scanInfo, tScanInfo); + newOp->theScanInfo = scanInfo; + } -void SetValueRecList::add(const char* anAttrName, float aValue) -{ - SetValueRec* newSetValueRec = new SetValueRec(); + // Copy the first 8 words of key info from KEYINF20 into TCKEYREQ + TcKeyReq * tcKeyReq = CAST_PTR(TcKeyReq,newOp->theTCREQ->getDataPtrSend()); + Uint32 i = 0; + for (i = 0; i < TcKeyReq::MaxKeyInfo && i < len; i++) { + tcKeyReq->keyInfo[i] = * src++; + } + + if(i < len){ + NdbApiSignal* tSignal = theNdb->getSignal(); + newOp->theFirstKEYINFO = tSignal; + + Uint32 left = len - i; + while(tSignal && left > KeyInfo::DataLength){ + tSignal->setSignal(GSN_KEYINFO); + KeyInfo * keyInfo = CAST_PTR(KeyInfo, tSignal->getDataPtrSend()); + memcpy(keyInfo->keyData, src, 4 * KeyInfo::DataLength); + src += KeyInfo::DataLength; + left -= KeyInfo::DataLength; + + tSignal->next(theNdb->getSignal()); + tSignal = tSignal->next(); + } - newSetValueRec->stype = SetValueRec::SET_FLOAT_ATTR1; - newSetValueRec->anAttrName = strdup(anAttrName); - newSetValueRec->aFloatValue = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; + if(tSignal && left > 0){ + tSignal->setSignal(GSN_KEYINFO); + KeyInfo * keyInfo = CAST_PTR(KeyInfo, tSignal->getDataPtrSend()); + memcpy(keyInfo->keyData, src, 4 * left); + } + } + return newOp; } + return 0; } -void SetValueRecList::add(const char* anAttrName, double aValue) +NdbIndexScanOperation::NdbIndexScanOperation(Ndb* aNdb) + : NdbScanOperation(aNdb) { - SetValueRec* newSetValueRec = new SetValueRec(); +} - newSetValueRec->stype = SetValueRec::SET_DOUBLE_ATTR1; - newSetValueRec->anAttrName = strdup(anAttrName); - newSetValueRec->aDoubleValue = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; - } +NdbIndexScanOperation::~NdbIndexScanOperation(){ } -void SetValueRecList::add(Uint32 anAttrId, const char* aValue, Uint32 len) +int +NdbIndexScanOperation::setBound(const char* anAttrName, int type, const void* aValue, Uint32 len) { - SetValueRec* newSetValueRec = new SetValueRec(); - - newSetValueRec->stype = SetValueRec::SET_STRING_ATTR2; - newSetValueRec->anAttrId = anAttrId; - newSetValueRec->stringStruct.aStringValue = (char *) malloc(len); - strlcpy(newSetValueRec->stringStruct.aStringValue, aValue, len); - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; - } + return setBound(m_accessTable->getColumn(anAttrName), type, aValue, len); } -void SetValueRecList::add(Uint32 anAttrId, Int32 aValue) +int +NdbIndexScanOperation::setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len) { - SetValueRec* newSetValueRec = new SetValueRec(); + return setBound(m_accessTable->getColumn(anAttrId), type, aValue, len); +} - newSetValueRec->stype = SetValueRec::SET_INT32_ATTR2; - newSetValueRec->anAttrId = anAttrId; - newSetValueRec->anInt32Value = aValue; - last->next = newSetValueRec; - last = newSetValueRec; +int +NdbIndexScanOperation::equal_impl(const NdbColumnImpl* anAttrObject, + const char* aValue, + Uint32 len){ + return setBound(anAttrObject, BoundEQ, aValue, len); } -void SetValueRecList::add(Uint32 anAttrId, Uint32 aValue) -{ - SetValueRec* newSetValueRec = new SetValueRec(); +NdbRecAttr* +NdbIndexScanOperation::getValue_impl(const NdbColumnImpl* attrInfo, + char* aValue){ + if(!attrInfo->getPrimaryKey() || !m_ordered){ + return NdbScanOperation::getValue_impl(attrInfo, aValue); + } + + Uint32 id = attrInfo->m_attrId; + Uint32 marker = theTupleKeyDefined[id][0]; - newSetValueRec->stype = SetValueRec::SET_UINT32_ATTR2; - newSetValueRec->anAttrId = anAttrId; - newSetValueRec->anUint32Value = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; + if(marker == SETBOUND_EQ){ + return NdbScanOperation::getValue_impl(attrInfo, aValue); + } else if(marker == API_PTR){ + return NdbScanOperation::getValue_impl(attrInfo, aValue); } + + UintPtr oldVal; + oldVal = theTupleKeyDefined[id][1]; +#if (SIZEOF_CHARP == 8) + oldVal = oldVal | (((UintPtr)theTupleKeyDefined[id][2]) << 32); +#endif + theTupleKeyDefined[id][0] = API_PTR; + + NdbRecAttr* tmp = (NdbRecAttr*)oldVal; + tmp->setup(attrInfo, aValue); + return tmp; } -void SetValueRecList::add(Uint32 anAttrId, Int64 aValue) +#include <AttributeHeader.hpp> +/* + * Define bound on index column in range scan. + */ +int +NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, + int type, const void* aValue, Uint32 len) { - SetValueRec* newSetValueRec = new SetValueRec(); + if (theOperationType == OpenRangeScanRequest && + theStatus == SetBound && + (0 <= type && type <= 4) && + aValue != NULL && + len <= 8000) { + // bound type + + insertATTRINFO(type); + // attribute header + Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; + if (len != sizeInBytes && (len != 0)) { + setErrorCodeAbort(4209); + return -1; + } + len = sizeInBytes; + Uint32 tIndexAttrId = tAttrInfo->m_attrId; + Uint32 sizeInWords = (len + 3) / 4; + AttributeHeader ah(tIndexAttrId, sizeInWords); + insertATTRINFO(ah.m_value); + // attribute data + if ((UintPtr(aValue) & 0x3) == 0 && (len & 0x3) == 0) + insertATTRINFOloop((const Uint32*)aValue, sizeInWords); + else { + Uint32 temp[2000]; + memcpy(temp, aValue, len); + while ((len & 0x3) != 0) + ((char*)temp)[len++] = 0; + insertATTRINFOloop(temp, sizeInWords); + } - newSetValueRec->stype = SetValueRec::SET_INT64_ATTR2; - newSetValueRec->anAttrId = anAttrId; - newSetValueRec->anInt64Value = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; + /** + * Do sorted stuff + */ + + /** + * The primary keys for an ordered index is defined in the beginning + * so it's safe to use [tIndexAttrId] + * (instead of looping as is NdbOperation::equal_impl) + */ + if(!theTupleKeyDefined[tIndexAttrId][0]){ + theNoOfTupKeyDefined++; + theTupleKeyDefined[tIndexAttrId][0] = SETBOUND_EQ; + m_sort_columns -= m_ordered; + } + + return 0; + } else { + setErrorCodeAbort(4228); // XXX wrong code + return -1; } } -void SetValueRecList::add(Uint32 anAttrId, Uint64 aValue) -{ - SetValueRec* newSetValueRec = new SetValueRec(); +NdbResultSet* +NdbIndexScanOperation::readTuples(LockMode lm, + Uint32 batch, + Uint32 parallel, + bool order_by){ + NdbResultSet * rs = NdbScanOperation::readTuples(lm, batch, 0); + if(rs && order_by){ + m_ordered = 1; + m_sort_columns = m_accessTable->getNoOfPrimaryKeys(); + m_current_api_receiver = m_sent_receivers_count; + } + return rs; +} - newSetValueRec->stype = SetValueRec::SET_UINT64_ATTR2; - newSetValueRec->anAttrId = anAttrId; - newSetValueRec->anUint64Value = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; +void +NdbIndexScanOperation::fix_get_values(){ + /** + * Loop through all getValues and set buffer pointer to "API" pointer + */ + NdbRecAttr * curr = theReceiver.theFirstRecAttr; + + Uint32 cnt = m_sort_columns; + assert(cnt < MAXNROFTUPLEKEY); + + Uint32 idx = 0; + NdbTableImpl * tab = m_currentTable; + while(cnt > 0){ // To MAXNROFTUPLEKEY loops + NdbColumnImpl * col = tab->getColumn(idx); + if(col->getPrimaryKey()){ + Uint32 val = theTupleKeyDefined[idx][0]; + switch(val){ + case FAKE_PTR: + curr->setup(col, 0); + // Fall-through + case API_PTR: + cnt--; + break; + case SETBOUND_EQ: + (void)1; +#ifdef VM_TRACE + break; + default: + abort(); +#endif + } + } + idx++; } } -void SetValueRecList::add(Uint32 anAttrId, float aValue) -{ - SetValueRec* newSetValueRec = new SetValueRec(); +int +NdbIndexScanOperation::compare(Uint32 skip, Uint32 cols, + const NdbReceiver* t1, + const NdbReceiver* t2){ + + NdbRecAttr * r1 = t1->m_rows[t1->m_current_row]; + NdbRecAttr * r2 = t2->m_rows[t2->m_current_row]; - newSetValueRec->stype = SetValueRec::SET_FLOAT_ATTR2; - newSetValueRec->anAttrId = anAttrId; - newSetValueRec->aFloatValue = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; + r1 = (skip ? r1->next() : r1); + r2 = (skip ? r2->next() : r2); + + while(cols > 0){ + Uint32 * d1 = (Uint32*)r1->aRef(); + Uint32 * d2 = (Uint32*)r2->aRef(); + unsigned r1_null = r1->isNULL(); + if((r1_null ^ (unsigned)r2->isNULL())){ + return (r1_null ? 1 : -1); + } + Uint32 type = NdbColumnImpl::getImpl(* r1->m_column).m_extType; + Uint32 size = (r1->theAttrSize * r1->theArraySize + 3) / 4; + if(!r1_null){ + char r = NdbSqlUtil::cmp(type, d1, d2, size, size); + if(r){ + assert(r != NdbSqlUtil::CmpUnknown); + assert(r != NdbSqlUtil::CmpError); + return r; + } + } + cols--; + r1 = r1->next(); + r2 = r2->next(); } + return 0; } -void SetValueRecList::add(Uint32 anAttrId, double aValue) -{ - SetValueRec* newSetValueRec = new SetValueRec(); +#define DEBUG_NEXT_RESULT 0 + +int +NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){ + + Uint32 u_idx = m_current_api_receiver; // start of unsorted + Uint32 u_last = u_idx + 1; // last unsorted + Uint32 s_idx = u_last; // start of sorted + Uint32 s_last = theParallelism; // last sorted + + NdbReceiver** arr = m_api_receivers; + NdbReceiver* tRec = arr[u_idx]; + + if(DEBUG_NEXT_RESULT) ndbout_c("nextOrderedResult(%d) nextResult: %d", + fetchAllowed, + (u_idx < s_last ? tRec->nextResult() : 0)); + + if(DEBUG_NEXT_RESULT) ndbout_c("u=[%d %d] s=[%d %d]", + u_idx, u_last, + s_idx, s_last); + + bool fetchNeeded = (u_idx == s_last) || !tRec->nextResult(); + + if(fetchNeeded){ + if(fetchAllowed){ + if(DEBUG_NEXT_RESULT) ndbout_c("performing fetch..."); + TransporterFacade* tp = TransporterFacade::instance(); + Guard guard(tp->theMutexPtr); + Uint32 seq = theNdbCon->theNodeSequence; + Uint32 nodeId = theNdbCon->theDBnode; + if(seq == tp->getNodeSequence(nodeId) && !send_next_scan_ordered(u_idx)){ + Uint32 tmp = m_sent_receivers_count; + while(m_sent_receivers_count > 0){ + theNdb->theWaiter.m_node = nodeId; + theNdb->theWaiter.m_state = WAIT_SCAN; + int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + if (return_code == 0 && seq == tp->getNodeSequence(nodeId)) { + continue; + } + return -1; + } + + u_idx = 0; + u_last = m_conf_receivers_count; + s_idx = (u_last > 1 ? s_last : s_idx); + m_conf_receivers_count = 0; + memcpy(arr, m_conf_receivers, u_last * sizeof(char*)); + + if(DEBUG_NEXT_RESULT) ndbout_c("sent: %d recv: %d", tmp, u_last); + } + } else { + return 2; + } + } - newSetValueRec->stype = SetValueRec::SET_DOUBLE_ATTR2; - newSetValueRec->anAttrId = anAttrId; - newSetValueRec->aDoubleValue = aValue; - if (!last) - first = last = newSetValueRec; - else { - last->next = newSetValueRec; - last = newSetValueRec; + if(DEBUG_NEXT_RESULT) ndbout_c("u=[%d %d] s=[%d %d]", + u_idx, u_last, + s_idx, s_last); + + + Uint32 cols = m_sort_columns; + Uint32 skip = m_keyInfo; + while(u_idx < u_last){ + u_last--; + tRec = arr[u_last]; + + // Do binary search instead to find place + Uint32 place = s_idx; + for(; place < s_last; place++){ + if(compare(skip, cols, tRec, arr[place]) <= 0){ + break; + } + } + + if(place != s_idx){ + if(DEBUG_NEXT_RESULT) + ndbout_c("memmove(%d, %d, %d)", s_idx-1, s_idx, (place - s_idx)); + memmove(arr+s_idx-1, arr+s_idx, sizeof(char*)*(place - s_idx)); + } + + if(DEBUG_NEXT_RESULT) ndbout_c("putting %d @ %d", u_last, place - 1); + m_api_receivers[place-1] = tRec; + s_idx--; } -} -void -SetValueRecList::callSetValueFn(SetValueRec& aSetValueRec, NdbOperation& oper) -{ - switch(aSetValueRec.stype) { - case(SetValueRec::SET_STRING_ATTR1): - oper.setValue(aSetValueRec.anAttrName, aSetValueRec.stringStruct.aStringValue, aSetValueRec.stringStruct.len); - break; - case(SetValueRec::SET_INT32_ATTR1): - oper.setValue(aSetValueRec.anAttrName, aSetValueRec.anInt32Value); - break; - case(SetValueRec::SET_UINT32_ATTR1): - oper.setValue(aSetValueRec.anAttrName, aSetValueRec.anUint32Value); - break; - case(SetValueRec::SET_INT64_ATTR1): - oper.setValue(aSetValueRec.anAttrName, aSetValueRec.anInt64Value); - break; - case(SetValueRec::SET_UINT64_ATTR1): - oper.setValue(aSetValueRec.anAttrName, aSetValueRec.anUint64Value); - break; - case(SetValueRec::SET_FLOAT_ATTR1): - oper.setValue(aSetValueRec.anAttrName, aSetValueRec.aFloatValue); - break; - case(SetValueRec::SET_DOUBLE_ATTR1): - oper.setValue(aSetValueRec.anAttrName, aSetValueRec.aDoubleValue); - break; - case(SetValueRec::SET_STRING_ATTR2): - oper.setValue(aSetValueRec.anAttrId, aSetValueRec.stringStruct.aStringValue, aSetValueRec.stringStruct.len); - break; - case(SetValueRec::SET_INT32_ATTR2): - oper.setValue(aSetValueRec.anAttrId, aSetValueRec.anInt32Value); - break; - case(SetValueRec::SET_UINT32_ATTR2): - oper.setValue(aSetValueRec.anAttrId, aSetValueRec.anUint32Value); - break; - case(SetValueRec::SET_INT64_ATTR2): - oper.setValue(aSetValueRec.anAttrId, aSetValueRec.anInt64Value); - break; - case(SetValueRec::SET_UINT64_ATTR2): - oper.setValue(aSetValueRec.anAttrId, aSetValueRec.anUint64Value); - break; - case(SetValueRec::SET_FLOAT_ATTR2): - oper.setValue(aSetValueRec.anAttrId, aSetValueRec.aFloatValue); - break; - case(SetValueRec::SET_DOUBLE_ATTR2): - oper.setValue(aSetValueRec.anAttrId, aSetValueRec.aDoubleValue); - break; + if(DEBUG_NEXT_RESULT) ndbout_c("u=[%d %d] s=[%d %d]", + u_idx, u_last, + s_idx, s_last); + + m_current_api_receiver = s_idx; + + if(DEBUG_NEXT_RESULT) + for(Uint32 i = s_idx; i<s_last; i++) + ndbout_c("%p", arr[i]); + + tRec = m_api_receivers[s_idx]; + if(s_idx < s_last && tRec->nextResult()){ + tRec->copyout(theReceiver); + return 0; } -} -SetValueRec::~SetValueRec() -{ - if ((stype == SET_STRING_ATTR1) || - (stype == SET_INT32_ATTR1) || - (stype == SET_UINT32_ATTR1) || - (stype == SET_INT64_ATTR1) || - (stype == SET_UINT64_ATTR1) || - (stype == SET_FLOAT_ATTR1) || - (stype == SET_DOUBLE_ATTR1)) - free(anAttrName); - - if ((stype == SET_STRING_ATTR1) || - (stype == SET_STRING_ATTR2)) - free(stringStruct.aStringValue); - if (next) delete next; - next = 0; + TransporterFacade* tp = TransporterFacade::instance(); + Guard guard(tp->theMutexPtr); + Uint32 seq = theNdbCon->theNodeSequence; + Uint32 nodeId = theNdbCon->theDBnode; + if(seq == tp->getNodeSequence(nodeId) && send_next_scan(0, true) == 0){ + return 1; + } + return -1; } int -NdbScanOperation::equal_impl(const NdbColumnImpl* anAttrObject, - const char* aValue, - Uint32 len){ - return setBound(anAttrObject, BoundEQ, aValue, len); +NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx){ + if(idx == theParallelism) + return 0; + + NdbApiSignal tSignal(theNdb->theMyRef); + tSignal.setSignal(GSN_SCAN_NEXTREQ); + + Uint32* theData = tSignal.getDataPtrSend(); + theData[0] = theNdbCon->theTCConPtr; + theData[1] = 0; + Uint64 transId = theNdbCon->theTransactionId; + theData[2] = transId; + theData[3] = (Uint32) (transId >> 32); + + /** + * Prepare ops + */ + Uint32 last = m_sent_receivers_count; + Uint32 * prep_array = theData + 4; + + NdbReceiver * tRec = m_api_receivers[idx]; + m_sent_receivers[last] = tRec; + tRec->m_list_index = last; + prep_array[0] = tRec->m_tcPtrI; + tRec->prepareSend(); + + m_sent_receivers_count = last + 1; + + Uint32 nodeId = theNdbCon->theDBnode; + TransporterFacade * tp = TransporterFacade::instance(); + tSignal.setLength(4+1); + return tp->sendSignal(&tSignal, nodeId); } - - diff --git a/ndb/src/ndbapi/Ndbif.cpp b/ndb/src/ndbapi/Ndbif.cpp index 2d722e12129..60eda978397 100644 --- a/ndb/src/ndbapi/Ndbif.cpp +++ b/ndb/src/ndbapi/Ndbif.cpp @@ -16,12 +16,11 @@ #include "NdbApiSignal.hpp" +#include "AttrType.hpp" #include "NdbImpl.hpp" -//#include "NdbSchemaOp.hpp" -//#include "NdbSchemaCon.hpp" #include "NdbOperation.hpp" #include "NdbIndexOperation.hpp" -#include "NdbScanReceiver.hpp" +#include "NdbScanOperation.hpp" #include "NdbConnection.hpp" #include "NdbRecAttr.hpp" #include "NdbReceiver.hpp" @@ -34,6 +33,9 @@ #include <signaldata/CreateIndx.hpp> #include <signaldata/DropIndx.hpp> #include <signaldata/TcIndx.hpp> +#include <signaldata/TransIdAI.hpp> +#include <signaldata/ScanFrag.hpp> +#include <signaldata/ScanTab.hpp> #include <ndb_limits.h> #include <NdbOut.hpp> @@ -41,12 +43,13 @@ /****************************************************************************** - * int init( int aMaxNoOfTransactions ); + * int init( int aNrOfCon, int aNrOfOp ); * * Return Value: Return 0 : init was successful. * Return -1: In all other case. - * Parameters: aMaxNoOfTransactions : Max number of simultaneous transations - * Remark: Create pointers and idle list Synchronous. + * Parameters: aNrOfCon : Number of connections offered to the application. + * aNrOfOp : Number of operations offered to the application. + * Remark: Create pointers and idle list Synchronous. ****************************************************************************/ int Ndb::init(int aMaxNoOfTransactions) @@ -88,7 +91,7 @@ Ndb::init(int aMaxNoOfTransactions) theMyRef = numberToRef(theNdbBlockNumber, theNode); for (i = 1; i < MAX_NDB_NODES; i++){ - if (theFacade->getIsNodeDefined(i)){ + if (theFacade->getIsDbNode(i)){ theDBnodes[theNoOfDBnodes] = i; theNoOfDBnodes++; } @@ -252,9 +255,8 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) for (int i = tNoSentTransactions - 1; i >= 0; i--) { NdbConnection* localCon = theSentTransactionsArray[i]; if (localCon->getConnectedNodeId() == aNodeId ) { - const NdbConnection::SendStatusType sendStatus = localCon->theSendStatus; - if (sendStatus == NdbConnection::sendTC_OP || - sendStatus == NdbConnection::sendTC_COMMIT) { + const SendStatusType sendStatus = localCon->theSendStatus; + if (sendStatus == sendTC_OP || sendStatus == sendTC_COMMIT) { /* A transaction was interrupted in the prepare phase by a node failure. Since the transaction was not found in the phase @@ -262,13 +264,13 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) we report a normal node failure abort. */ localCon->setOperationErrorCodeAbort(4010); - localCon->theCompletionStatus = NdbConnection::CompletedFailure; - } else if (sendStatus == NdbConnection::sendTC_ROLLBACK) { + localCon->theCompletionStatus = CompletedFailure; + } else if (sendStatus == sendTC_ROLLBACK) { /* We aimed for abort and abort we got even if it was by a node failure. We will thus report it as a success. */ - localCon->theCompletionStatus = NdbConnection::CompletedSuccess; + localCon->theCompletionStatus = CompletedSuccess; } else { #ifdef VM_TRACE printState("abortTransactionsAfterNodeFailure %x", this); @@ -280,7 +282,7 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) intact since the node was failing and they were aborted. Thus we set commit state to Aborted and set state to release on close. */ - localCon->theCommitStatus = NdbConnection::Aborted; + localCon->theCommitStatus = Aborted; localCon->theReleaseOnClose = true; completedTransaction(localCon); }//if @@ -300,26 +302,28 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) NdbOperation* tOp; NdbIndexOperation* tIndexOp; NdbConnection* tCon; - int tReturnCode; + int tReturnCode = -1; const Uint32* tDataPtr = aSignal->getDataPtr(); const Uint32 tWaitState = theWaiter.m_state; const Uint32 tSignalNumber = aSignal->readSignalNumber(); const Uint32 tFirstData = *tDataPtr; + const Uint32 tLen = aSignal->getLength(); + void * tFirstDataPtr; /* - In order to support 64 bit processes in the application we need to use - id's rather than a direct pointer to the object used. It is also a good - idea that one cannot corrupt the application code by sending a corrupt - memory pointer. - - All signals received by the API requires the first data word to be such - an id to the receiving object. + In order to support 64 bit processes in the application we need to use + id's rather than a direct pointer to the object used. It is also a good + idea that one cannot corrupt the application code by sending a corrupt + memory pointer. + + All signals received by the API requires the first data word to be such + an id to the receiving object. */ - + switch (tSignalNumber){ case GSN_TCKEYCONF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; const TcKeyConf * const keyConf = (TcKeyConf *)tDataPtr; @@ -327,8 +331,8 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_OP)) { - tReturnCode = tCon->receiveTCKEYCONF(keyConf, aSignal->getLength()); + (tCon->theSendStatus == sendTC_OP)) { + tReturnCode = tCon->receiveTCKEYCONF(keyConf, tLen); if (tReturnCode != -1) { completedTransaction(tCon); }//if @@ -346,91 +350,48 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) return; } - case GSN_READCONF: - { - void* tFirstDataPtr = int2void(tFirstData); - if (tFirstDataPtr == 0) goto InvalidSignal; - - tOp = void2rec_op(tFirstDataPtr); - if (tOp->checkMagicNumber() == 0) { - tCon = tOp->theNdbCon; - if (tCon != NULL) { - if (tCon->theSendStatus == NdbConnection::sendTC_OP) { - tReturnCode = tOp->receiveREAD_CONF(tDataPtr, - aSignal->getLength()); - if (tReturnCode != -1) { - completedTransaction(tCon); - }//if - }//if - }//if - }//if - return; - } case GSN_TRANSID_AI: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); + assert(tFirstDataPtr); if (tFirstDataPtr == 0) goto InvalidSignal; - - // ndbout << "*** GSN_TRANSID_AI ***" << endl; NdbReceiver* tRec = void2rec(tFirstDataPtr); - if (tRec->getType() == NdbReceiver::NDB_OPERATION){ - // tOp = (NdbOperation*)tRec->getOwner(); - tOp = void2rec_op(tFirstDataPtr); - // ndbout << "NDB_OPERATION" << endl; - if (tOp->checkMagicNumber() == 0) { - tCon = tOp->theNdbCon; - if (tCon != NULL) { - if (tCon->theSendStatus == NdbConnection::sendTC_OP) { - tReturnCode = tOp->receiveTRANSID_AI(tDataPtr, - aSignal->getLength()); - if (tReturnCode != -1) { - completedTransaction(tCon); - break; - } - } - } + assert(tRec->checkMagicNumber()); + assert(tRec->getTransaction()); + assert(tRec->getTransaction()->checkState_TransId(((const TransIdAI*)tDataPtr)->transId)); + if(tRec->checkMagicNumber() && (tCon = tRec->getTransaction()) && + tCon->checkState_TransId(((const TransIdAI*)tDataPtr)->transId)){ + Uint32 com; + if(aSignal->m_noOfSections > 0){ + com = tRec->execTRANSID_AI(ptr[0].p, ptr[0].sz); + } else { + com = tRec->execTRANSID_AI(tDataPtr + TransIdAI::HeaderLength, + tLen - TransIdAI::HeaderLength); } - } else if (tRec->getType() == NdbReceiver::NDB_INDEX_OPERATION){ - // tOp = (NdbIndexOperation*)tRec->getOwner(); - tOp = void2rec_iop(tFirstDataPtr); - // ndbout << "NDB_INDEX_OPERATION" << endl; - if (tOp->checkMagicNumber() == 0) { - tCon = tOp->theNdbCon; - if (tCon != NULL) { - if (tCon->theSendStatus == NdbConnection::sendTC_OP) { - tReturnCode = tOp->receiveTRANSID_AI(tDataPtr, - aSignal->getLength()); - if (tReturnCode != -1) { - completedTransaction(tCon); - break; - } - } - } - } - } else if (tRec->getType() == NdbReceiver::NDB_SCANRECEIVER) { - // NdbScanReceiver* tScanRec = (NdbScanReceiver*)tRec->getOwner(); - // NdbScanReceiver* tScanRec = - // (NdbScanReceiver*)(void2rec(tFirstDataPtr)->getOwner()); - NdbScanReceiver* tScanRec = void2rec_srec(tFirstDataPtr); - // ndbout << "NDB_SCANRECEIVER" << endl; - if(tScanRec->checkMagicNumber() == 0){ - tReturnCode = tScanRec->receiveTRANSID_AI_SCAN(aSignal); - if (tReturnCode != -1) { + + if(com == 1){ + switch(tRec->getType()){ + case NdbReceiver::NDB_OPERATION: + case NdbReceiver::NDB_INDEX_OPERATION: + if(tCon->OpCompleteSuccess() != -1) + completedTransaction(tCon); + break; + case NdbReceiver::NDB_SCANRECEIVER: + tCon->theScanningOp->receiver_delivered(tRec); theWaiter.m_state = NO_WAIT; break; + default: + goto InvalidSignal; } } + break; } else { -#ifdef NDB_NO_DROPPED_SIGNAL - abort(); -#endif goto InvalidSignal; } - return; } case GSN_TCKEY_FAILCONF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; const TcKeyFailConf * const failConf = (TcKeyFailConf *)tDataPtr; @@ -441,8 +402,8 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) if (tOp->checkMagicNumber() == 0) { tCon = tOp->theNdbCon; if (tCon != NULL) { - if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || - (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { + if ((tCon->theSendStatus == sendTC_OP) || + (tCon->theSendStatus == sendTC_COMMIT)) { tReturnCode = tCon->receiveTCKEY_FAILCONF(failConf); if (tReturnCode != -1) { completedTransaction(tCon); @@ -461,15 +422,15 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_TCKEY_FAILREF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; tOp = void2rec_op(tFirstDataPtr); if (tOp->checkMagicNumber() == 0) { tCon = tOp->theNdbCon; if (tCon != NULL) { - if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || - (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { + if ((tCon->theSendStatus == sendTC_OP) || + (tCon->theSendStatus == sendTC_ROLLBACK)) { tReturnCode = tCon->receiveTCKEY_FAILREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -482,14 +443,14 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_TCKEYREF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; tOp = void2rec_op(tFirstDataPtr); if (tOp->checkMagicNumber() == 0) { tCon = tOp->theNdbCon; if (tCon != NULL) { - if (tCon->theSendStatus == NdbConnection::sendTC_OP) { + if (tCon->theSendStatus == sendTC_OP) { tReturnCode = tOp->receiveTCKEYREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -503,7 +464,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_TC_COMMITCONF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; const TcCommitConf * const commitConf = (TcCommitConf *)tDataPtr; @@ -511,7 +472,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { + (tCon->theSendStatus == sendTC_COMMIT)) { tReturnCode = tCon->receiveTC_COMMITCONF(commitConf); if (tReturnCode != -1) { completedTransaction(tCon); @@ -531,12 +492,12 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) case GSN_TC_COMMITREF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { + (tCon->theSendStatus == sendTC_COMMIT)) { tReturnCode = tCon->receiveTC_COMMITREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -547,12 +508,12 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_TCROLLBACKCONF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { + (tCon->theSendStatus == sendTC_ROLLBACK)) { tReturnCode = tCon->receiveTCROLLBACKCONF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -562,12 +523,12 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_TCROLLBACKREF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { + (tCon->theSendStatus == sendTC_ROLLBACK)) { tReturnCode = tCon->receiveTCROLLBACKREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -578,7 +539,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_TCROLLBACKREP: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; tCon = void2con(tFirstDataPtr); @@ -592,7 +553,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_TCSEIZECONF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; if (tWaitState != WAIT_TC_SEIZE) { @@ -612,7 +573,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_TCSEIZEREF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; if (tWaitState != WAIT_TC_SEIZE) { @@ -632,7 +593,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_TCRELEASECONF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; if (tWaitState != WAIT_TC_RELEASE) { @@ -650,7 +611,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_TCRELEASEREF: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; if (tWaitState != WAIT_TC_RELEASE) { @@ -704,7 +665,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) case GSN_DIHNDBTAMPER: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; if (tWaitState != WAIT_NDB_TAMPER) @@ -718,27 +679,34 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) break; } case GSN_SCAN_TABCONF: - { - void* tFirstDataPtr = int2void(tFirstData); - if (tFirstDataPtr == 0) goto InvalidSignal; - - //ndbout << "*** GSN_SCAN_TABCONF *** " << endl; - if (tWaitState != WAIT_SCAN){ - return; - } - tCon = void2con(tFirstDataPtr); - if (tCon->checkMagicNumber() != 0) - return; - tReturnCode = tCon->receiveSCAN_TABCONF(aSignal); - if (tReturnCode != -1) - theWaiter.m_state = NO_WAIT; - break; + { + tFirstDataPtr = int2void(tFirstData); + assert(tFirstDataPtr); + assert(void2con(tFirstDataPtr)); + assert(void2con(tFirstDataPtr)->checkMagicNumber() == 0); + if(tFirstDataPtr && + (tCon = void2con(tFirstDataPtr)) && (tCon->checkMagicNumber() == 0)){ + + if(aSignal->m_noOfSections > 0){ + tReturnCode = tCon->receiveSCAN_TABCONF(aSignal, ptr[0].p, ptr[0].sz); + } else { + tReturnCode = + tCon->receiveSCAN_TABCONF(aSignal, + tDataPtr + ScanTabConf::SignalLength, + tLen - ScanTabConf::SignalLength); + } + if (tReturnCode != -1) + theWaiter.m_state = NO_WAIT; + break; + } else { + goto InvalidSignal; } + } case GSN_SCAN_TABREF: - { - void* tFirstDataPtr = int2void(tFirstData); + { + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; - + if (tWaitState == WAIT_SCAN){ tCon = void2con(tFirstDataPtr); if (tCon->checkMagicNumber() == 0){ @@ -753,43 +721,49 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) } case GSN_SCAN_TABINFO: { - void* tFirstDataPtr = int2void(tFirstData); - if (tFirstDataPtr == 0) goto InvalidSignal; - - //ndbout << "*** GSN_SCAN_TABINFO ***" << endl; - if (tWaitState != WAIT_SCAN) - return; - tCon = void2con(tFirstDataPtr); - if (tCon->checkMagicNumber() != 0) - return; - tReturnCode = tCon->receiveSCAN_TABINFO(aSignal); - if (tReturnCode != -1) - theWaiter.m_state = NO_WAIT; - break; + goto InvalidSignal; } case GSN_KEYINFO20: { - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; - - //ndbout << "*** GSN_KEYINFO20 ***" << endl; - NdbScanReceiver* tScanRec = void2rec_srec(tFirstDataPtr); - if (tScanRec->checkMagicNumber() != 0) - return; - tReturnCode = tScanRec->receiveKEYINFO20(aSignal); - if (tReturnCode != -1) - theWaiter.m_state = NO_WAIT; - break; + NdbReceiver* tRec = void2rec(tFirstDataPtr); + + if(tRec->checkMagicNumber() && (tCon = tRec->getTransaction()) && + tCon->checkState_TransId(&((const KeyInfo20*)tDataPtr)->transId1)){ + + Uint32 len = ((const KeyInfo20*)tDataPtr)->keyLen; + Uint32 info = ((const KeyInfo20*)tDataPtr)->scanInfo_Node; + int com = -1; + if(aSignal->m_noOfSections > 0 && len == ptr[0].sz){ + com = tRec->execKEYINFO20(info, ptr[0].p, len); + } else if(len == tLen - KeyInfo20::HeaderLength){ + com = tRec->execKEYINFO20(info, tDataPtr+KeyInfo20::HeaderLength, len); + } + + switch(com){ + case 1: + tCon->theScanningOp->receiver_delivered(tRec); + theWaiter.m_state = NO_WAIT; + break; + case 0: + break; + case -1: + goto InvalidSignal; + } + break; + } + goto InvalidSignal; } case GSN_TCINDXCONF:{ - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; const TcIndxConf * const indxConf = (TcIndxConf *)tDataPtr; const BlockReference aTCRef = aSignal->theSendersBlockRef; tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_OP)) { - tReturnCode = tCon->receiveTCINDXCONF(indxConf, aSignal->getLength()); + (tCon->theSendStatus == sendTC_OP)) { + tReturnCode = tCon->receiveTCINDXCONF(indxConf, tLen); if (tReturnCode != -1) { completedTransaction(tCon); }//if @@ -804,14 +778,14 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) break; } case GSN_TCINDXREF:{ - void* tFirstDataPtr = int2void(tFirstData); + tFirstDataPtr = int2void(tFirstData); if (tFirstDataPtr == 0) goto InvalidSignal; tIndexOp = void2rec_iop(tFirstDataPtr); if (tIndexOp->checkMagicNumber() == 0) { tCon = tIndexOp->theNdbCon; if (tCon != NULL) { - if (tCon->theSendStatus == NdbConnection::sendTC_OP) { + if (tCon->theSendStatus == sendTC_OP) { tReturnCode = tIndexOp->receiveTCINDXREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -865,8 +839,7 @@ Ndb::completedTransaction(NdbConnection* aCon) Uint32 tTransArrayIndex = aCon->theTransArrayIndex; Uint32 tNoSentTransactions = theNoOfSentTransactions; Uint32 tNoCompletedTransactions = theNoOfCompletedTransactions; - if ((tNoSentTransactions > 0) && - (aCon->theListState == NdbConnection::InSendList) && + if ((tNoSentTransactions > 0) && (aCon->theListState == InSendList) && (tTransArrayIndex < tNoSentTransactions)) { NdbConnection* tMoveCon = theSentTransactionsArray[tNoSentTransactions - 1]; @@ -880,7 +853,7 @@ Ndb::completedTransaction(NdbConnection* aCon) theNoOfCompletedTransactions = tNoCompletedTransactions + 1; theNoOfSentTransactions = tNoSentTransactions - 1; - aCon->theListState = NdbConnection::InCompletedList; + aCon->theListState = InCompletedList; aCon->handleExecuteCompletion(); if ((theMinNoOfEventsToWakeUp != 0) && (theNoOfCompletedTransactions >= theMinNoOfEventsToWakeUp)) { @@ -895,8 +868,8 @@ Ndb::completedTransaction(NdbConnection* aCon) ndbout << endl << flush; #ifdef VM_TRACE printState("completedTransaction abort"); -#endif abort(); +#endif }//if }//Ndb::completedTransaction() @@ -915,7 +888,7 @@ Ndb::reportCallback(NdbConnection** aCopyArray, Uint32 aNoOfCompletedTrans) NdbAsynchCallback aCallback = aCopyArray[i]->theCallbackFunction; int tResult = 0; if (aCallback != NULL) { - if (aCopyArray[i]->theReturnStatus == NdbConnection::ReturnFailure) { + if (aCopyArray[i]->theReturnStatus == ReturnFailure) { tResult = -1; }//if (*aCallback)(tResult, aCopyArray[i], anyObject); @@ -939,13 +912,13 @@ Ndb::pollCompleted(NdbConnection** aCopyArray) if (tNoCompletedTransactions > 0) { for (i = 0; i < tNoCompletedTransactions; i++) { aCopyArray[i] = theCompletedTransactionsArray[i]; - if (aCopyArray[i]->theListState != NdbConnection::InCompletedList) { + if (aCopyArray[i]->theListState != InCompletedList) { ndbout << "pollCompleted error "; ndbout << aCopyArray[i]->theListState << endl; abort(); }//if theCompletedTransactionsArray[i] = NULL; - aCopyArray[i]->theListState = NdbConnection::NotInList; + aCopyArray[i]->theListState = NotInList; }//for }//if theNoOfCompletedTransactions = 0; @@ -967,8 +940,8 @@ Ndb::check_send_timeout() a_con->printState(); #endif a_con->setOperationErrorCodeAbort(4012); - a_con->theCommitStatus = NdbConnection::Aborted; - a_con->theCompletionStatus = NdbConnection::CompletedFailure; + a_con->theCommitStatus = Aborted; + a_con->theCompletionStatus = CompletedFailure; a_con->handleExecuteCompletion(); remove_sent_list(i); insert_completed_list(a_con); @@ -997,7 +970,7 @@ Ndb::insert_completed_list(NdbConnection* a_con) Uint32 no_of_comp = theNoOfCompletedTransactions; theCompletedTransactionsArray[no_of_comp] = a_con; theNoOfCompletedTransactions = no_of_comp + 1; - a_con->theListState = NdbConnection::InCompletedList; + a_con->theListState = InCompletedList; a_con->theTransArrayIndex = no_of_comp; return no_of_comp; } @@ -1008,7 +981,7 @@ Ndb::insert_sent_list(NdbConnection* a_con) Uint32 no_of_sent = theNoOfSentTransactions; theSentTransactionsArray[no_of_sent] = a_con; theNoOfSentTransactions = no_of_sent + 1; - a_con->theListState = NdbConnection::InSendList; + a_con->theListState = InSendList; a_con->theTransArrayIndex = no_of_sent; return no_of_sent; } @@ -1046,10 +1019,10 @@ Ndb::sendPrepTrans(int forceSend) if ((tp->getNodeSequence(node_id) == a_con->theNodeSequence) && tp->get_node_alive(node_id) || (tp->get_node_stopping(node_id) && - ((a_con->theSendStatus == NdbConnection::sendABORT) || - (a_con->theSendStatus == NdbConnection::sendABORTfail) || - (a_con->theSendStatus == NdbConnection::sendCOMMITstate) || - (a_con->theSendStatus == NdbConnection::sendCompleted)))) { + ((a_con->theSendStatus == sendABORT) || + (a_con->theSendStatus == sendABORTfail) || + (a_con->theSendStatus == sendCOMMITstate) || + (a_con->theSendStatus == sendCompleted)))) { /* We will send if 1) Node is alive and sequences are correct OR @@ -1081,13 +1054,13 @@ Ndb::sendPrepTrans(int forceSend) again and will thus set the state to Aborted to avoid a more or less eternal loop of tries. */ - if (a_con->theSendStatus == NdbConnection::sendOperations) { + if (a_con->theSendStatus == sendOperations) { a_con->setOperationErrorCodeAbort(4021); - a_con->theCommitStatus = NdbConnection::NeedAbort; + a_con->theCommitStatus = NeedAbort; TRACE_DEBUG("Send buffer full and sendOperations"); } else { a_con->setOperationErrorCodeAbort(4026); - a_con->theCommitStatus = NdbConnection::Aborted; + a_con->theCommitStatus = Aborted; TRACE_DEBUG("Send buffer full, set state to Aborted"); }//if }//if @@ -1104,7 +1077,7 @@ Ndb::sendPrepTrans(int forceSend) */ TRACE_DEBUG("Abort a transaction when stopping a node"); a_con->setOperationErrorCodeAbort(4023); - a_con->theCommitStatus = NdbConnection::NeedAbort; + a_con->theCommitStatus = NeedAbort; } else { /* The node is hard dead and we cannot continue. We will also release @@ -1114,10 +1087,10 @@ Ndb::sendPrepTrans(int forceSend) a_con->setOperationErrorCodeAbort(4025); a_con->theReleaseOnClose = true; a_con->theTransactionIsStarted = false; - a_con->theCommitStatus = NdbConnection::Aborted; + a_con->theCommitStatus = Aborted; }//if }//if - a_con->theCompletionStatus = NdbConnection::CompletedFailure; + a_con->theCompletionStatus = CompletedFailure; a_con->handleExecuteCompletion(); insert_completed_list(a_con); }//for @@ -1255,8 +1228,7 @@ Return: 0 - Response received ******************************************************************************/ int -Ndb::receiveResponse(int waitTime) -{ +Ndb::receiveResponse(int waitTime){ int tResultCode; TransporterFacade::instance()->checkForceSend(theNdbBlockNumber); @@ -1310,10 +1282,10 @@ Ndb::sendRecSignal(Uint16 node_id, if (return_code != -1) { theWaiter.m_node = node_id; theWaiter.m_state = aWaitState; - return receiveResponse(); - // End of protected area - }//if - return_code = -3; + return_code = receiveResponse(); + } else { + return_code = -3; + } } else { return_code = -4; }//if diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp index 042faa431a0..1d9d6fee5e4 100644 --- a/ndb/src/ndbapi/Ndbinit.cpp +++ b/ndb/src/ndbapi/Ndbinit.cpp @@ -137,7 +137,7 @@ Ndb::Ndb( const char* aDataBase , const char* aDataBaseSchema) : TransporterFacade * m_facade = 0; if(theNoOfNdbObjects == 0){ - if ((m_facade = TransporterFacade::start_instance(0,ndbConnectString)) == 0) + if ((m_facade = TransporterFacade::start_instance(ndbConnectString)) == 0) theInitState = InitConfigError; } else { m_facade = TransporterFacade::instance(); diff --git a/ndb/src/ndbapi/Ndblist.cpp b/ndb/src/ndbapi/Ndblist.cpp index 0d9c0f60985..8cc8ba1a079 100644 --- a/ndb/src/ndbapi/Ndblist.cpp +++ b/ndb/src/ndbapi/Ndblist.cpp @@ -15,16 +15,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <NdbOut.hpp> -#include "Ndb.hpp" -//#include "NdbSchemaOp.hpp" -//#include "NdbSchemaCon.hpp" -#include "NdbOperation.hpp" -#include "NdbScanOperation.hpp" -#include "NdbIndexOperation.hpp" -#include "NdbConnection.hpp" +#include <Ndb.hpp> +#include <NdbOperation.hpp> +#include <NdbIndexOperation.hpp> +#include <NdbIndexScanOperation.hpp> +#include <NdbConnection.hpp> #include "NdbApiSignal.hpp" -#include "NdbRecAttr.hpp" -#include "NdbScanReceiver.hpp" +#include <NdbRecAttr.hpp> #include "NdbUtil.hpp" #include "API.hpp" @@ -263,13 +260,13 @@ Ndb::getNdbLabel() * Remark: Get a NdbScanReceiver from theScanRecList and return the * object . ****************************************************************************/ -NdbScanReceiver* +NdbReceiver* Ndb::getNdbScanRec() { - NdbScanReceiver* tNdbScanRec; + NdbReceiver* tNdbScanRec; if ( theScanList == NULL ) { - tNdbScanRec = new NdbScanReceiver(this); + tNdbScanRec = new NdbReceiver(this); if (tNdbScanRec == NULL) { return NULL; @@ -344,17 +341,17 @@ Return Value: Return theOpList : if the getScanOperation was succesful. Return NULL : In all other case. Remark: Get an operation from theScanOpIdleList and return the object . ***************************************************************************/ -NdbScanOperation* +NdbIndexScanOperation* Ndb::getScanOperation() { - NdbScanOperation* tOp = theScanOpIdleList; + NdbIndexScanOperation* tOp = theScanOpIdleList; if (tOp != NULL ) { - NdbScanOperation* tOpNext = (NdbScanOperation*) tOp->next(); + NdbIndexScanOperation* tOpNext = (NdbIndexScanOperation*)tOp->next(); tOp->next(NULL); theScanOpIdleList = tOpNext; return tOp; } else { - tOp = new NdbScanOperation(this); + tOp = new NdbIndexScanOperation(this); if (tOp != NULL) tOp->next(NULL); } @@ -495,7 +492,7 @@ Parameters: aNdbScanRec: The NdbScanReceiver object. Remark: Add a NdbScanReceiver object into the Scan idlelist. ***************************************************************************/ void -Ndb::releaseNdbScanRec(NdbScanReceiver* aNdbScanRec) +Ndb::releaseNdbScanRec(NdbReceiver* aNdbScanRec) { aNdbScanRec->next(theScanList); theScanList = aNdbScanRec; @@ -544,12 +541,12 @@ Parameters: aScanOperation : The released NdbScanOperation object. Remark: Add a NdbScanOperation object into the signal idlelist. ***************************************************************************/ void -Ndb::releaseScanOperation(NdbScanOperation* aScanOperation) +Ndb::releaseScanOperation(NdbIndexScanOperation* aScanOperation) { aScanOperation->next(theScanOpIdleList); aScanOperation->theNdbCon = NULL; aScanOperation->theMagicNumber = 0xFE11D2; - theScanOpIdleList = (NdbScanOperation*)aScanOperation; + theScanOpIdleList = aScanOperation; } /*************************************************************************** @@ -623,7 +620,7 @@ void Ndb::freeScanOperation() { NdbScanOperation* tOp = theScanOpIdleList; - theScanOpIdleList = (NdbScanOperation *) theScanOpIdleList->next(); + theScanOpIdleList = (NdbIndexScanOperation *) theScanOpIdleList->next(); delete tOp; } @@ -674,7 +671,7 @@ Remark: Always release the first item in the free list void Ndb::freeNdbScanRec() { - NdbScanReceiver* tNdbScanRec = theScanList; + NdbReceiver* tNdbScanRec = theScanList; theScanList = theScanList->next(); delete tNdbScanRec; } diff --git a/ndb/src/ndbapi/ObjectMap.hpp b/ndb/src/ndbapi/ObjectMap.hpp index 4abb54b5081..f67774bb413 100644 --- a/ndb/src/ndbapi/ObjectMap.hpp +++ b/ndb/src/ndbapi/ObjectMap.hpp @@ -93,26 +93,28 @@ inline void * NdbObjectIdMap::unmap(Uint32 id, void *object){ - int i = id>>2; + Uint32 i = id>>2; // lock(); - - void * obj = m_map[i].m_obj; - if (object == obj) { - m_map[i].m_next = m_firstFree; - m_firstFree = i; - } else { - ndbout_c("Error: NdbObjectIdMap::::unmap(%u, 0x%x) obj=0x%x", id, object, obj); - return 0; - } - - // unlock(); - + if(i < m_size){ + void * obj = m_map[i].m_obj; + if (object == obj) { + m_map[i].m_next = m_firstFree; + m_firstFree = i; + } else { + ndbout_c("Error: NdbObjectIdMap::::unmap(%u, 0x%x) obj=0x%x", id, object, obj); + return 0; + } + + // unlock(); + #ifdef DEBUG_OBJECTMAP - ndbout_c("NdbObjectIdMap::unmap(%u) obj=0x%x", id, obj); + ndbout_c("NdbObjectIdMap::unmap(%u) obj=0x%x", id, obj); #endif - - return obj; + + return obj; + } + return 0; } inline void * @@ -120,7 +122,11 @@ NdbObjectIdMap::getObject(Uint32 id){ #ifdef DEBUG_OBJECTMAP ndbout_c("NdbObjectIdMap::getObject(%u) obj=0x%x", id, m_map[id>>2].m_obj); #endif - return m_map[id>>2].m_obj; + id >>= 2; + if(id < m_size){ + return m_map[id].m_obj; + } + return 0; } inline void @@ -129,7 +135,6 @@ NdbObjectIdMap::expand(Uint32 incSize){ MapEntry * tmp = (MapEntry*)malloc(newSize * sizeof(MapEntry)); memcpy(tmp, m_map, m_size * sizeof(MapEntry)); - free(m_map); m_map = tmp; for(Uint32 i = m_size; i<newSize; i++){ diff --git a/ndb/src/ndbapi/ScanOperation.txt b/ndb/src/ndbapi/ScanOperation.txt index 7197cf66f7e..27e4e8c1755 100644 --- a/ndb/src/ndbapi/ScanOperation.txt +++ b/ndb/src/ndbapi/ScanOperation.txt @@ -8,3 +8,49 @@ theNdbCon -> z z) NdbConnection (scan) theScanningOp -> y theFirstOpInList -> y (until after openScan) + +# SU + +ScanOpLen: includes KeyInfo +New protocol + +# -- Impl. + +1) Scan uses one NdbReceiver per "parallelism" +2) Each NdbReceiver can handle up to "batch size" rows +3) API send one "pointer" per parallelism (prev. was one per row) +4) API handles each receiver independently. + It can "nextResult"-one, receive one and close-one +5) When a recevier has been "nextResult"-ed, the API can fetch from it again +6) After doing "openScan"-req, no wait is performed + (only possible to block on nextResult(true) or closeScan) + +7) Instead of "ack"-ing each row with length, +* Each row is sent in one lonw signal (unless to short) +* Each NdbReceiver is ack-ed with #rows and sum(#length) +* KeyInfo20 is one signal and included in sum(#length) + +8) The API receive(s) the data into NdbRecAttr-objects + (prev. it copied signals using new/delete) +9) KeyInfo20 is also received into a NdbRecAttr-object +10) + +# -- Close of scan + +1) Each NdbReciver gets a signal when it's complete + (0 rows is ack-ed) +2) The API then "closes" this receiver +3) The API can at any time close then scan for other reason(s) + (example dying) +4) This is signal:ed via a NEXT_SCANREQ (close = 1) +5) TC responds with a SCAN_TABCONF (close = 1) + + +# -- Sorted + +1) The sorted scan is transparent to TC + It's a API only impl. +2) The API makes the following adjustements: +* Scan all fragments simultaniously (max parallelism) +* Never return a row to the API if a NdbReciver is "outstanding" +* Sort Receivers (only top row as they already are sorted within) diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp index 7806e482f1f..e725144a8f8 100644 --- a/ndb/src/ndbapi/TransporterFacade.cpp +++ b/ndb/src/ndbapi/TransporterFacade.cpp @@ -28,6 +28,8 @@ #include "API.hpp" #include <ConfigRetriever.hpp> +#include <mgmapi_config_parameters.h> +#include <mgmapi_configuration.hpp> #include <NdbConfig.h> #include <ndb_version.h> #include <SignalLoggerManager.hpp> @@ -331,39 +333,40 @@ atexit_stop_instance(){ * Which is protected by a mutex */ TransporterFacade* -TransporterFacade::start_instance(Properties* props, const char *connectString) -{ - bool ownProps = false; - if (props == NULL) { - // TransporterFacade used from API get config from mgmt srvr - ConfigRetriever configRetriever; - configRetriever.setConnectString(connectString); - props = configRetriever.getConfig("API", NDB_VERSION); - if (props == 0) { - ndbout << "Configuration error: "; - const char* erString = configRetriever.getErrorString(); - if (erString == 0) { - erString = "No error specified!"; - } - ndbout << erString << endl; - return NULL; +TransporterFacade::start_instance(const char * connectString){ + + // TransporterFacade used from API get config from mgmt srvr + ConfigRetriever configRetriever; + configRetriever.setConnectString(connectString); + ndb_mgm_configuration * props = configRetriever.getConfig(NDB_VERSION, + NODE_TYPE_API); + if (props == 0) { + ndbout << "Configuration error: "; + const char* erString = configRetriever.getErrorString(); + if (erString == 0) { + erString = "No error specified!"; } - props->put("LocalNodeId", configRetriever.getOwnNodeId()); - props->put("LocalNodeType", "API"); - - ownProps = true; + ndbout << erString << endl; + return 0; } - TransporterFacade* tf = new TransporterFacade(); + const int nodeId = configRetriever.getOwnNodeId(); - if (! tf->init(props)) { + TransporterFacade * tf = start_instance(nodeId, props); + + free(props); + return tf; +} + +TransporterFacade* +TransporterFacade::start_instance(int nodeId, + const ndb_mgm_configuration* props) +{ + TransporterFacade* tf = new TransporterFacade(); + if (! tf->init(nodeId, props)) { delete tf; return NULL; } - if (ownProps) { - delete props; - } - /** * Install atexit handler */ @@ -498,61 +501,65 @@ TransporterFacade::TransporterFacade() : } bool -TransporterFacade::init(Properties* props) +TransporterFacade::init(Uint32 nodeId, const ndb_mgm_configuration* props) { - IPCConfig config(props); - - if (config.init() != 0) { - TRP_DEBUG( "IPCConfig object config failed to init()" ); - return false; - } - theOwnId = config.ownId(); - + theOwnId = nodeId; theTransporterRegistry = new TransporterRegistry(this); - if(config.configureTransporters(theTransporterRegistry) <= 0) { + + const int res = IPCConfig::configureTransporters(nodeId, + * props, + * theTransporterRegistry); + if(res <= 0){ TRP_DEBUG( "configureTransporters returned 0 or less" ); return false; } + ndb_mgm_configuration_iterator iter(* props, CFG_SECTION_NODE); + iter.first(); theClusterMgr = new ClusterMgr(* this); - theClusterMgr->init(config); - - theReceiveThread = NdbThread_Create(runReceiveResponse_C, - (void**)this, - 32768, - "ndb_receive", - NDB_THREAD_PRIO_LOW); - - theSendThread = NdbThread_Create(runSendRequest_C, - (void**)this, - 32768, - "ndb_send", - NDB_THREAD_PRIO_LOW); - - theClusterMgr->startThread(); + theClusterMgr->init(iter); /** * Unless there is a "Name", the initiated transporter is within * an NDB Cluster. (If "Name" is defined, then the transporter * is used to connect to a different system, i.e. NDB Cluster.) */ +#if 0 if (!props->contains("Name")) { - const Properties* p = 0; - if(!props->get("Node", ownId(), &p)) { +#endif + iter.first(); + if(iter.find(CFG_NODE_ID, nodeId)){ TRP_DEBUG( "Node info missing from config." ); return false; } Uint32 rank = 0; - if (p->get("ArbitrationRank", &rank) && rank > 0) { + if(!iter.get(CFG_NODE_ARBIT_RANK, &rank) && rank>0){ theArbitMgr = new ArbitMgr(* this); theArbitMgr->setRank(rank); Uint32 delay = 0; - p->get("ArbitrationDelay", &delay); + iter.get(CFG_NODE_ARBIT_DELAY, &delay); theArbitMgr->setDelay(delay); } + +#if 0 } +#endif + + theReceiveThread = NdbThread_Create(runReceiveResponse_C, + (void**)this, + 32768, + "ndb_receive", + NDB_THREAD_PRIO_LOW); + + theSendThread = NdbThread_Create(runSendRequest_C, + (void**)this, + 32768, + "ndb_send", + NDB_THREAD_PRIO_LOW); + theClusterMgr->startThread(); + #ifdef API_TRACE signalLogger.logOn(true, 0, SignalLoggerManager::LogInOut); #endif diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp index 1fe72debe1c..4b76cbe864a 100644 --- a/ndb/src/ndbapi/TransporterFacade.hpp +++ b/ndb/src/ndbapi/TransporterFacade.hpp @@ -27,8 +27,8 @@ class ClusterMgr; class ArbitMgr; -class Properties; class IPCConfig; +struct ndb_mgm_configuration; class Ndb; class NdbApiSignal; @@ -51,10 +51,11 @@ class TransporterFacade public: TransporterFacade(); virtual ~TransporterFacade(); - bool init(Properties* props); + bool init(Uint32, const ndb_mgm_configuration *); static TransporterFacade* instance(); - static TransporterFacade* start_instance(Properties* ipcConfig, const char *connectString); + static TransporterFacade* start_instance(int, const ndb_mgm_configuration*); + static TransporterFacade* start_instance(const char *connectString); static void stop_instance(); /** @@ -79,7 +80,7 @@ public: // Is node available for running transactions bool get_node_alive(NodeId nodeId) const; bool get_node_stopping(NodeId nodeId) const; - bool getIsNodeDefined(NodeId nodeId) const; + bool getIsDbNode(NodeId nodeId) const; bool getIsNodeSendable(NodeId nodeId) const; Uint32 getNodeGrp(NodeId nodeId) const; Uint32 getNodeSequence(NodeId nodeId) const; @@ -255,8 +256,10 @@ TransporterFacade::check_send_size(Uint32 node_id, Uint32 send_size) inline bool -TransporterFacade::getIsNodeDefined(NodeId n) const { - return theClusterMgr->getNodeInfo(n).defined; +TransporterFacade::getIsDbNode(NodeId n) const { + return + theClusterMgr->getNodeInfo(n).defined && + theClusterMgr->getNodeInfo(n).m_info.m_type == NodeInfo::DB; } inline diff --git a/ndb/src/ndbapi/signal-sender/SignalSender.cpp b/ndb/src/ndbapi/signal-sender/SignalSender.cpp index e642848dcee..680d0c23b4a 100644 --- a/ndb/src/ndbapi/signal-sender/SignalSender.cpp +++ b/ndb/src/ndbapi/signal-sender/SignalSender.cpp @@ -71,7 +71,7 @@ SimpleSignal::print(FILE * out){ SignalSender::SignalSender(const char * connectString){ m_cond = NdbCondition_Create(); - theFacade = TransporterFacade::start_instance(0,connectString); + theFacade = TransporterFacade::start_instance(connectString); m_blockNo = theFacade->open(this, execSignal, execNodeStatus); assert(m_blockNo > 0); } diff --git a/ndb/src/rep/adapters/ExtNDB.cpp b/ndb/src/rep/adapters/ExtNDB.cpp index 036406828be..6642b750b57 100644 --- a/ndb/src/rep/adapters/ExtNDB.cpp +++ b/ndb/src/rep/adapters/ExtNDB.cpp @@ -72,22 +72,26 @@ ExtNDB::init(const char * connectString) "ExtNDB_Service", NDB_THREAD_PRIO_LOW); - ConfigRetriever configRetriever; - configRetriever.setConnectString(connectString); +#if 0 + /** + * I don't see that this does anything + * + * Jonas 13/2-04 + */ + ConfigRetriever cr; cr.setConnectString(connectString); - Properties* config = configRetriever.getConfig("REP", REP_VERSION_ID); + ndb_mgm_configuration * config = cr.getConfig(NDB_VERSION, NODE_TYPE_REP); if (config == 0) { ndbout << "ExtNDB: Configuration error: "; - const char* erString = configRetriever.getErrorString(); + const char* erString = cr.getErrorString(); if (erString == 0) { erString = "No error specified!"; } ndbout << erString << endl; return false; } - m_ownNodeId = configRetriever.getOwnNodeId(); - config->put("LocalNodeId", m_ownNodeId); - config->put("LocalNodeType", "REP"); + NdbAutoPtr autoPtr(config); + m_ownNodeId = r.getOwnNodeId(); /** * Check which GREPs to connect to (in configuration) @@ -117,6 +121,7 @@ ExtNDB::init(const char * connectString) } } } +#endif m_transporterFacade = TransporterFacade::instance(); @@ -142,7 +147,7 @@ ExtNDB::init(const char * connectString) m_ownBlockNo); for (Uint32 i=1; i<MAX_NDB_NODES; i++) { - if (m_transporterFacade->getIsNodeDefined(i) && + if (m_transporterFacade->getIsDbNode(i) && m_transporterFacade->getIsNodeSendable(i)) { Uint32 nodeGrp = m_transporterFacade->getNodeGrp(i); diff --git a/ndb/src/rep/state/RepState.hpp b/ndb/src/rep/state/RepState.hpp index e88151d5609..06bbca19f7e 100644 --- a/ndb/src/rep/state/RepState.hpp +++ b/ndb/src/rep/state/RepState.hpp @@ -22,6 +22,7 @@ #include <rep/repapi/repapi.h> #include <rep/ExtSender.hpp> #include <rep/adapters/AppNDB.hpp> +#include <Properties.hpp> #include "Channel.hpp" #include "Interval.hpp" diff --git a/ndb/src/rep/transfer/TransPS.cpp b/ndb/src/rep/transfer/TransPS.cpp index d43555a0ce5..11fb0203cbc 100644 --- a/ndb/src/rep/transfer/TransPS.cpp +++ b/ndb/src/rep/transfer/TransPS.cpp @@ -47,6 +47,8 @@ TransPS::~TransPS() void TransPS::init(TransporterFacade * tf, const char * connectString) { + abort(); +#ifdef NOT_FUNCTIONAL m_signalExecThread = NdbThread_Create(signalExecThread_C, (void **)this, 32768, @@ -128,6 +130,7 @@ TransPS::init(TransporterFacade * tf, const char * connectString) m_repSender->setNodeId(extRepNodeId); m_repSender->setOwnRef(m_ownRef); m_repSender->setTransporterFacade(tf); +#endif } /***************************************************************************** diff --git a/ndb/src/rep/transfer/TransSS.cpp b/ndb/src/rep/transfer/TransSS.cpp index 719271df238..376c6375bc4 100644 --- a/ndb/src/rep/transfer/TransSS.cpp +++ b/ndb/src/rep/transfer/TransSS.cpp @@ -52,6 +52,8 @@ TransSS::~TransSS() void TransSS::init(const char * connectString) { + abort(); +#ifdef NOT_FUNCTIONAL m_signalExecThread = NdbThread_Create(signalExecThread_C, (void **)this, 32768, @@ -139,6 +141,7 @@ TransSS::init(const char * connectString) m_repSender->setNodeId(extRepNodeId); m_repSender->setOwnRef(m_ownRef); m_repSender->setTransporterFacade(m_transporterFacade); +#endif } /***************************************************************************** diff --git a/ndb/test/include/HugoTransactions.hpp b/ndb/test/include/HugoTransactions.hpp index 5ff1fef16bc..d859c463acf 100644 --- a/ndb/test/include/HugoTransactions.hpp +++ b/ndb/test/include/HugoTransactions.hpp @@ -38,12 +38,12 @@ public: int scanReadRecords(Ndb*, int records, int abort = 0, - int parallelism = 1, + int parallelism = 0, bool committed = false); int scanReadCommittedRecords(Ndb*, int records, int abort = 0, - int parallelism = 1); + int parallelism = 0); int pkReadRecords(Ndb*, int records, int batchsize = 1, @@ -52,20 +52,20 @@ public: int scanUpdateRecords(Ndb*, int records, int abort = 0, - int parallelism = 1); + int parallelism = 0); int scanUpdateRecords1(Ndb*, int records, int abort = 0, - int parallelism = 1); + int parallelism = 0); int scanUpdateRecords2(Ndb*, int records, int abort = 0, - int parallelism = 1); + int parallelism = 0); int scanUpdateRecords3(Ndb*, int records, int abort = 0, - int parallelism = 1); + int parallelism = 0); int pkUpdateRecords(Ndb*, int records, @@ -100,24 +100,6 @@ public: int batchsize = 1); protected: - int takeOverAndUpdateRecord(Ndb*, - NdbOperation*); -#if 0 - int setValueForAttr(NdbOperation*, - int attrId, - int rowId, - int updateId); -public: - int equalForAttr(NdbOperation*, - int attrId, - int rowId); -#endif - - int addRowToUpdate(Ndb* pNdb, - NdbConnection* pUpdTrans, - NdbOperation* pOrgOp); - - NDBT_ResultRow row; int m_defaultScanUpdateMethod; }; diff --git a/ndb/test/include/NdbConfig.hpp b/ndb/test/include/NdbConfig.hpp index f13872f4d64..19439fafbb2 100644 --- a/ndb/test/include/NdbConfig.hpp +++ b/ndb/test/include/NdbConfig.hpp @@ -17,29 +17,22 @@ #ifndef NDBT_CONFIG_HPP #define NDBT_CONFIG_HPP +#include <ndb_types.h> #include <mgmapi.h> #include <Vector.hpp> #include <NdbRestarter.hpp> -#include <Properties.hpp> +#include <mgmapi_config_parameters.h> -class NdbConfig : public NdbRestarter{ +class NdbConfig : public NdbRestarter { public: NdbConfig(int own_id, const char* addr = 0) : NdbRestarter(addr), ownNodeId(own_id) {}; - bool getProperty(unsigned int node_id, const char* type, - const char * name, Uint32 * value) const; - bool getProperty(unsigned int node_id, const char* type, - const char * name, const char ** value) const; - - bool getHostName(unsigned int node_id, - const char ** hostname) const; -protected: - bool getPropsForNode(unsigned int node_id, - const char* type, - const Properties ** props) const; + bool getProperty(unsigned nodeid, unsigned type, unsigned key, Uint32 * val); + bool getHostName(unsigned int node_id, const char ** hostname); + //protected: int ownNodeId; }; diff --git a/ndb/test/include/NdbRestarter.hpp b/ndb/test/include/NdbRestarter.hpp index cfd5409bb69..b4c29a87eff 100644 --- a/ndb/test/include/NdbRestarter.hpp +++ b/ndb/test/include/NdbRestarter.hpp @@ -89,7 +89,9 @@ protected: const char* host; int port; NdbMgmHandle handle; - + ndb_mgm_configuration * m_config; +protected: + ndb_mgm_configuration * getConfig(); }; #endif diff --git a/ndb/test/include/UtilTransactions.hpp b/ndb/test/include/UtilTransactions.hpp index b16ab74455e..1298028d591 100644 --- a/ndb/test/include/UtilTransactions.hpp +++ b/ndb/test/include/UtilTransactions.hpp @@ -34,24 +34,24 @@ public: int clearTable(Ndb*, int records = 0, - int parallelism = 240); + int parallelism = 0); // Delete all records from the table using a scan int clearTable1(Ndb*, int records = 0, - int parallelism = 16); + int parallelism = 0); // Delete all records from the table using a scan // Using batching int clearTable2(Ndb*, int records = 0, - int parallelism = 240); + int parallelism = 0); int clearTable3(Ndb*, int records = 0, - int parallelism = 240); + int parallelism = 0); int selectCount(Ndb*, - int parallelism = 16, + int parallelism = 0, int* count_rows = NULL, ScanLock lock = SL_Read, NdbConnection* pTrans = NULL); @@ -64,7 +64,7 @@ public: ReadCallBackFn* fn = NULL); int verifyIndex(Ndb*, const char* indexName, - int parallelism = 240, + int parallelism = 0, bool transactional = false); int copyTableData(Ndb*, @@ -88,7 +88,7 @@ private: int verifyUniqueIndex(Ndb*, const char* indexName, - int parallelism = 240, + int parallelism = 0, bool transactional = false); int scanAndCompareUniqueIndex(Ndb* pNdb, diff --git a/ndb/test/ndbapi/Makefile_old b/ndb/test/ndbapi/Makefile_old index 91f0c84c18e..2e20f05ecc9 100644 --- a/ndb/test/ndbapi/Makefile_old +++ b/ndb/test/ndbapi/Makefile_old @@ -4,12 +4,11 @@ include .defs.mk ifeq ($(NDB_OS), OSE) DIRS = basic flexBench flexAsynch else -DIRS = lmc-bench bank ronja +DIRS = lmc-bench ronja BIN_DIRS = \ flexAsynch \ flexBench \ flexHammer \ - flexScan \ flexTT \ create_tab \ create_all_tabs \ @@ -32,7 +31,6 @@ BIN_DIRS = \ testDataBuffers \ testDict \ acid \ - interpreterInTup \ telco \ indexTest \ test_event \ diff --git a/ndb/test/ndbapi/ScanFunctions.hpp b/ndb/test/ndbapi/ScanFunctions.hpp index 36d01909861..e0a88ab9e94 100644 --- a/ndb/test/ndbapi/ScanFunctions.hpp +++ b/ndb/test/ndbapi/ScanFunctions.hpp @@ -80,7 +80,8 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, int sleepTime = 10; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; + NdbResultSet *rs; while (true){ if (retryAttempt >= retryMax){ @@ -104,69 +105,36 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, // Execute the scan without defining a scan operation if(action != ExecuteScanWithOutOpenScan){ - - if (action == OnlyOneOpBeforeOpenScan){ - // There can only be one operation defined when calling openScan - NdbOperation* pOp3; - pOp3 = pTrans->getNdbOperation(tab.getName()); - if (pOp3 == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - if (exclusive == true) - check = pOp->openScanExclusive(parallelism); - else - check = pOp->openScanRead(parallelism); - if( check == -1 ) { + + rs = pOp->readTuples(exclusive ? + NdbScanOperation::LM_Exclusive : + NdbScanOperation::LM_Read); + + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - - if (action == OnlyOneScanPerTrans){ - // There can only be one operation in a scan transaction - NdbOperation* pOp4; - pOp4 = pTrans->getNdbOperation(tab.getName()); - if (pOp4 == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - + if (action == OnlyOpenScanOnce){ // Call openScan one more time when it's already defined - check = pOp->openScanRead(parallelism); - if( check == -1 ) { + NdbResultSet* rs2 = pOp->readTuples(NdbScanOperation::LM_Read); + if( rs2 == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } } - - if (action == OnlyOneOpInScanTrans){ - // Try to add another op to this scanTransaction - NdbOperation* pOp2; - pOp2 = pTrans->getNdbOperation(tab.getName()); - if (pOp2 == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - + if (action==EqualAfterOpenScan){ check = pOp->equal(tab.getColumn(0)->getName(), 10); if( check == -1 ) { @@ -191,7 +159,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, } } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -203,7 +171,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, bool abortTrans = (action==CloseWithoutStop); int eof; int rows = 0; - eof = pTrans->nextScanResult(); + eof = rs->nextResult(); while(eof == 0){ rows++; @@ -213,7 +181,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, if (action != CloseWithoutStop){ // Test that we can closeTrans without stopScan - check = pTrans->stopScan(); + rs->close(); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -236,7 +204,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, } } - eof = pTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); @@ -246,7 +214,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, // Be cruel, call nextScanResult after error for(int i=0; i<10; i++){ - eof =pTrans->nextScanResult(); + eof = rs->nextResult(); if(eof == 0){ g_err << "nextScanResult returned eof = " << eof << endl << " That is an error when there are no more records" << endl; @@ -276,7 +244,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, if (action == NextScanWhenNoMore){ g_info << "Calling nextScanresult when there are no more records" << endl; for(int i=0; i<10; i++){ - eof =pTrans->nextScanResult(); + eof = rs->nextResult(); if(eof == 0){ g_err << "nextScanResult returned eof = " << eof << endl << " That is an error when there are no more records" << endl; @@ -285,7 +253,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, } } - if(action ==CheckInactivityBeforeClose){ + if(action == CheckInactivityBeforeClose){ // Sleep for a long time before calling close g_info << "NdbSleep_SecSleep(5) before close transaction" << endl; NdbSleep_SecSleep(5); diff --git a/ndb/test/ndbapi/ScanInterpretTest.hpp b/ndb/test/ndbapi/ScanInterpretTest.hpp index 3862de34111..e8a0d4b6dca 100644 --- a/ndb/test/ndbapi/ScanInterpretTest.hpp +++ b/ndb/test/ndbapi/ScanInterpretTest.hpp @@ -197,7 +197,7 @@ ScanInterpretTest::scanRead(Ndb* pNdb, int retryMax = 100; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; while (true){ @@ -220,16 +220,17 @@ ScanInterpretTest::scanRead(Ndb* pNdb, return NDBT_FAILED; } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - - check = pOp->openScanRead(parallelism); - //check = pOp->openScanExclusive(parallelism); - if( check == -1 ) { + + NdbResultSet * rs = pOp->readTuples(NdbScanOperation::LM_Read, + 0, parallelism); + + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -250,7 +251,7 @@ ScanInterpretTest::scanRead(Ndb* pNdb, return NDBT_FAILED; } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -261,32 +262,22 @@ ScanInterpretTest::scanRead(Ndb* pNdb, int rows = 0; NdbConnection* pInsTrans; - while((eof = pTrans->nextScanResult(true)) == 0){ - pInsTrans = pNdb->startTransaction(); - if (pInsTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - ERR(err); - return NDBT_FAILED; - } + while((eof = rs->nextResult(true)) == 0){ do { rows++; - if (addRowToInsert(pNdb, pInsTrans) != 0){ + if (addRowToInsert(pNdb, pTrans) != 0){ pNdb->closeTransaction(pTrans); - pNdb->closeTransaction(pInsTrans); return NDBT_FAILED; } - } while((eof = pTrans->nextScanResult(false)) == 0); + } while((eof = rs->nextResult(false)) == 0); - check = pInsTrans->execute(Commit); + check = pTrans->execute(Commit); if( check == -1 ) { - const NdbError err = pInsTrans->getNdbError(); + const NdbError err = pTrans->getNdbError(); ERR(err); - pNdb->closeTransaction(pInsTrans); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - pNdb->closeTransaction(pInsTrans); - } if (eof == -1) { const NdbError err = pTrans->getNdbError(); @@ -322,7 +313,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, const int retryMax = 100; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; while (true){ @@ -346,7 +337,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { if (pOp->getValue("KOL2") == 0){ ERR(pNdb->getNdbError()); return NDBT_FAILED; @@ -357,9 +348,10 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - - check = pOp->openScanRead(parallelism); - if( check == -1 ) { + + NdbResultSet * rs = pOp->readTuples(NdbScanOperation::LM_Read, + 0, parallelism); + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -382,7 +374,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, return NDBT_FAILED; } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -400,7 +392,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, NdbConnection* pExistTrans; NdbConnection* pNoExistTrans; - while((eof = pTrans->nextScanResult(true)) == 0){ + while((eof = rs->nextResult(true)) == 0){ pExistTrans = pNdb->startTransaction(); if (pExistTrans == NULL) { const NdbError err = pNdb->getNdbError(); @@ -432,7 +424,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, return NDBT_FAILED; } } - } while((eof = pTrans->nextScanResult(false)) == 0); + } while((eof = rs->nextResult(false)) == 0); // Execute the transaction containing reads of diff --git a/ndb/test/ndbapi/old_dirs/testBackup/Makefile b/ndb/test/ndbapi/old_dirs/testBackup/Makefile index ce0e404803c..abf47dcfb2d 100644 --- a/ndb/test/ndbapi/old_dirs/testBackup/Makefile +++ b/ndb/test/ndbapi/old_dirs/testBackup/Makefile @@ -3,7 +3,6 @@ include .defs.mk TYPE = ndbapitest BIN_TARGET = testBackup -BIN_TARGET_LIBS += bank SOURCES = testBackup.cpp include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testGrep/Makefile b/ndb/test/ndbapi/old_dirs/testGrep/Makefile index 34fdd7113d0..6bad3d56a00 100644 --- a/ndb/test/ndbapi/old_dirs/testGrep/Makefile +++ b/ndb/test/ndbapi/old_dirs/testGrep/Makefile @@ -3,7 +3,6 @@ include .defs.mk TYPE = ndbapitest DIRS = verify BIN_TARGET = testGrep -BIN_TARGET_LIBS += bank SOURCES = testGrep.cpp include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile b/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile index 4e6182de6b2..256e3c98f36 100644 --- a/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile +++ b/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile @@ -3,7 +3,6 @@ include .defs.mk TYPE = ndbapitest BIN_TARGET = testGrepVerify -BIN_TARGET_LIBS += bank SOURCES = testGrepVerify.cpp CFLAGS_testGrepVerify.cpp += -I$(call fixpath,$(NDB_TOP)/include/kernel) -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) diff --git a/ndb/test/ndbapi/testBackup.cpp b/ndb/test/ndbapi/testBackup.cpp index 129eced54b0..6641045942c 100644 --- a/ndb/test/ndbapi/testBackup.cpp +++ b/ndb/test/ndbapi/testBackup.cpp @@ -205,6 +205,8 @@ int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +#if 0 + #include "bank/Bank.hpp" int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ @@ -393,6 +395,7 @@ int runRestoreBankAndVerify(NDBT_Context* ctx, NDBT_Step* step){ return result; } +#endif NDBT_TESTSUITE(testBackup); TESTCASE("BackupOne", @@ -410,6 +413,7 @@ TESTCASE("BackupOne", FINALIZER(runClearTable); } +#if 0 TESTCASE("BackupBank", "Test that backup and restore works during transaction load\n" " by backing up the bank" @@ -428,8 +432,8 @@ TESTCASE("BackupBank", STEP(runBackupBank); VERIFIER(runRestoreBankAndVerify); // FINALIZER(runDropBank); - } +#endif TESTCASE("NFMaster", "Test that backup behaves during node failiure\n"){ INITIALIZER(setMaster); diff --git a/ndb/test/ndbapi/testDataBuffers.cpp b/ndb/test/ndbapi/testDataBuffers.cpp index 75773040113..ea13ec1b069 100644 --- a/ndb/test/ndbapi/testDataBuffers.cpp +++ b/ndb/test/ndbapi/testDataBuffers.cpp @@ -84,6 +84,8 @@ static NdbSchemaCon* tcon = 0; static NdbSchemaOp* top = 0; static NdbConnection* con = 0; static NdbOperation* op = 0; +static NdbScanOperation* sop = 0; +static NdbResultSet* rs = 0; static int ndberror(char const* fmt, ...) @@ -438,9 +440,9 @@ testcase(int flag) int newkey = 0; if ((con = ndb->startTransaction()) == 0) return ndberror("startTransaction key=%d", key); - if ((op = con->getNdbOperation(tab)) == 0) + if ((sop = con->getNdbScanOperation(tab)) == 0) return ndberror("getNdbOperation key=%d", key); - if (op->openScanRead(1) < 0) + if ((rs = sop->readTuples(1)) == 0) return ndberror("openScanRead key=%d", key); { col& c = ccol[0]; @@ -481,10 +483,10 @@ testcase(int flag) } } } - if (con->executeScan() < 0) + if (con->execute(NoCommit) < 0) return ndberror("executeScan key=%d", key); int ret, cnt = 0; - while ((ret = con->nextScanResult()) == 0) { + while ((ret = rs->nextResult()) == 0) { if (key != newkey) return ndberror("unexpected key=%d newkey=%d", key, newkey); for (int i = 1; i < attrcnt; i++) { diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index 06614690b8d..1451c942362 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1003,9 +1003,9 @@ int runGetPrimaryKey(NDBT_Context* ctx, NDBT_Step* step){ int NF_codes[] = { - 14000 - ,14001 - //,14002 + 6003 + ,6004 + //,6005 }; int diff --git a/ndb/test/ndbapi/testGrep.cpp b/ndb/test/ndbapi/testGrep.cpp index 4b870f6f9a9..b8966d15c5e 100644 --- a/ndb/test/ndbapi/testGrep.cpp +++ b/ndb/test/ndbapi/testGrep.cpp @@ -254,6 +254,7 @@ int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +#if 0 #include "../bank/Bank.hpp" @@ -444,6 +445,8 @@ int runRestoreBankAndVerify(NDBT_Context* ctx, NDBT_Step* step){ return result; } */ +#endif + NDBT_TESTSUITE(testGrep); TESTCASE("GrepBasic", "Test that Global Replication works on one table \n" @@ -473,7 +476,7 @@ TESTCASE("GrepNodeRestart", } - +#if 0 TESTCASE("GrepBank", "Test that grep and restore works during transaction load\n" @@ -495,6 +498,8 @@ TESTCASE("GrepBank", // FINALIZER(runDropBank); } +#endif + TESTCASE("NFMaster", "Test that grep behaves during node failiure\n"){ INITIALIZER(setMaster); diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp index 47db0b3cff7..d93c7f6a8a0 100644 --- a/ndb/test/ndbapi/testIndex.cpp +++ b/ndb/test/ndbapi/testIndex.cpp @@ -1130,7 +1130,7 @@ runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){ if(!pTrans) goto done; sOp = pTrans->getNdbScanOperation(pTab->getName()); if(!sOp) goto done; - rs = sOp->readTuples(240, NdbScanOperation::LM_Exclusive); + rs = sOp->readTuples(NdbScanOperation::LM_Exclusive); if(!rs) goto done; if(pTrans->execute(NoCommit) == -1) goto done; while((eof = rs->nextResult(true)) == 0){ diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp index a47d9d2099e..4b82cadffa5 100644 --- a/ndb/test/ndbapi/testOIBasic.cpp +++ b/ndb/test/ndbapi/testOIBasic.cpp @@ -551,7 +551,8 @@ struct Con { NdbConnection* m_tx; NdbOperation* m_op; NdbConnection* m_scantx; - NdbOperation* m_scanop; + NdbIndexScanOperation* m_scanop; + NdbResultSet* m_resultSet; enum ScanMode { ScanNo = 0, Committed, Latest, Exclusive }; ScanMode m_scanmode; enum ErrType { ErrNone = 0, ErrDeadlock, ErrOther }; @@ -632,7 +633,7 @@ Con::getNdbOperation(const Tab& tab) int Con::getNdbOperation(const ITab& itab, const Tab& tab) { - CHKCON((m_op = m_tx->getNdbOperation(itab.m_name, tab.m_name)) != 0, *this); + CHKCON((m_scanop = m_tx->getNdbIndexScanOperation(itab.m_name, tab.m_name)) != 0, *this); return 0; } @@ -664,7 +665,7 @@ int Con::setBound(int num, int type, const void* value) { assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->setBound(num, type, value) == 0, *this); + CHKCON(m_scanop->setBound(num, type, value) == 0, *this); return 0; } @@ -680,7 +681,7 @@ int Con::openScanRead(unsigned parallelism) { assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->openScanRead(parallelism) == 0, *this); + CHKCON((m_resultSet = m_scanop->readTuples(parallelism)) != 0, *this); return 0; } @@ -688,14 +689,14 @@ int Con::openScanExclusive(unsigned parallelism) { assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->openScanExclusive(parallelism) == 0, *this); + CHKCON((m_resultSet = m_scanop->readTuplesExclusive(parallelism)) != 0, *this); return 0; } int Con::executeScan() { - CHKCON(m_tx->executeScan() == 0, *this); + CHKCON(m_tx->execute(NoCommit) == 0, *this); return 0; } @@ -703,7 +704,8 @@ int Con::nextScanResult() { int ret; - CHKCON((ret = m_tx->nextScanResult()) != -1, *this); + assert(m_resultSet != 0); + CHKCON((ret = m_resultSet->nextResult()) != -1, *this); assert(ret == 0 || ret == 1); return ret; } @@ -712,7 +714,7 @@ int Con::takeOverForUpdate(Con& scan) { assert(m_tx != 0 && scan.m_op != 0); - CHKCON((m_op = scan.m_op->takeOverForUpdate(m_tx)) != 0, scan); + CHKCON((m_op = scan.m_resultSet->updateTuple(m_tx)) != 0, scan); return 0; } @@ -720,7 +722,7 @@ int Con::takeOverForDelete(Con& scan) { assert(m_tx != 0 && scan.m_op != 0); - CHKCON((m_op = scan.m_op->takeOverForUpdate(m_tx)) != 0, scan); + CHKCON(scan.m_resultSet->deleteTuple(m_tx) == 0, scan); return 0; } diff --git a/ndb/test/ndbapi/testSystemRestart.cpp b/ndb/test/ndbapi/testSystemRestart.cpp index 1b8a35487cb..61e086ff941 100644 --- a/ndb/test/ndbapi/testSystemRestart.cpp +++ b/ndb/test/ndbapi/testSystemRestart.cpp @@ -805,6 +805,207 @@ int runSystemRestart5(NDBT_Context* ctx, NDBT_Step* step){ return result; } +int runSystemRestart6(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + Uint32 i = 1; + + const Uint32 nodeCount = restarter.getNumDbNodes(); + if(nodeCount < 2){ + g_info << "SR6 - Needs atleast 2 nodes to test" << endl; + return NDBT_OK; + } + + Vector<int> nodeIds; + for(Uint32 i = 0; i<nodeCount; i++) + nodeIds.push_back(restarter.getDbNodeId(i)); + + Uint32 currentRestartNodeIndex = 0; + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + while(i<=loops && result != NDBT_FAILED){ + + g_info << "Loop " << i << "/"<< loops <<" started" << endl; + /** + * 1. Load data + * 2. Restart all node -nostart + * 3. Restart some nodes -i -nostart + * 4. Start all nodes verify records + */ + g_info << "Loading records..." << endl; + hugoTrans.loadTable(pNdb, records); + + CHECK(restarter.restartAll(false, true, false) == 0); + + Uint32 nodeId = nodeIds[currentRestartNodeIndex]; + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + CHECK(restarter.restartOneDbNode(nodeId, true, true,false) == 0); + CHECK(restarter.waitClusterNoStart(timeout) == 0); + CHECK(restarter.startAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + int count = records - 1; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(utilTrans.clearTable(pNdb) == 0); + i++; + } + + g_info << "runSystemRestart6 finished" << endl; + + return result; +} + +int runSystemRestart7(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + Uint32 i = 1; + + const Uint32 nodeCount = restarter.getNumDbNodes(); + if(nodeCount < 2){ + g_info << "SR8 - Needs atleast 2 nodes to test" << endl; + return NDBT_OK; + } + + Vector<int> nodeIds; + for(Uint32 i = 0; i<nodeCount; i++) + nodeIds.push_back(restarter.getDbNodeId(i)); + + int a_nodeIds[64]; + if(nodeCount > 64) + abort(); + + Uint32 currentRestartNodeIndex = 1; + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + while(i<=loops && result != NDBT_FAILED){ + + g_info << "Loop " << i << "/"<< loops <<" started" << endl; + /** + * 1. Load data + * 2. Restart all node -nostart + * 3. Start all but one node + * 4. Wait for startphase >= 2 + * 5. Start last node + * 6. Verify records + */ + g_info << "Loading records..." << endl; + hugoTrans.loadTable(pNdb, records); + + CHECK(restarter.restartAll(false, true, false) == 0); + + int nodeId = nodeIds[currentRestartNodeIndex]; + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + Uint32 j = 0; + for(Uint32 k = 0; k<nodeCount; k++){ + if(nodeIds[k] != nodeId){ + a_nodeIds[j++] = nodeIds[k]; + } + } + + CHECK(restarter.startNodes(a_nodeIds, nodeCount - 1) == 0); + CHECK(restarter.waitNodesStarted(a_nodeIds, nodeCount - 1, 120) == 0); + CHECK(pNdb->waitUntilReady(5) == 0); + int count = records - 1; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + + CHECK(restarter.startNodes(&nodeId, 1) == 0); + CHECK(restarter.waitNodesStarted(&nodeId, 1, 120) == 0); + + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(utilTrans.clearTable(pNdb) == 0); + + i++; + } + + g_info << "runSystemRestart7 finished" << endl; + + return result; +} + +int runSystemRestart8(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + Uint32 i = 1; + + const Uint32 nodeCount = restarter.getNumDbNodes(); + if(nodeCount < 2){ + g_info << "SR8 - Needs atleast 2 nodes to test" << endl; + return NDBT_OK; + } + + Vector<int> nodeIds; + for(Uint32 i = 0; i<nodeCount; i++) + nodeIds.push_back(restarter.getDbNodeId(i)); + + int a_nodeIds[64]; + if(nodeCount > 64) + abort(); + + Uint32 currentRestartNodeIndex = 1; + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + while(i<=loops && result != NDBT_FAILED){ + + g_info << "Loop " << i << "/"<< loops <<" started" << endl; + /** + * 1. Load data + * 2. Restart all node -nostart + * 3. Start all but one node + * 4. Verify records + * 5. Start last node + * 6. Verify records + */ + g_info << "Loading records..." << endl; + hugoTrans.loadTable(pNdb, records); + + CHECK(restarter.restartAll(false, true, false) == 0); + + int nodeId = nodeIds[currentRestartNodeIndex]; + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + Uint32 j = 0; + for(Uint32 k = 0; k<nodeCount; k++){ + if(nodeIds[k] != nodeId){ + a_nodeIds[j++] = nodeIds[k]; + } + } + + CHECK(restarter.startNodes(a_nodeIds, nodeCount-1) == 0); + CHECK(restarter.waitNodesStartPhase(a_nodeIds, nodeCount-1, 3, 120) == 0); + CHECK(restarter.startNodes(&nodeId, 1) == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + + int count = records - 1; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(utilTrans.clearTable(pNdb) == 0); + i++; + } + + g_info << "runSystemRestart7 finished" << endl; + + return result; +} + int runWaitStarted(NDBT_Context* ctx, NDBT_Step* step){ NdbRestarter restarter; @@ -817,8 +1018,13 @@ int runWaitStarted(NDBT_Context* ctx, NDBT_Step* step){ int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ int records = ctx->getNumRecords(); - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + Ndb* pNdb = GETNDB(step); + if(pNdb->waitUntilReady(5) != 0){ + return NDBT_FAILED; + } + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(pNdb, records) != 0){ return NDBT_FAILED; } return NDBT_OK; @@ -933,6 +1139,43 @@ TESTCASE("SR5", STEP(runSystemRestart5); FINALIZER(runClearTable); } +TESTCASE("SR6", + "Perform system restart with some nodes having FS others wo/\n" + "* 1. Load data\n" + "* 2. Restart all node -nostart\n" + "* 3. Restart some nodes -i -nostart\n" + "* 4. Start all nodes verify records\n"){ + INITIALIZER(runWaitStarted); + INITIALIZER(runClearTable); + STEP(runSystemRestart6); + FINALIZER(runClearTable); +} +TESTCASE("SR7", + "Perform partition win system restart\n" + "* 1. Load data\n" + "* 2. Restart all node -nostart\n" + "* 3. Start all but one node\n" + "* 4. Verify records\n" + "* 5. Start last node\n" + "* 6. Verify records\n"){ + INITIALIZER(runWaitStarted); + INITIALIZER(runClearTable); + STEP(runSystemRestart7); + FINALIZER(runClearTable); +} +TESTCASE("SR8", + "Perform partition win system restart with other nodes delayed\n" + "* 1. Load data\n" + "* 2. Restart all node -nostart\n" + "* 3. Start all but one node\n" + "* 4. Wait for startphase >= 2\n" + "* 5. Start last node\n" + "* 6. Verify records\n"){ + INITIALIZER(runWaitStarted); + INITIALIZER(runClearTable); + STEP(runSystemRestart8); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testSystemRestart); int main(int argc, const char** argv){ diff --git a/ndb/test/ndbapi/testTimeout.cpp b/ndb/test/ndbapi/testTimeout.cpp index de1d2cfc40b..8a7866880b3 100644 --- a/ndb/test/ndbapi/testTimeout.cpp +++ b/ndb/test/ndbapi/testTimeout.cpp @@ -57,8 +57,8 @@ int runTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ int stepNo = step->getStepNo(); Uint32 timeoutVal; if (!conf.getProperty(nodeId, - "DB", - "TransactionInactiveTimeout", + NODE_TYPE_DB, + CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &timeoutVal)){ return NDBT_FAILED; } @@ -103,8 +103,8 @@ int runDontTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ int stepNo = step->getStepNo(); Uint32 timeoutVal; if (!conf.getProperty(nodeId, - "DB", - "TransactionInactiveTimeout", + NODE_TYPE_DB, + CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &timeoutVal)){ return NDBT_FAILED; } @@ -151,8 +151,8 @@ int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){ int stepNo = step->getStepNo(); Uint32 timeoutVal; if (!conf.getProperty(nodeId, - "DB", - "TransactionInactiveTimeout", + NODE_TYPE_DB, + CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &timeoutVal)){ return NDBT_FAILED; } diff --git a/ndb/test/src/HugoOperations.cpp b/ndb/test/src/HugoOperations.cpp index 91263aa29b4..f4b814adee2 100644 --- a/ndb/test/src/HugoOperations.cpp +++ b/ndb/test/src/HugoOperations.cpp @@ -295,6 +295,7 @@ int HugoOperations::pkDeleteRecord(Ndb* pNdb, int HugoOperations::scanReadRecords(Ndb* pNdb, Uint32 parallelism, ScanLock lock){ +#ifdef JONAS_NOT_DONE NdbConnection * pCon = pNdb->hupp(pTrans); NDBT_ResultRow * m_tmpRow = new NDBT_ResultRow(tab); ScanTmp tmp(pCon, m_tmpRow); @@ -350,6 +351,7 @@ int HugoOperations::scanReadRecords(Ndb* pNdb, m_scans.push_back(tmp); return 0; +#endif } int HugoOperations::executeScanRead(Ndb* pNdb){ @@ -414,6 +416,7 @@ int HugoOperations::execute_Commit(Ndb* pNdb, int HugoOperations::run(ScanTmp & tmp){ +#if JONAS_NOT_DONE int count = 0; if(tmp.m_op == ScanTmp::DONE) abort(); @@ -443,6 +446,7 @@ HugoOperations::run(ScanTmp & tmp){ if(count == 0) return 626; +#endif return 0; } diff --git a/ndb/test/src/HugoTransactions.cpp b/ndb/test/src/HugoTransactions.cpp index 7f12484ddc8..7c26baa3ec2 100644 --- a/ndb/test/src/HugoTransactions.cpp +++ b/ndb/test/src/HugoTransactions.cpp @@ -48,7 +48,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, const int retryMax = 100; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; while (true){ @@ -72,19 +72,18 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, return NDBT_FAILED; } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - if (committed == true) - check = pOp->openScanReadCommitted(parallelism); - else - check = pOp->openScanRead(parallelism); + NdbResultSet * rs; + rs = pOp ->readTuples(committed ? NdbScanOperation::LM_CommittedRead : + NdbScanOperation::LM_Read); - if( check == -1 ) { + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -106,7 +105,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ @@ -130,12 +129,10 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, if (abortCount < abortPercent) abortTrans = true; } - + int eof; int rows = 0; - eof = pTrans->nextScanResult(); - - while(eof == 0){ + while((eof = rs->nextResult(true)) == 0){ rows++; if (calc.verifyRowValues(&row) != 0){ pNdb->closeTransaction(pTrans); @@ -145,22 +142,20 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, if (abortCount == rows && abortTrans == true){ ndbout << "Scan is aborted" << endl; g_info << "Scan is aborted" << endl; - check = pTrans->stopScan(); + rs->close(); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - + pNdb->closeTransaction(pTrans); return NDBT_OK; } - - eof = pTrans->nextScanResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); - + if (err.status == NdbError::TemporaryError){ ERR_INFO(err); pNdb->closeTransaction(pTrans); @@ -199,106 +194,6 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, #define RESTART_SCAN 99 -// Take over one record from pOrgOp and update it -int -HugoTransactions::takeOverAndUpdateRecord(Ndb* pNdb, - NdbOperation* pOrgOp){ - int retryAttempt = 0; - const int retryMax = 10; - int check; - NdbConnection *pUpdTrans; - NdbOperation *pUpdOp; - - while (true){ - - if (retryAttempt >= retryMax){ - g_info << "ERROR: has retried this operation " << retryAttempt - << " times, failing!" << endl; - return NDBT_FAILED; - } - - pUpdTrans = pNdb->startTransaction(); - if (pUpdTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - - if (err.status == NdbError::TemporaryError){ - ERR(err); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - return NDBT_FAILED; - } - - if ((pUpdOp = pOrgOp->takeOverForUpdate(pUpdTrans)) == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - - int updates = calc.getUpdatesValue(&row) + 1; - int id = calc.getIdValue(&row); - - // Set a calculated value for each non-PK attribute in this table - for (int a = 0; a<tab.getNoOfColumns(); a++){ - if (tab.getColumn(a)->getPrimaryKey() == false){ - if(setValueForAttr(pUpdOp, a, id, updates ) != 0){ - ERR(pUpdTrans->getNdbError()); - pNdb->closeTransaction(pUpdTrans); - return NDBT_FAILED; - } - } - } - check = pUpdTrans->execute( Commit ); - if(check == -1 ) { - const NdbError err = pUpdTrans->getNdbError(); - pNdb->closeTransaction(pUpdTrans); - - ERR(err); - if(err.code == 499 || err.code == 250){ - return RESTART_SCAN; - } - - switch(err.status){ - case NdbError::Success: - g_info << "ERROR: NdbError reports success when transcaction failed" - << endl; - return NDBT_FAILED; - break; - - case NdbError::TemporaryError: - NdbSleep_MilliSleep(50+50*retryAttempt); - retryAttempt++; - continue; - break; - - case NdbError::UnknownResult: - return NDBT_FAILED; - break; - - default: - case NdbError::PermanentError: - switch (err.code){ - case 499: - case 250: - return NDBT_TEMPORARY; - - default: - return NDBT_FAILED; - break; - } - break; - } - } - else{ - pNdb->closeTransaction(pUpdTrans); - } - - return NDBT_OK; - } - return NDBT_FAILED; -} - int HugoTransactions::scanUpdateRecords(Ndb* pNdb, int records, @@ -320,6 +215,9 @@ HugoTransactions::scanUpdateRecords1(Ndb* pNdb, int records, int abortPercent, int parallelism){ +#if 1 + return scanUpdateRecords3(pNdb, records, abortPercent, 1); +#else int retryAttempt = 0; const int retryMax = 100; int check; @@ -472,9 +370,9 @@ HugoTransactions::scanUpdateRecords1(Ndb* pNdb, return NDBT_OK; } return NDBT_FAILED; +#endif } - // Scan all records exclusive and update // them batched by asking nextScanResult to // give us all cached records before fetching new @@ -484,6 +382,9 @@ HugoTransactions::scanUpdateRecords2(Ndb* pNdb, int records, int abortPercent, int parallelism){ +#if 1 + return scanUpdateRecords3(pNdb, records, abortPercent, parallelism); +#else int retryAttempt = 0; const int retryMax = 100; int check; @@ -642,35 +543,9 @@ HugoTransactions::scanUpdateRecords2(Ndb* pNdb, return NDBT_OK; } return NDBT_FAILED; +#endif } -int -HugoTransactions::addRowToUpdate(Ndb* pNdb, - NdbConnection* pUpdTrans, - NdbOperation* pOrgOp){ - - int updates = calc.getUpdatesValue(&row) + 1; - int r = calc.getIdValue(&row); - - NdbOperation* pUpdOp = pOrgOp->takeOverForUpdate(pUpdTrans); - if (pUpdOp == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - - for(int a = 0; a<tab.getNoOfColumns(); a++){ - if (tab.getColumn(a)->getPrimaryKey() == false){ - if(setValueForAttr(pUpdOp, a, r, updates ) != 0){ - ERR(pUpdTrans->getNdbError()); - pNdb->closeTransaction(pUpdTrans); - return NDBT_FAILED; - } - } - } - return NDBT_OK; -} - - int HugoTransactions::scanUpdateRecords3(Ndb* pNdb, int records, @@ -759,7 +634,6 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb, } const int updates = calc.getUpdatesValue(&row) + 1; const int r = calc.getIdValue(&row); - for(int a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pUp, a, r, updates ) != 0){ @@ -794,7 +668,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb, return NDBT_FAILED; } } - + const NdbError err = pTrans->getNdbError(); if( check == -1 ) { pNdb->closeTransaction(pTrans); @@ -2083,7 +1957,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb, int check; NdbConnection *pTrans; NdbOperation *pOp; - NdbScanOperation *sOp; + NdbIndexScanOperation *sOp; NdbResultSet * rs; const NdbDictionary::Index* pIndex @@ -2134,7 +2008,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb, } check = pOp->readTuple(); } else { - pOp = sOp = pTrans->getNdbScanOperation(idxName, tab.getName()); + pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); if (sOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -2284,7 +2158,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, return NDBT_FAILED; } } else { - pOp = sOp = pTrans->getNdbScanOperation(idxName, tab.getName()); + pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); diff --git a/ndb/test/src/Makefile_old b/ndb/test/src/Makefile_old index 2b634bcd3cd..2738ce1aba2 100644 --- a/ndb/test/src/Makefile_old +++ b/ndb/test/src/Makefile_old @@ -15,10 +15,12 @@ SOURCES = NDBT_ReturnCodes.cpp \ SOURCES.c = CFLAGS_NdbRestarter.cpp := -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) -CFLAGS_NdbBackup.cpp := -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) -CFLAGS_NdbConfig.cpp := -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) +CFLAGS_NdbConfig.cpp := -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) \ + -I$(call fixpath,$(NDB_TOP)/src/mgmapi) CFLAGS_NdbRestarts.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) -CFLAGS_NdbBackup.cpp += -I$(call fixpath,$(NDB_TOP)/include/kernel) +CFLAGS_NdbBackup.cpp := -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) \ + -I$(call fixpath,$(NDB_TOP)/src/mgmapi) \ + -I$(call fixpath,$(NDB_TOP)/include/kernel) CFLAGS_NdbGrep.cpp += -I$(call fixpath,$(NDB_TOP)/include/kernel) -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/src/NDBT_Tables.cpp b/ndb/test/src/NDBT_Tables.cpp index 548e755a3fb..8fd2d4042fd 100644 --- a/ndb/test/src/NDBT_Tables.cpp +++ b/ndb/test/src/NDBT_Tables.cpp @@ -835,7 +835,7 @@ NDBT_Tables::printAll(){ if (tab == NULL){ abort(); } - ndbout << (* tab) << endl; + ndbout << (* (NDBT_Table*)tab) << endl; } return NDBT_OK; diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp index 6cbb69508f5..13dc67748a5 100644 --- a/ndb/test/src/NdbBackup.cpp +++ b/ndb/test/src/NdbBackup.cpp @@ -19,7 +19,6 @@ #include <NdbOut.hpp> #include <NDBT_Output.hpp> #include <NdbConfig.h> -#include <ConfigRetriever.hpp> #include <ndb_version.h> #include <NDBT.hpp> #include <NdbSleep.h> @@ -32,6 +31,10 @@ << " (Line: " << __LINE__ << ")" << "- " << _xx << endl; \ return NDBT_FAILED; } } +#include <ConfigRetriever.hpp> +#include <mgmapi.h> +#include <mgmapi_config_parameters.h> +#include <mgmapi_configuration.hpp> int NdbBackup::start(unsigned int & _backup_id){ @@ -68,16 +71,12 @@ NdbBackup::getFileSystemPathForNode(int _node_id){ */ ConfigRetriever cr; - - Properties * p = cr.getConfig(host, - port, - _node_id, - NDB_VERSION); + ndb_mgm_configuration * p = cr.getConfig(host, port, 0); if(p == 0){ const char * s = cr.getErrorString(); if(s == 0) s = "No error given!"; - + ndbout << "Could not fetch configuration" << endl; ndbout << s << endl; return NULL; @@ -86,19 +85,19 @@ NdbBackup::getFileSystemPathForNode(int _node_id){ /** * Setup cluster configuration data */ - const Properties * db = 0; - if (!p->get("Node", _node_id, &db)) { + ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE); + if (iter.find(CFG_NODE_ID, _node_id)){ ndbout << "Invalid configuration fetched, DB missing" << endl; return NULL; } - const char * type; - if(!(db->get("Type", &type) && strcmp(type, "DB") == 0)){ + unsigned int type; + if(!iter.get(CFG_TYPE_OF_SECTION, &type) || type != NODE_TYPE_DB){ ndbout <<"Invalid configuration fetched, I'm wrong type of node" << endl; return NULL; } - + const char * path; - if (!db->get("FileSystemPath", &path)){ + if (iter.get(CFG_DB_FILESYSTEM_PATH, &path)){ ndbout << "FileSystemPath not found" << endl; return NULL; } diff --git a/ndb/test/src/NdbConfig.cpp b/ndb/test/src/NdbConfig.cpp index 3a254bc1577..2fb466d1b8f 100644 --- a/ndb/test/src/NdbConfig.cpp +++ b/ndb/test/src/NdbConfig.cpp @@ -17,144 +17,67 @@ #include "NdbConfig.hpp" #include <NdbOut.hpp> #include <NDBT_Output.hpp> +#include <assert.h> #include <NdbConfig.h> #include <ConfigRetriever.hpp> #include <ndb_version.h> - - +#include <mgmapi.h> +#include <mgmapi_config_parameters.h> +#include <mgmapi_configuration.hpp> bool -NdbConfig::getPropsForNode(unsigned int node_id, - const char* type, - const Properties ** props) const { - - /** - * Fetch configuration from management server - */ - ConfigRetriever cr; - - - Properties * p = cr.getConfig(host, - port, - node_id, - NDB_VERSION); +NdbConfig::getHostName(unsigned int node_id, const char ** hostname) { + + ndb_mgm_configuration * p = getConfig(); if(p == 0){ - const char * s = cr.getErrorString(); - if(s == 0) - s = "No error given!"; - - ndbout << "Could not fetch configuration" << endl; - ndbout << s << endl; return false; - } + } /** * Setup cluster configuration data */ - if (!p->get("Node", node_id, props)) { - ndbout << "Invalid configuration fetched no info for nodeId = " - << node_id << endl; + ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE); + if (iter.find(CFG_NODE_ID, node_id)){ + ndbout << "Invalid configuration fetched, DB missing" << endl; return false; } - const char * str; - if(!((*props)->get("Type", &str) && strcmp(str, type) == 0)){ - ndbout <<"Invalid configuration fetched, type != " << type << endl; - return false; - } - return true; -} - -bool -NdbConfig::getProperty(unsigned int node_id, - const char* type, - const char* name, - const char ** value) const { - const Properties * db = 0; - - if(!getPropsForNode(node_id, type, &db)){ + if (iter.get(CFG_NODE_HOST, hostname)){ + ndbout << "Host not found" << endl; return false; } - if (!db->get(name, value)){ - ndbout << name << " not found" << endl; - return false; - } - return true; } bool -NdbConfig::getProperty(unsigned int node_id, - const char* type, - const char* name, - Uint32 * value) const { - const Properties * db = 0; - - if(!getPropsForNode(node_id, type, &db)){ - return false; - } - - if (!db->get(name, value)){ - ndbout << name << " not found" << endl; - return false; - } - - return true; -} - - -bool -NdbConfig::getHostName(unsigned int node_id, - const char ** hostname) const { - /** - * Fetch configuration from management server - */ - ConfigRetriever cr; - - - Properties * p = cr.getConfig(host, - port, - node_id, - NDB_VERSION); +NdbConfig::getProperty(unsigned nodeid, + unsigned type, unsigned key, Uint32 * val){ + ndb_mgm_configuration * p = getConfig(); if(p == 0){ - const char * s = cr.getErrorString(); - if(s == 0) - s = "No error given!"; - - ndbout << "Could not fetch configuration" << endl; - ndbout << s << endl; return false; - } + } /** * Setup cluster configuration data */ - const Properties * node_props; - if (!p->get("Node", node_id, &node_props)) { - ndbout << "Invalid configuration fetched no info for node = " - << node_id << endl; - return false; - } - const char* computer_id_str; - if (!node_props->get("ExecuteOnComputer", &computer_id_str)){ - ndbout << "ExecuteOnComputer not found" << endl; + ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE); + if (iter.find(CFG_NODE_ID, nodeid)){ + ndbout << "Invalid configuration fetched, DB missing" << endl; return false; } - - const Properties * comp_props; - if (!p->get("Computer", atoi(computer_id_str), &comp_props)) { - ndbout << "Invalid configuration fetched no info for computer = " - << node_id << endl; + unsigned _type; + if (iter.get(CFG_TYPE_OF_SECTION, &_type) || type != _type){ + ndbout << "No such node in configuration" << endl; return false; } - if (!comp_props->get("HostName", hostname)){ - ndbout << "HostName not found" << endl; + + if (iter.get(key, val)){ + ndbout << "No such key: " << key << " in configuration" << endl; return false; } - - + return true; } diff --git a/ndb/test/src/NdbRestarter.cpp b/ndb/test/src/NdbRestarter.cpp index cc2fab46cc5..b731cccb259 100644 --- a/ndb/test/src/NdbRestarter.cpp +++ b/ndb/test/src/NdbRestarter.cpp @@ -36,7 +36,8 @@ NdbRestarter::NdbRestarter(const char* _addr): addr(_addr), host(NULL), port(-1), - handle(NULL) + handle(NULL), + m_config(0) { if (addr == NULL){ LocalConfig lcfg; @@ -661,3 +662,13 @@ int NdbRestarter::exitSingleUserMode(){ } return reply.return_code; } + +ndb_mgm_configuration* +NdbRestarter::getConfig(){ + if(m_config) return m_config; + + if (!isConnected()) + return 0; + m_config = ndb_mgm_get_configuration(handle, 0); + return m_config; +} diff --git a/ndb/test/src/UtilTransactions.cpp b/ndb/test/src/UtilTransactions.cpp index 3ef31a2f535..8963e580bca 100644 --- a/ndb/test/src/UtilTransactions.cpp +++ b/ndb/test/src/UtilTransactions.cpp @@ -47,10 +47,14 @@ UtilTransactions::clearTable(Ndb* pNdb, } } + int UtilTransactions::clearTable1(Ndb* pNdb, int records, int parallelism){ +#if 1 + return clearTable3(pNdb, records, 1); +#else // Scan all records exclusive and delete // them one by one int retryAttempt = 0; @@ -191,12 +195,16 @@ UtilTransactions::clearTable1(Ndb* pNdb, return NDBT_OK; } return NDBT_FAILED; +#endif } int UtilTransactions::clearTable2(Ndb* pNdb, int records, int parallelism){ +#if 1 + return clearTable3(pNdb, records, parallelism); +#else // Scan all records exclusive and delete // them one by one int retryAttempt = 0; @@ -336,6 +344,7 @@ UtilTransactions::clearTable2(Ndb* pNdb, return NDBT_OK; } return NDBT_FAILED; +#endif } int @@ -451,7 +460,7 @@ UtilTransactions::copyTableData(Ndb* pNdb, int parallelism = 240; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; NDBT_ResultRow row(tab); while (true){ @@ -477,14 +486,15 @@ UtilTransactions::copyTableData(Ndb* pNdb, return NDBT_FAILED; } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - check = pOp->openScanRead(parallelism); + NdbResultSet* rs = pOp->readTuples(NdbScanOperation::LM_Read, + parallelism); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -508,7 +518,7 @@ UtilTransactions::copyTableData(Ndb* pNdb, } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -516,39 +526,27 @@ UtilTransactions::copyTableData(Ndb* pNdb, } int eof; - NdbConnection* pInsTrans; - - while((eof = pTrans->nextScanResult(true)) == 0){ - pInsTrans = pNdb->startTransaction(); - if (pInsTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - ERR(err); - pNdb->closeTransaction(pInsTrans); - return NDBT_FAILED; - } + while((eof = rs->nextResult(true)) == 0){ do { insertedRows++; - if (addRowToInsert(pNdb, pInsTrans, row, destName) != 0){ - pNdb->closeTransaction(pInsTrans); + if (addRowToInsert(pNdb, pTrans, row, destName) != 0){ pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - } while((eof = pTrans->nextScanResult(false)) == 0); - - check = pInsTrans->execute(Commit); + } while((eof = rs->nextResult(false)) == 0); + + check = pTrans->execute(Commit); + pTrans->releaseCompletedOperations(); if( check == -1 ) { - const NdbError err = pInsTrans->getNdbError(); + const NdbError err = pTrans->getNdbError(); ERR(err); - pNdb->closeTransaction(pInsTrans); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - pNdb->closeTransaction(pInsTrans); - } if (eof == -1) { const NdbError err = pTrans->getNdbError(); - + if (err.status == NdbError::TemporaryError){ ERR(err); pNdb->closeTransaction(pTrans); @@ -562,30 +560,17 @@ UtilTransactions::copyTableData(Ndb* pNdb, pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - + pNdb->closeTransaction(pTrans); - + g_info << insertedRows << " rows copied" << endl; - + return NDBT_OK; } return NDBT_FAILED; } int -UtilTransactions::addRowToDelete(Ndb* pNdb, - NdbConnection* pDelTrans, - NdbOperation* pOrgOp){ - - NdbOperation* pDelOp = pOrgOp->takeOverForDelete(pDelTrans); - if (pDelOp == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - return NDBT_OK; -} - -int UtilTransactions::addRowToInsert(Ndb* pNdb, NdbConnection* pInsTrans, NDBT_ResultRow & row, @@ -621,101 +606,6 @@ UtilTransactions::addRowToInsert(Ndb* pNdb, return NDBT_OK; } -// Take over one record from pOrgOp and delete it -int -UtilTransactions::takeOverAndDeleteRecord(Ndb* pNdb, - NdbOperation* pOrgOp){ - - int retryAttempt = 0; - const int retryMax = 10; - int check; - NdbConnection *pDelTrans; - NdbOperation *pDelOp; - - while (true){ - - if (retryAttempt >= retryMax){ - g_info << "ERROR: has retried this operation " << retryAttempt - << " times, failing!" << endl; - return NDBT_FAILED; - } - - pDelTrans = pNdb->startTransaction(); - if (pDelTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - - if (err.status == NdbError::TemporaryError){ - ERR(err); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - return NDBT_FAILED; - } - - if ((pDelOp = pOrgOp->takeOverForDelete(pDelTrans)) == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - -#if 0 - // It should not be necessary to call deleteTuple HERE!!! - check = pDelOp->deleteTuple(); - if( check == -1 ) { - ERR(pDelTrans->getNdbError()); - pNdb->closeTransaction(pDelTrans); - return NDBT_FAILED; - } -#endif - - check = pDelTrans->execute( Commit ); - if(check == -1 ) { - const NdbError err = pDelTrans->getNdbError(); - pNdb->closeTransaction(pDelTrans); - - ERR(err); - if(err.code == 250 || err.code == 499) - return RESTART_SCAN; - - switch(err.status){ - case NdbError::Success: - g_info << "ERROR: NdbError reports success when transcaction failed" - << endl; - RETURN_FAIL(err); - break; - - case NdbError::TemporaryError: - NdbSleep_MilliSleep(50+50*retryAttempt); - retryAttempt++; - continue; - break; - - case NdbError::UnknownResult: - RETURN_FAIL(err); - break; - - default: - case NdbError::PermanentError: - switch (err.classification){ - default: - RETURN_FAIL(err); - break; - } - break; - } - } - else{ - pNdb->closeTransaction(pDelTrans); - } - - return NDBT_OK; - } - return NDBT_FAILED; -} - - - int UtilTransactions::scanReadRecords(Ndb* pNdb, @@ -730,7 +620,7 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, const int retryMax = 100; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; NDBT_ResultRow row(tab); while (true){ @@ -755,18 +645,18 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, return NDBT_FAILED; } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - if (exclusive == true) - check = pOp->openScanExclusive(parallelism); - else - check = pOp->openScanRead(parallelism); - if( check == -1 ) { + NdbResultSet * rs = pOp->readTuples(exclusive ? + NdbScanOperation::LM_Exclusive : + NdbScanOperation::LM_Read, + 0, parallelism); + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -778,7 +668,7 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - + // Call getValue for all the attributes supplied in attrib_list // ************************************************ for (int a = 0; a < noAttribs; a++){ @@ -793,8 +683,8 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, } } // ************************************************* - - check = pTrans->executeScan(); + + check = pTrans->execute(NoCommit); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); @@ -812,15 +702,14 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, int eof; int rows = 0; - eof = pTrans->nextScanResult(); - while(eof == 0){ + + while((eof = rs->nextResult()) == 0){ rows++; // Call callback for each record returned if(fn != NULL) fn(&row); - eof = pTrans->nextScanResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); @@ -856,14 +745,15 @@ UtilTransactions::selectCount(Ndb* pNdb, int parallelism, int* count_rows, ScanLock lock, - NdbConnection* pBuddyTrans){ + NdbConnection* pTrans){ int retryAttempt = 0; const int retryMax = 100; int check; - NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; + if(!pTrans) + pTrans = pNdb->startTransaction(); while (true){ if (retryAttempt >= retryMax){ @@ -871,39 +761,27 @@ UtilTransactions::selectCount(Ndb* pNdb, << " times, failing!" << endl; return NDBT_FAILED; } - - pTrans = pNdb->hupp(pBuddyTrans); - if (pTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - - if (err.status == NdbError::TemporaryError){ - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - return NDBT_FAILED; - } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } + NdbResultSet * rs; switch(lock){ case SL_ReadHold: - check = pOp->openScanReadHoldLock(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_Read); break; case SL_Exclusive: - check = pOp->openScanExclusive(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_Exclusive); break; case SL_Read: default: - check = pOp->openScanRead(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead); } - if( check == -1 ) { + if( rs == 0) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -922,9 +800,9 @@ UtilTransactions::selectCount(Ndb* pNdb, return NDBT_FAILED; } } - - - check = pTrans->executeScan(); + + + check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -933,15 +811,14 @@ UtilTransactions::selectCount(Ndb* pNdb, int eof; int rows = 0; - eof = pTrans->nextScanResult(); + - while(eof == 0){ + while((eof = rs->nextResult()) == 0){ rows++; - eof = pTrans->nextScanResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); - + if (err.status == NdbError::TemporaryError){ pNdb->closeTransaction(pTrans); NdbSleep_MilliSleep(50); @@ -952,7 +829,7 @@ UtilTransactions::selectCount(Ndb* pNdb, pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - + pNdb->closeTransaction(pTrans); if (count_rows != NULL){ @@ -963,7 +840,6 @@ UtilTransactions::selectCount(Ndb* pNdb, } return NDBT_FAILED; } - int UtilTransactions::verifyIndex(Ndb* pNdb, @@ -1028,7 +904,7 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, const int retryMax = 100; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; NDBT_ResultRow row(tab); parallelism = 1; @@ -1055,20 +931,21 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, return NDBT_FAILED; } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } + NdbResultSet* rs; if(transactional){ - check = pOp->openScanReadHoldLock(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism); } else { - check = pOp->openScanRead(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, parallelism); } - - if( check == -1 ) { + + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -1091,10 +968,10 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); - + if (err.status == NdbError::TemporaryError){ ERR(err); pNdb->closeTransaction(pTrans); @@ -1109,14 +986,14 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, int eof; int rows = 0; - eof = pTrans->nextScanResult(); - while(eof == 0){ + + while((eof = rs->nextResult()) == 0){ rows++; - + // ndbout << row.c_str().c_str() << endl; - - + + if (readRowFromTableAndIndex(pNdb, pTrans, indexName, @@ -1124,11 +1001,6 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - - - - - eof = pTrans->nextScanResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); @@ -1265,13 +1137,13 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, * Read the record from INDEX_TABLE */ NdbIndexOperation* pIndexOp= NULL; - NdbScanOperation *pScanOp= NULL; + NdbIndexScanOperation *pScanOp= NULL; { void* pOpCheck= NULL; if (indexType == NdbDictionary::Index::UniqueHashIndex) { pOpCheck= pIndexOp= pTrans1->getNdbIndexOperation(indexName, tab.getName()); } else { - pOpCheck= pScanOp= pTrans1->getNdbScanOperation(indexName, tab.getName()); + pOpCheck= pScanOp= pTrans1->getNdbIndexScanOperation(indexName, tab.getName()); } if (pOpCheck == NULL) { @@ -1308,7 +1180,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, // setBound not possible for null attributes if ( !row.attributeStore(col->getName())->isNULL() ) { r = pScanOp->setBound(col->getName(), - NdbOperation::BoundEQ, + NdbIndexScanOperation::BoundEQ, row.attributeStore(col->getName())->aRef()); } } diff --git a/ndb/test/tools/create_index.cpp b/ndb/test/tools/create_index.cpp index dc9e6c606d6..f883755ea24 100644 --- a/ndb/test/tools/create_index.cpp +++ b/ndb/test/tools/create_index.cpp @@ -29,10 +29,13 @@ main(int argc, const char** argv){ const char* _dbname = "TEST_DB"; int _help = 0; + int _ordered, _pk; struct getargs args[] = { { "database", 'd', arg_string, &_dbname, "dbname", "Name of database table is in"}, + { "ordered", 'o', arg_flag, &_ordered, "Create ordered index", "" }, + { "pk", 'p', arg_flag, &_pk, "Create index on primary key", "" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; @@ -73,14 +76,21 @@ main(int argc, const char** argv){ } NdbDictionary::Index ind; + if(_ordered){ + ind.setType(NdbDictionary::Index::OrderedIndex); + ind.setLogging(false); + } else { + ind.setType(NdbDictionary::Index::UniqueHashIndex); + } char buf[512]; - sprintf(buf, "IND_%s", argv[i]); + sprintf(buf, "IND_%s_%s_%c", + argv[i], (_pk ? "PK" : "FULL"), (_ordered ? 'O' : 'U')); ind.setName(buf); ind.setTable(argv[i]); - ind.setType(NdbDictionary::Index::UniqueHashIndex); - for(int c = 0; c<tab->getNoOfColumns(); c++) - ind.addIndexColumn(tab->getColumn(c)->getName()); - + for(int c = 0; c<tab->getNoOfColumns(); c++){ + if(!_pk || tab->getColumn(c)->getPrimaryKey()) + ind.addIndexColumn(tab->getColumn(c)->getName()); + } ndbout << "creating index " << buf << " on table " << argv[i] << "..."; const int res = dict->createIndex(ind); if(res != 0) diff --git a/ndb/tools/select_all.cpp b/ndb/tools/select_all.cpp index 34f63a095bb..329ed87bc48 100644 --- a/ndb/tools/select_all.cpp +++ b/ndb/tools/select_all.cpp @@ -29,11 +29,13 @@ int scanReadRecords(Ndb*, const NdbDictionary::Table*, + const NdbDictionary::Index*, int parallel, int lockType, bool headers, bool useHexFormat, - char delim); + char delim, + bool orderby); int main(int argc, const char** argv){ int _parallelism = 240; @@ -44,6 +46,7 @@ int main(int argc, const char** argv){ const char* _dbname = "TEST_DB"; int _help = 0; int _lock = 0; + int _order = 0; struct getargs args[] = { { "database", 'd', arg_string, &_dbname, "dbname", @@ -57,7 +60,8 @@ int main(int argc, const char** argv){ "delimiter" }, { "usage", '?', arg_flag, &_help, "Print help", "" }, { "lock", 'l', arg_integer, &_lock, - "Read(0), Read-hold(1), Exclusive(2)", "lock"} + "Read(0), Read-hold(1), Exclusive(2)", "lock"}, + { "order", 'o', arg_flag, &_order, "Sort resultset according to index", ""} }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0; @@ -90,6 +94,11 @@ int main(int argc, const char** argv){ // Check if table exists in db const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname); + const NdbDictionary::Index * pIdx = 0; + if(optind+1 < argc){ + pIdx = MyNdb.getDictionary()->getIndex(argv[optind+1], _tabname); + } + if(pTab == NULL){ ndbout << " Table " << _tabname << " does not exist!" << endl; return NDBT_ProgramExit(NDBT_WRONGARGS); @@ -97,11 +106,12 @@ int main(int argc, const char** argv){ if (scanReadRecords(&MyNdb, pTab, + pIdx, _parallelism, _lock, _header, _useHexFormat, - (char)*_delimiter) != 0){ + (char)*_delimiter, _order) != 0){ return NDBT_ProgramExit(NDBT_FAILED); } @@ -111,17 +121,19 @@ int main(int argc, const char** argv){ int scanReadRecords(Ndb* pNdb, const NdbDictionary::Table* pTab, + const NdbDictionary::Index* pIdx, int parallel, int _lock, bool headers, bool useHexFormat, - char delimiter){ + char delimiter, bool order){ int retryAttempt = 0; const int retryMax = 100; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; + NdbIndexScanOperation * pIOp; NDBT_ResultRow * row = new NDBT_ResultRow(*pTab, delimiter); @@ -146,29 +158,45 @@ int scanReadRecords(Ndb* pNdb, return -1; } - pOp = pTrans->getNdbOperation(pTab->getName()); + + pOp = (!pIdx) ? pTrans->getNdbScanOperation(pTab->getName()) : + pIOp=pTrans->getNdbIndexScanOperation(pIdx->getName(), pTab->getName()); + if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return -1; } - switch(_lock){ + NdbResultSet * rs; + switch(_lock + (3 * order)){ case 1: - check = pOp->openScanReadHoldLock(parallel); + rs = pOp->readTuples(NdbScanOperation::LM_Read, 0, parallel); break; case 2: - check = pOp->openScanExclusive(parallel); + rs = pOp->readTuples(NdbScanOperation::LM_Exclusive, 0, parallel); + break; + case 3: + rs = pIOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, parallel, + true); break; + case 4: + rs = pIOp->readTuples(NdbScanOperation::LM_Read, 0, parallel, true); + break; + case 5: + rs = pIOp->readTuples(NdbScanOperation::LM_Exclusive, 0, parallel, true); + break; + case 0: default: - check = pOp->openScanRead(parallel); + rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, parallel); + break; } - if( check == -1 ) { + if( rs == 0 ){ ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return -1; } - + if(0){ NdbScanFilter sf(pOp); #if 0 @@ -229,10 +257,10 @@ int scanReadRecords(Ndb* pNdb, } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); - + if (err.status == NdbError::TemporaryError){ pNdb->closeTransaction(pTrans); NdbSleep_MilliSleep(50); @@ -246,11 +274,11 @@ int scanReadRecords(Ndb* pNdb, if (headers) row->header(ndbout) << endl; - + int eof; int rows = 0; - eof = pTrans->nextScanResult(); - + eof = rs->nextResult(); + while(eof == 0){ rows++; @@ -260,7 +288,7 @@ int scanReadRecords(Ndb* pNdb, ndbout << (*row) << endl; } - eof = pTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); |