summaryrefslogtreecommitdiff
path: root/ndb
diff options
context:
space:
mode:
authorunknown <joreland@mysql.com>2004-05-27 11:36:10 +0200
committerunknown <joreland@mysql.com>2004-05-27 11:36:10 +0200
commitda2ae1899885b985b035a951a4a4278450c93c1c (patch)
tree7862a781e675e63710a9a14890d55b31d68af986 /ndb
parent489aa9be1ce31a0b7f4e8901faa818b21a8f7c7a (diff)
parent910b86cdac28d2bed391298e67e4b22b6361ff80 (diff)
downloadmariadb-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')
-rw-r--r--ndb/Epilogue.mk_old2
-rw-r--r--ndb/include/kernel/BlockNumbers.h1
-rw-r--r--ndb/include/kernel/GlobalSignalNumbers.h84
-rw-r--r--ndb/include/kernel/LogLevel.hpp28
-rw-r--r--ndb/include/kernel/kernel_config_parameters.h56
-rw-r--r--ndb/include/kernel/signaldata/CheckNodeGroups.hpp12
-rw-r--r--ndb/include/kernel/signaldata/CntrStart.hpp69
-rw-r--r--ndb/include/kernel/signaldata/CreateFragmentation.hpp2
-rw-r--r--ndb/include/kernel/signaldata/DictTabInfo.hpp2
-rw-r--r--ndb/include/kernel/signaldata/DropTab.hpp3
-rw-r--r--ndb/include/kernel/signaldata/EventSubscribeReq.hpp6
-rw-r--r--ndb/include/kernel/signaldata/FsOpenReq.hpp1
-rw-r--r--ndb/include/kernel/signaldata/KeyInfo.hpp1
-rw-r--r--ndb/include/kernel/signaldata/PrepDropTab.hpp6
-rw-r--r--ndb/include/kernel/signaldata/ReadConfig.hpp24
-rw-r--r--ndb/include/kernel/signaldata/ReadNodesConf.hpp48
-rw-r--r--ndb/include/kernel/signaldata/ScanTab.hpp81
-rw-r--r--ndb/include/kernel/signaldata/SetLogLevelOrd.hpp1
-rw-r--r--ndb/include/kernel/signaldata/TcCommit.hpp1
-rw-r--r--ndb/include/kernel/signaldata/TcKeyReq.hpp1
-rw-r--r--ndb/include/kernel/signaldata/UpgradeStartup.hpp36
-rw-r--r--ndb/include/mgmapi/mgmapi.h35
-rw-r--r--ndb/include/mgmapi/mgmapi_config_parameters.h142
-rw-r--r--ndb/include/mgmapi/mgmapi_config_parameters_debug.h8
-rw-r--r--ndb/include/mgmcommon/ConfigRetriever.hpp32
-rw-r--r--ndb/include/mgmcommon/IPCConfig.hpp4
-rw-r--r--ndb/include/ndbapi/Ndb.hpp18
-rw-r--r--ndb/include/ndbapi/NdbApi.hpp4
-rw-r--r--ndb/include/ndbapi/NdbConnection.hpp147
-rw-r--r--ndb/include/ndbapi/NdbCursorOperation.hpp73
-rw-r--r--ndb/include/ndbapi/NdbIndexOperation.hpp2
-rw-r--r--ndb/include/ndbapi/NdbIndexScanOperation.hpp140
-rw-r--r--ndb/include/ndbapi/NdbOperation.hpp234
-rw-r--r--ndb/include/ndbapi/NdbRecAttr.hpp51
-rw-r--r--ndb/include/ndbapi/NdbReceiver.hpp69
-rw-r--r--ndb/include/ndbapi/NdbResultSet.hpp49
-rw-r--r--ndb/include/ndbapi/NdbScanOperation.hpp223
-rw-r--r--ndb/include/util/Base64.hpp5
-rw-r--r--ndb/include/util/Bitmask.hpp27
-rw-r--r--ndb/include/util/ConfigValues.hpp252
-rw-r--r--ndb/include/util/Properties.hpp17
-rw-r--r--ndb/include/util/UtilBuffer.hpp9
-rw-r--r--ndb/src/common/debugger/LogLevel.cpp19
-rw-r--r--ndb/src/common/debugger/signaldata/CntrStart.cpp37
-rw-r--r--ndb/src/common/debugger/signaldata/DictTabInfo.cpp2
-rw-r--r--ndb/src/common/debugger/signaldata/Makefile_old1
-rw-r--r--ndb/src/common/debugger/signaldata/ReadNodesConf.cpp24
-rw-r--r--ndb/src/common/debugger/signaldata/ScanTab.cpp49
-rw-r--r--ndb/src/common/debugger/signaldata/SignalDataPrint.cpp8
-rw-r--r--ndb/src/common/debugger/signaldata/SignalNames.cpp36
-rw-r--r--ndb/src/common/mgmcommon/Config.cpp59
-rw-r--r--ndb/src/common/mgmcommon/Config.hpp22
-rw-r--r--ndb/src/common/mgmcommon/ConfigInfo.cpp3860
-rw-r--r--ndb/src/common/mgmcommon/ConfigInfo.hpp33
-rw-r--r--ndb/src/common/mgmcommon/ConfigRetriever.cpp386
-rw-r--r--ndb/src/common/mgmcommon/IPCConfig.cpp159
-rw-r--r--ndb/src/common/mgmcommon/InitConfigFileParser.cpp159
-rw-r--r--ndb/src/common/mgmcommon/InitConfigFileParser.hpp77
-rw-r--r--ndb/src/common/mgmcommon/Makefile_old3
-rw-r--r--ndb/src/common/mgmcommon/printConfig/Makefile6
-rw-r--r--ndb/src/common/mgmcommon/printConfig/printConfig.cpp11
-rw-r--r--ndb/src/common/util/Base64.cpp161
-rw-r--r--ndb/src/common/util/ConfigValues.cpp743
-rw-r--r--ndb/src/common/util/Makefile_old4
-rw-r--r--ndb/src/common/util/Properties.cpp122
-rw-r--r--ndb/src/common/util/socket_io.cpp6
-rw-r--r--ndb/src/common/util/testConfigValues/Makefile12
-rw-r--r--ndb/src/common/util/testConfigValues/testConfigValues.cpp122
-rw-r--r--ndb/src/common/util/testProperties/Makefile5
-rw-r--r--ndb/src/common/util/testProperties/testProperties.cpp11
-rw-r--r--ndb/src/kernel/Makefile_old2
-rw-r--r--ndb/src/kernel/blocks/ERROR_codes.txt9
-rw-r--r--ndb/src/kernel/blocks/Start.txt32
-rw-r--r--ndb/src/kernel/blocks/backup/BackupInit.cpp18
-rw-r--r--ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp388
-rw-r--r--ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp13
-rw-r--r--ndb/src/kernel/blocks/dbacc/Dbacc.hpp5
-rw-r--r--ndb/src/kernel/blocks/dbacc/DbaccInit.cpp2
-rw-r--r--ndb/src/kernel/blocks/dbacc/DbaccMain.cpp113
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.cpp107
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.hpp4
-rw-r--r--ndb/src/kernel/blocks/dbdih/Dbdih.hpp8
-rw-r--r--ndb/src/kernel/blocks/dbdih/DbdihInit.cpp4
-rw-r--r--ndb/src/kernel/blocks/dbdih/DbdihMain.cpp218
-rw-r--r--ndb/src/kernel/blocks/dblqh/Dblqh.hpp6
-rw-r--r--ndb/src/kernel/blocks/dblqh/DblqhInit.cpp2
-rw-r--r--ndb/src/kernel/blocks/dblqh/DblqhMain.cpp286
-rw-r--r--ndb/src/kernel/blocks/dbtc/Dbtc.hpp260
-rw-r--r--ndb/src/kernel/blocks/dbtc/DbtcInit.cpp59
-rw-r--r--ndb/src/kernel/blocks/dbtc/DbtcMain.cpp1565
-rw-r--r--ndb/src/kernel/blocks/dbtup/Dbtup.hpp13
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp289
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp50
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupGen.cpp100
-rw-r--r--ndb/src/kernel/blocks/dbtux/Dbtux.hpp3
-rw-r--r--ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp40
-rw-r--r--ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp251
-rw-r--r--ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp25
-rw-r--r--ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp2339
-rw-r--r--ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp5
-rw-r--r--ndb/src/kernel/blocks/qmgr/Qmgr.hpp176
-rw-r--r--ndb/src/kernel/blocks/qmgr/QmgrInit.cpp22
-rw-r--r--ndb/src/kernel/blocks/qmgr/QmgrMain.cpp1813
-rw-r--r--ndb/src/kernel/ndb-main/Main.cpp8
-rw-r--r--ndb/src/kernel/ndb-main/Makefile_old2
-rw-r--r--ndb/src/kernel/ndb-main/SimBlockList.cpp15
-rw-r--r--ndb/src/kernel/vm/Configuration.cpp439
-rw-r--r--ndb/src/kernel/vm/Configuration.hpp28
-rw-r--r--ndb/src/kernel/vm/FastScheduler.cpp14
-rw-r--r--ndb/src/kernel/vm/FastScheduler.hpp14
-rw-r--r--ndb/src/kernel/vm/Makefile_old5
-rw-r--r--ndb/src/kernel/vm/SignalCounter.hpp2
-rw-r--r--ndb/src/kernel/vm/SimulatedBlock.cpp59
-rw-r--r--ndb/src/kernel/vm/SimulatedBlock.hpp15
-rw-r--r--ndb/src/kernel/vm/TransporterCallback.cpp7
-rw-r--r--ndb/src/kernel/vm/VMSignal.hpp9
-rw-r--r--ndb/src/kernel/vm/pc.hpp6
-rw-r--r--ndb/src/kernel/vm/testLongSig/testLongSig.cpp40
-rw-r--r--ndb/src/mgmapi/Makefile_old2
-rw-r--r--ndb/src/mgmapi/mgmapi.cpp148
-rw-r--r--ndb/src/mgmapi/mgmapi_configuration.cpp157
-rw-r--r--ndb/src/mgmapi/mgmapi_configuration.hpp32
-rw-r--r--ndb/src/mgmapi/test/keso.c14
-rw-r--r--ndb/src/mgmclient/Makefile_old2
-rw-r--r--ndb/src/mgmsrv/CommandInterpreter.cpp9
-rw-r--r--ndb/src/mgmsrv/Makefile_old5
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.cpp151
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.hpp12
-rw-r--r--ndb/src/mgmsrv/MgmtSrvrConfig.cpp27
-rw-r--r--ndb/src/mgmsrv/Services.cpp184
-rw-r--r--ndb/src/mgmsrv/main.cpp57
-rw-r--r--ndb/src/mgmsrv/mkconfig/Makefile5
-rw-r--r--ndb/src/mgmsrv/mkconfig/mkconfig.cpp20
-rw-r--r--ndb/src/ndbapi/ClusterMgr.cpp123
-rw-r--r--ndb/src/ndbapi/ClusterMgr.hpp4
-rw-r--r--ndb/src/ndbapi/Makefile_old19
-rw-r--r--ndb/src/ndbapi/Ndb.cpp48
-rw-r--r--ndb/src/ndbapi/NdbApiSignal.cpp3
-rw-r--r--ndb/src/ndbapi/NdbConnection.cpp492
-rw-r--r--ndb/src/ndbapi/NdbConnectionScan.cpp530
-rw-r--r--ndb/src/ndbapi/NdbCursorOperation.cpp6
-rw-r--r--ndb/src/ndbapi/NdbDictionaryImpl.cpp9
-rw-r--r--ndb/src/ndbapi/NdbDictionaryImpl.hpp4
-rw-r--r--ndb/src/ndbapi/NdbEventOperationImpl.cpp26
-rw-r--r--ndb/src/ndbapi/NdbImpl.hpp11
-rw-r--r--ndb/src/ndbapi/NdbIndexOperation.cpp6
-rw-r--r--ndb/src/ndbapi/NdbOperation.cpp59
-rw-r--r--ndb/src/ndbapi/NdbOperationDefine.cpp121
-rw-r--r--ndb/src/ndbapi/NdbOperationExec.cpp379
-rw-r--r--ndb/src/ndbapi/NdbOperationInt.cpp28
-rw-r--r--ndb/src/ndbapi/NdbOperationScan.cpp560
-rw-r--r--ndb/src/ndbapi/NdbRecAttr.cpp18
-rw-r--r--ndb/src/ndbapi/NdbReceiver.cpp172
-rw-r--r--ndb/src/ndbapi/NdbResultSet.cpp33
-rw-r--r--ndb/src/ndbapi/NdbScanOperation.cpp1561
-rw-r--r--ndb/src/ndbapi/Ndbif.cpp352
-rw-r--r--ndb/src/ndbapi/Ndbinit.cpp2
-rw-r--r--ndb/src/ndbapi/Ndblist.cpp39
-rw-r--r--ndb/src/ndbapi/ObjectMap.hpp41
-rw-r--r--ndb/src/ndbapi/ScanOperation.txt46
-rw-r--r--ndb/src/ndbapi/TransporterFacade.cpp117
-rw-r--r--ndb/src/ndbapi/TransporterFacade.hpp15
-rw-r--r--ndb/src/ndbapi/signal-sender/SignalSender.cpp2
-rw-r--r--ndb/src/rep/adapters/ExtNDB.cpp21
-rw-r--r--ndb/src/rep/state/RepState.hpp1
-rw-r--r--ndb/src/rep/transfer/TransPS.cpp3
-rw-r--r--ndb/src/rep/transfer/TransSS.cpp3
-rw-r--r--ndb/test/include/HugoTransactions.hpp30
-rw-r--r--ndb/test/include/NdbConfig.hpp19
-rw-r--r--ndb/test/include/NdbRestarter.hpp4
-rw-r--r--ndb/test/include/UtilTransactions.hpp14
-rw-r--r--ndb/test/ndbapi/Makefile_old4
-rw-r--r--ndb/test/ndbapi/ScanFunctions.hpp72
-rw-r--r--ndb/test/ndbapi/ScanInterpretTest.hpp52
-rw-r--r--ndb/test/ndbapi/old_dirs/testBackup/Makefile1
-rw-r--r--ndb/test/ndbapi/old_dirs/testGrep/Makefile1
-rw-r--r--ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile1
-rw-r--r--ndb/test/ndbapi/testBackup.cpp6
-rw-r--r--ndb/test/ndbapi/testDataBuffers.cpp10
-rw-r--r--ndb/test/ndbapi/testDict.cpp6
-rw-r--r--ndb/test/ndbapi/testGrep.cpp7
-rw-r--r--ndb/test/ndbapi/testIndex.cpp2
-rw-r--r--ndb/test/ndbapi/testOIBasic.cpp20
-rw-r--r--ndb/test/ndbapi/testSystemRestart.cpp247
-rw-r--r--ndb/test/ndbapi/testTimeout.cpp12
-rw-r--r--ndb/test/src/HugoOperations.cpp4
-rw-r--r--ndb/test/src/HugoTransactions.cpp174
-rw-r--r--ndb/test/src/Makefile_old8
-rw-r--r--ndb/test/src/NDBT_Tables.cpp2
-rw-r--r--ndb/test/src/NdbBackup.cpp25
-rw-r--r--ndb/test/src/NdbConfig.cpp131
-rw-r--r--ndb/test/src/NdbRestarter.cpp13
-rw-r--r--ndb/test/src/UtilTransactions.cpp270
-rw-r--r--ndb/test/tools/create_index.cpp20
-rw-r--r--ndb/tools/select_all.cpp64
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 &section,
const BaseString &param,
const BaseString &value) {
+#if 0
const char *name;
Properties::Iterator it(this);
@@ -252,4 +260,7 @@ Config::change(const BaseString &section,
}
}
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 &param,
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, &section);
// 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();